From d151503d3428d61b5b3cb27ddbe849d3a6f288eb Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 17 Oct 2019 17:26:49 +0800 Subject: Upgrade xorm to v0.8.0 (#8536) --- contrib/pr/checkout.go | 2 +- go.mod | 4 +- go.sum | 18 +- integrations/migration-test/migration_test.go | 2 +- models/attachment.go | 2 +- models/commit_status.go | 2 +- models/gpg_key.go | 2 +- models/issue.go | 2 +- models/issue_assignees.go | 2 +- models/issue_comment.go | 2 +- models/issue_label.go | 2 +- models/issue_milestone.go | 2 +- models/issue_reaction.go | 2 +- models/issue_tracked_time.go | 2 +- models/issue_user.go | 2 +- models/issue_xref.go | 2 +- models/lfs_lock.go | 2 +- models/login_source.go | 2 +- models/migrate.go | 2 +- models/migrations/migrations.go | 2 +- models/migrations/v100.go | 2 +- models/migrations/v13.go | 2 +- models/migrations/v14.go | 2 +- models/migrations/v15.go | 2 +- models/migrations/v16.go | 2 +- models/migrations/v17.go | 2 +- models/migrations/v18.go | 2 +- models/migrations/v19.go | 2 +- models/migrations/v20.go | 2 +- models/migrations/v21.go | 2 +- models/migrations/v22.go | 2 +- models/migrations/v23.go | 2 +- models/migrations/v24.go | 2 +- models/migrations/v25.go | 2 +- models/migrations/v26.go | 2 +- models/migrations/v27.go | 2 +- models/migrations/v28.go | 2 +- models/migrations/v29.go | 2 +- models/migrations/v30.go | 2 +- models/migrations/v31.go | 2 +- models/migrations/v32.go | 2 +- models/migrations/v33.go | 2 +- models/migrations/v34.go | 2 +- models/migrations/v35.go | 2 +- models/migrations/v36.go | 2 +- models/migrations/v37.go | 2 +- models/migrations/v38.go | 2 +- models/migrations/v39.go | 2 +- models/migrations/v40.go | 2 +- models/migrations/v41.go | 2 +- models/migrations/v45.go | 2 +- models/migrations/v46.go | 2 +- models/migrations/v47.go | 2 +- models/migrations/v48.go | 2 +- models/migrations/v49.go | 2 +- models/migrations/v50.go | 2 +- models/migrations/v51.go | 2 +- models/migrations/v52.go | 2 +- models/migrations/v53.go | 2 +- models/migrations/v54.go | 2 +- models/migrations/v55.go | 2 +- models/migrations/v56.go | 2 +- models/migrations/v57.go | 2 +- models/migrations/v58.go | 2 +- models/migrations/v59.go | 2 +- models/migrations/v60.go | 2 +- models/migrations/v61.go | 2 +- models/migrations/v62.go | 2 +- models/migrations/v63.go | 2 +- models/migrations/v64.go | 2 +- models/migrations/v65.go | 2 +- models/migrations/v66.go | 2 +- models/migrations/v67.go | 2 +- models/migrations/v68.go | 2 +- models/migrations/v69.go | 2 +- models/migrations/v70.go | 2 +- models/migrations/v71.go | 2 +- models/migrations/v72.go | 2 +- models/migrations/v73.go | 2 +- models/migrations/v74.go | 2 +- models/migrations/v75.go | 2 +- models/migrations/v76.go | 2 +- models/migrations/v77.go | 2 +- models/migrations/v78.go | 2 +- models/migrations/v79.go | 2 +- models/migrations/v80.go | 2 +- models/migrations/v81.go | 2 +- models/migrations/v82.go | 2 +- models/migrations/v83.go | 2 +- models/migrations/v84.go | 2 +- models/migrations/v85.go | 2 +- models/migrations/v86.go | 2 +- models/migrations/v87.go | 2 +- models/migrations/v88.go | 2 +- models/migrations/v89.go | 2 +- models/migrations/v90.go | 2 +- models/migrations/v91.go | 2 +- models/migrations/v92.go | 2 +- models/migrations/v93.go | 2 +- models/migrations/v94.go | 2 +- models/migrations/v95.go | 2 +- models/migrations/v96.go | 2 +- models/migrations/v97.go | 2 +- models/migrations/v98.go | 2 +- models/migrations/v99.go | 2 +- models/models.go | 2 +- models/oauth2_application.go | 2 +- models/org.go | 2 +- models/org_team.go | 2 +- models/pull.go | 2 +- models/repo.go | 2 +- models/repo_activity.go | 2 +- models/repo_mirror.go | 2 +- models/repo_unit.go | 2 +- models/review.go | 2 +- models/ssh_key.go | 2 +- models/unit_tests.go | 2 +- models/user.go | 2 +- modules/auth/oauth2/oauth2.go | 2 +- routers/install.go | 2 +- vendor/github.com/go-xorm/xorm/.drone.yml | 823 ---------- vendor/github.com/go-xorm/xorm/.gitignore | 33 - vendor/github.com/go-xorm/xorm/CONTRIBUTING.md | 46 - vendor/github.com/go-xorm/xorm/LICENSE | 27 - vendor/github.com/go-xorm/xorm/README.md | 503 ------ vendor/github.com/go-xorm/xorm/README_CN.md | 500 ------ vendor/github.com/go-xorm/xorm/cache_lru.go | 284 ---- .../github.com/go-xorm/xorm/cache_memory_store.go | 51 - vendor/github.com/go-xorm/xorm/context_cache.go | 30 - vendor/github.com/go-xorm/xorm/convert.go | 348 ---- vendor/github.com/go-xorm/xorm/dialect_mssql.go | 567 ------- vendor/github.com/go-xorm/xorm/dialect_mysql.go | 654 -------- vendor/github.com/go-xorm/xorm/dialect_oracle.go | 902 ----------- vendor/github.com/go-xorm/xorm/dialect_postgres.go | 1253 --------------- vendor/github.com/go-xorm/xorm/dialect_sqlite3.go | 492 ------ vendor/github.com/go-xorm/xorm/doc.go | 184 --- vendor/github.com/go-xorm/xorm/engine.go | 1659 -------------------- vendor/github.com/go-xorm/xorm/engine_cond.go | 232 --- vendor/github.com/go-xorm/xorm/engine_context.go | 28 - vendor/github.com/go-xorm/xorm/engine_group.go | 219 --- .../github.com/go-xorm/xorm/engine_group_policy.go | 116 -- vendor/github.com/go-xorm/xorm/engine_table.go | 113 -- vendor/github.com/go-xorm/xorm/error.go | 51 - vendor/github.com/go-xorm/xorm/gen_reserved.sh | 6 - vendor/github.com/go-xorm/xorm/go.mod | 20 - vendor/github.com/go-xorm/xorm/go.sum | 172 -- vendor/github.com/go-xorm/xorm/helpers.go | 332 ---- vendor/github.com/go-xorm/xorm/helpler_time.go | 21 - vendor/github.com/go-xorm/xorm/interface.go | 118 -- vendor/github.com/go-xorm/xorm/json.go | 31 - vendor/github.com/go-xorm/xorm/logger.go | 187 --- vendor/github.com/go-xorm/xorm/pg_reserved.txt | 746 --------- vendor/github.com/go-xorm/xorm/processors.go | 78 - vendor/github.com/go-xorm/xorm/rows.go | 121 -- vendor/github.com/go-xorm/xorm/session.go | 866 ---------- vendor/github.com/go-xorm/xorm/session_cols.go | 156 -- vendor/github.com/go-xorm/xorm/session_cond.go | 70 - vendor/github.com/go-xorm/xorm/session_context.go | 23 - vendor/github.com/go-xorm/xorm/session_convert.go | 661 -------- vendor/github.com/go-xorm/xorm/session_delete.go | 244 --- vendor/github.com/go-xorm/xorm/session_exist.go | 96 -- vendor/github.com/go-xorm/xorm/session_find.go | 505 ------ vendor/github.com/go-xorm/xorm/session_get.go | 356 ----- vendor/github.com/go-xorm/xorm/session_insert.go | 878 ----------- vendor/github.com/go-xorm/xorm/session_iterate.go | 100 -- vendor/github.com/go-xorm/xorm/session_query.go | 320 ---- vendor/github.com/go-xorm/xorm/session_raw.go | 227 --- vendor/github.com/go-xorm/xorm/session_schema.go | 430 ----- vendor/github.com/go-xorm/xorm/session_stats.go | 98 -- vendor/github.com/go-xorm/xorm/session_tx.go | 83 - vendor/github.com/go-xorm/xorm/session_update.go | 525 ------- vendor/github.com/go-xorm/xorm/statement.go | 1252 --------------- vendor/github.com/go-xorm/xorm/statement_args.go | 170 -- .../github.com/go-xorm/xorm/statement_columnmap.go | 35 - .../github.com/go-xorm/xorm/statement_exprparam.go | 117 -- vendor/github.com/go-xorm/xorm/statement_quote.go | 19 - vendor/github.com/go-xorm/xorm/syslogger.go | 89 -- vendor/github.com/go-xorm/xorm/tag.go | 311 ---- vendor/github.com/go-xorm/xorm/test_mssql.sh | 1 - vendor/github.com/go-xorm/xorm/test_mssql_cache.sh | 1 - vendor/github.com/go-xorm/xorm/test_mymysql.sh | 1 - .../github.com/go-xorm/xorm/test_mymysql_cache.sh | 1 - vendor/github.com/go-xorm/xorm/test_mysql.sh | 1 - vendor/github.com/go-xorm/xorm/test_mysql_cache.sh | 1 - vendor/github.com/go-xorm/xorm/test_postgres.sh | 1 - .../github.com/go-xorm/xorm/test_postgres_cache.sh | 1 - vendor/github.com/go-xorm/xorm/test_sqlite.sh | 1 - .../github.com/go-xorm/xorm/test_sqlite_cache.sh | 1 - vendor/github.com/go-xorm/xorm/test_tidb.sh | 1 - vendor/github.com/go-xorm/xorm/transaction.go | 26 - vendor/github.com/go-xorm/xorm/types.go | 16 - vendor/github.com/go-xorm/xorm/xorm.go | 126 -- vendor/github.com/lafriks/xormstore/go.mod | 3 +- vendor/github.com/lafriks/xormstore/go.sum | 25 +- vendor/github.com/lafriks/xormstore/xormstore.go | 2 +- vendor/modules.txt | 6 +- vendor/xorm.io/xorm/.drone.yml | 771 +++++++++ vendor/xorm.io/xorm/.gitignore | 33 + vendor/xorm.io/xorm/CONTRIBUTING.md | 46 + vendor/xorm.io/xorm/LICENSE | 27 + vendor/xorm.io/xorm/README.md | 503 ++++++ vendor/xorm.io/xorm/README_CN.md | 498 ++++++ vendor/xorm.io/xorm/cache_lru.go | 284 ++++ vendor/xorm.io/xorm/cache_memory_store.go | 51 + vendor/xorm.io/xorm/context_cache.go | 30 + vendor/xorm.io/xorm/convert.go | 348 ++++ vendor/xorm.io/xorm/dialect_mssql.go | 567 +++++++ vendor/xorm.io/xorm/dialect_mysql.go | 654 ++++++++ vendor/xorm.io/xorm/dialect_oracle.go | 902 +++++++++++ vendor/xorm.io/xorm/dialect_postgres.go | 1253 +++++++++++++++ vendor/xorm.io/xorm/dialect_sqlite3.go | 492 ++++++ vendor/xorm.io/xorm/doc.go | 184 +++ vendor/xorm.io/xorm/engine.go | 1659 ++++++++++++++++++++ vendor/xorm.io/xorm/engine_cond.go | 232 +++ vendor/xorm.io/xorm/engine_context.go | 28 + vendor/xorm.io/xorm/engine_group.go | 219 +++ vendor/xorm.io/xorm/engine_group_policy.go | 116 ++ vendor/xorm.io/xorm/engine_table.go | 113 ++ vendor/xorm.io/xorm/error.go | 51 + vendor/xorm.io/xorm/gen_reserved.sh | 6 + vendor/xorm.io/xorm/go.mod | 15 + vendor/xorm.io/xorm/go.sum | 149 ++ vendor/xorm.io/xorm/helpers.go | 332 ++++ vendor/xorm.io/xorm/helpler_time.go | 21 + vendor/xorm.io/xorm/interface.go | 118 ++ vendor/xorm.io/xorm/json.go | 31 + vendor/xorm.io/xorm/logger.go | 187 +++ vendor/xorm.io/xorm/pg_reserved.txt | 746 +++++++++ vendor/xorm.io/xorm/processors.go | 78 + vendor/xorm.io/xorm/rows.go | 121 ++ vendor/xorm.io/xorm/session.go | 866 ++++++++++ vendor/xorm.io/xorm/session_cols.go | 156 ++ vendor/xorm.io/xorm/session_cond.go | 70 + vendor/xorm.io/xorm/session_context.go | 23 + vendor/xorm.io/xorm/session_convert.go | 671 ++++++++ vendor/xorm.io/xorm/session_delete.go | 244 +++ vendor/xorm.io/xorm/session_exist.go | 96 ++ vendor/xorm.io/xorm/session_find.go | 505 ++++++ vendor/xorm.io/xorm/session_get.go | 356 +++++ vendor/xorm.io/xorm/session_insert.go | 878 +++++++++++ vendor/xorm.io/xorm/session_iterate.go | 100 ++ vendor/xorm.io/xorm/session_query.go | 320 ++++ vendor/xorm.io/xorm/session_raw.go | 227 +++ vendor/xorm.io/xorm/session_schema.go | 430 +++++ vendor/xorm.io/xorm/session_stats.go | 98 ++ vendor/xorm.io/xorm/session_tx.go | 83 + vendor/xorm.io/xorm/session_update.go | 525 +++++++ vendor/xorm.io/xorm/statement.go | 1256 +++++++++++++++ vendor/xorm.io/xorm/statement_args.go | 170 ++ vendor/xorm.io/xorm/statement_columnmap.go | 35 + vendor/xorm.io/xorm/statement_exprparam.go | 117 ++ vendor/xorm.io/xorm/statement_quote.go | 19 + vendor/xorm.io/xorm/syslogger.go | 89 ++ vendor/xorm.io/xorm/tag.go | 311 ++++ vendor/xorm.io/xorm/test_mssql.sh | 1 + vendor/xorm.io/xorm/test_mssql_cache.sh | 1 + vendor/xorm.io/xorm/test_mymysql.sh | 1 + vendor/xorm.io/xorm/test_mymysql_cache.sh | 1 + vendor/xorm.io/xorm/test_mysql.sh | 1 + vendor/xorm.io/xorm/test_mysql_cache.sh | 1 + vendor/xorm.io/xorm/test_postgres.sh | 1 + vendor/xorm.io/xorm/test_postgres_cache.sh | 1 + vendor/xorm.io/xorm/test_sqlite.sh | 1 + vendor/xorm.io/xorm/test_sqlite_cache.sh | 1 + vendor/xorm.io/xorm/test_tidb.sh | 1 + vendor/xorm.io/xorm/transaction.go | 26 + vendor/xorm.io/xorm/types.go | 16 + vendor/xorm.io/xorm/xorm.go | 126 ++ 268 files changed, 18820 insertions(+), 18920 deletions(-) delete mode 100644 vendor/github.com/go-xorm/xorm/.drone.yml delete mode 100644 vendor/github.com/go-xorm/xorm/.gitignore delete mode 100644 vendor/github.com/go-xorm/xorm/CONTRIBUTING.md delete mode 100644 vendor/github.com/go-xorm/xorm/LICENSE delete mode 100644 vendor/github.com/go-xorm/xorm/README.md delete mode 100644 vendor/github.com/go-xorm/xorm/README_CN.md delete mode 100644 vendor/github.com/go-xorm/xorm/cache_lru.go delete mode 100644 vendor/github.com/go-xorm/xorm/cache_memory_store.go delete mode 100644 vendor/github.com/go-xorm/xorm/context_cache.go delete mode 100644 vendor/github.com/go-xorm/xorm/convert.go delete mode 100644 vendor/github.com/go-xorm/xorm/dialect_mssql.go delete mode 100644 vendor/github.com/go-xorm/xorm/dialect_mysql.go delete mode 100644 vendor/github.com/go-xorm/xorm/dialect_oracle.go delete mode 100644 vendor/github.com/go-xorm/xorm/dialect_postgres.go delete mode 100644 vendor/github.com/go-xorm/xorm/dialect_sqlite3.go delete mode 100644 vendor/github.com/go-xorm/xorm/doc.go delete mode 100644 vendor/github.com/go-xorm/xorm/engine.go delete mode 100644 vendor/github.com/go-xorm/xorm/engine_cond.go delete mode 100644 vendor/github.com/go-xorm/xorm/engine_context.go delete mode 100644 vendor/github.com/go-xorm/xorm/engine_group.go delete mode 100644 vendor/github.com/go-xorm/xorm/engine_group_policy.go delete mode 100644 vendor/github.com/go-xorm/xorm/engine_table.go delete mode 100644 vendor/github.com/go-xorm/xorm/error.go delete mode 100644 vendor/github.com/go-xorm/xorm/gen_reserved.sh delete mode 100644 vendor/github.com/go-xorm/xorm/go.mod delete mode 100644 vendor/github.com/go-xorm/xorm/go.sum delete mode 100644 vendor/github.com/go-xorm/xorm/helpers.go delete mode 100644 vendor/github.com/go-xorm/xorm/helpler_time.go delete mode 100644 vendor/github.com/go-xorm/xorm/interface.go delete mode 100644 vendor/github.com/go-xorm/xorm/json.go delete mode 100644 vendor/github.com/go-xorm/xorm/logger.go delete mode 100644 vendor/github.com/go-xorm/xorm/pg_reserved.txt delete mode 100644 vendor/github.com/go-xorm/xorm/processors.go delete mode 100644 vendor/github.com/go-xorm/xorm/rows.go delete mode 100644 vendor/github.com/go-xorm/xorm/session.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_cols.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_cond.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_context.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_convert.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_delete.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_exist.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_find.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_get.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_insert.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_iterate.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_query.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_raw.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_schema.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_stats.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_tx.go delete mode 100644 vendor/github.com/go-xorm/xorm/session_update.go delete mode 100644 vendor/github.com/go-xorm/xorm/statement.go delete mode 100644 vendor/github.com/go-xorm/xorm/statement_args.go delete mode 100644 vendor/github.com/go-xorm/xorm/statement_columnmap.go delete mode 100644 vendor/github.com/go-xorm/xorm/statement_exprparam.go delete mode 100644 vendor/github.com/go-xorm/xorm/statement_quote.go delete mode 100644 vendor/github.com/go-xorm/xorm/syslogger.go delete mode 100644 vendor/github.com/go-xorm/xorm/tag.go delete mode 100644 vendor/github.com/go-xorm/xorm/test_mssql.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_mssql_cache.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_mymysql.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_mymysql_cache.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_mysql.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_mysql_cache.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_postgres.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_postgres_cache.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_sqlite.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_sqlite_cache.sh delete mode 100644 vendor/github.com/go-xorm/xorm/test_tidb.sh delete mode 100644 vendor/github.com/go-xorm/xorm/transaction.go delete mode 100644 vendor/github.com/go-xorm/xorm/types.go delete mode 100644 vendor/github.com/go-xorm/xorm/xorm.go create mode 100644 vendor/xorm.io/xorm/.drone.yml create mode 100644 vendor/xorm.io/xorm/.gitignore create mode 100644 vendor/xorm.io/xorm/CONTRIBUTING.md create mode 100644 vendor/xorm.io/xorm/LICENSE create mode 100644 vendor/xorm.io/xorm/README.md create mode 100644 vendor/xorm.io/xorm/README_CN.md create mode 100644 vendor/xorm.io/xorm/cache_lru.go create mode 100644 vendor/xorm.io/xorm/cache_memory_store.go create mode 100644 vendor/xorm.io/xorm/context_cache.go create mode 100644 vendor/xorm.io/xorm/convert.go create mode 100644 vendor/xorm.io/xorm/dialect_mssql.go create mode 100644 vendor/xorm.io/xorm/dialect_mysql.go create mode 100644 vendor/xorm.io/xorm/dialect_oracle.go create mode 100644 vendor/xorm.io/xorm/dialect_postgres.go create mode 100644 vendor/xorm.io/xorm/dialect_sqlite3.go create mode 100644 vendor/xorm.io/xorm/doc.go create mode 100644 vendor/xorm.io/xorm/engine.go create mode 100644 vendor/xorm.io/xorm/engine_cond.go create mode 100644 vendor/xorm.io/xorm/engine_context.go create mode 100644 vendor/xorm.io/xorm/engine_group.go create mode 100644 vendor/xorm.io/xorm/engine_group_policy.go create mode 100644 vendor/xorm.io/xorm/engine_table.go create mode 100644 vendor/xorm.io/xorm/error.go create mode 100644 vendor/xorm.io/xorm/gen_reserved.sh create mode 100644 vendor/xorm.io/xorm/go.mod create mode 100644 vendor/xorm.io/xorm/go.sum create mode 100644 vendor/xorm.io/xorm/helpers.go create mode 100644 vendor/xorm.io/xorm/helpler_time.go create mode 100644 vendor/xorm.io/xorm/interface.go create mode 100644 vendor/xorm.io/xorm/json.go create mode 100644 vendor/xorm.io/xorm/logger.go create mode 100644 vendor/xorm.io/xorm/pg_reserved.txt create mode 100644 vendor/xorm.io/xorm/processors.go create mode 100644 vendor/xorm.io/xorm/rows.go create mode 100644 vendor/xorm.io/xorm/session.go create mode 100644 vendor/xorm.io/xorm/session_cols.go create mode 100644 vendor/xorm.io/xorm/session_cond.go create mode 100644 vendor/xorm.io/xorm/session_context.go create mode 100644 vendor/xorm.io/xorm/session_convert.go create mode 100644 vendor/xorm.io/xorm/session_delete.go create mode 100644 vendor/xorm.io/xorm/session_exist.go create mode 100644 vendor/xorm.io/xorm/session_find.go create mode 100644 vendor/xorm.io/xorm/session_get.go create mode 100644 vendor/xorm.io/xorm/session_insert.go create mode 100644 vendor/xorm.io/xorm/session_iterate.go create mode 100644 vendor/xorm.io/xorm/session_query.go create mode 100644 vendor/xorm.io/xorm/session_raw.go create mode 100644 vendor/xorm.io/xorm/session_schema.go create mode 100644 vendor/xorm.io/xorm/session_stats.go create mode 100644 vendor/xorm.io/xorm/session_tx.go create mode 100644 vendor/xorm.io/xorm/session_update.go create mode 100644 vendor/xorm.io/xorm/statement.go create mode 100644 vendor/xorm.io/xorm/statement_args.go create mode 100644 vendor/xorm.io/xorm/statement_columnmap.go create mode 100644 vendor/xorm.io/xorm/statement_exprparam.go create mode 100644 vendor/xorm.io/xorm/statement_quote.go create mode 100644 vendor/xorm.io/xorm/syslogger.go create mode 100644 vendor/xorm.io/xorm/tag.go create mode 100644 vendor/xorm.io/xorm/test_mssql.sh create mode 100644 vendor/xorm.io/xorm/test_mssql_cache.sh create mode 100644 vendor/xorm.io/xorm/test_mymysql.sh create mode 100644 vendor/xorm.io/xorm/test_mymysql_cache.sh create mode 100644 vendor/xorm.io/xorm/test_mysql.sh create mode 100644 vendor/xorm.io/xorm/test_mysql_cache.sh create mode 100644 vendor/xorm.io/xorm/test_postgres.sh create mode 100644 vendor/xorm.io/xorm/test_postgres_cache.sh create mode 100644 vendor/xorm.io/xorm/test_sqlite.sh create mode 100644 vendor/xorm.io/xorm/test_sqlite_cache.sh create mode 100644 vendor/xorm.io/xorm/test_tidb.sh create mode 100644 vendor/xorm.io/xorm/transaction.go create mode 100644 vendor/xorm.io/xorm/types.go create mode 100644 vendor/xorm.io/xorm/xorm.go diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go index 490d6760c8..9c06357295 100644 --- a/contrib/pr/checkout.go +++ b/contrib/pr/checkout.go @@ -27,13 +27,13 @@ import ( "code.gitea.io/gitea/routers" "code.gitea.io/gitea/routers/routes" - "github.com/go-xorm/xorm" context2 "github.com/gorilla/context" "github.com/unknwon/com" "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/config" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/testfixtures.v2" + "xorm.io/xorm" ) var codeFilePath = "contrib/pr/checkout.go" diff --git a/go.mod b/go.mod index f3ee20acf4..e1bbd9ac89 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,6 @@ require ( github.com/go-redis/redis v6.15.2+incompatible github.com/go-sql-driver/mysql v1.4.1 github.com/go-swagger/go-swagger v0.20.1 - github.com/go-xorm/xorm v0.7.9 github.com/gobwas/glob v0.2.3 github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 @@ -60,7 +59,7 @@ require ( github.com/klauspost/compress v0.0.0-20161025140425-8df558b6cb6f github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc // indirect github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 // indirect - github.com/lafriks/xormstore v1.3.1 + github.com/lafriks/xormstore v1.3.2 github.com/lib/pq v1.2.0 github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 github.com/lunny/levelqueue v0.0.0-20190217115915-02b525a4418e @@ -118,4 +117,5 @@ require ( strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 xorm.io/builder v0.3.6 xorm.io/core v0.7.2 + xorm.io/xorm v0.8.0 ) diff --git a/go.sum b/go.sum index c4317af9e2..2eeaa79810 100644 --- a/go.sum +++ b/go.sum @@ -89,8 +89,6 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f h1:REH9VH5ubNR0skLaOxK7TRJeRbE2dDfvaouQo8FsRcA= github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f/go.mod h1:6QaC0vFoKWYDth94dHFNgRT2YkT5FHdQp/Yx15aAAi0= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/corbym/gocrest v1.0.3 h1:gwEdq6RkTmq+09CTuM29DfKOCtZ7G7bcyxs3IZ6EVdU= github.com/corbym/gocrest v1.0.3/go.mod h1:maVFL5lbdS2PgfOQgGRWDYTeunSWQeiEgoNdTABShCs= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= @@ -241,11 +239,8 @@ github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= -github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0= -github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561 h1:deE7ritpK04PgtpyVOS2TYcQEld9qLCD5b5EbVNOuLA= github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:YgYOrVn3Nj9Tq0EvjmFbphRytDj7JNRoWSStJZWDJTQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -329,9 +324,6 @@ github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0= github.com/issue9/assert v1.3.2/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio= github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c h1:A/PDn117UYld5mlxe58EpMguqpkeTMw5/FCo0ZPS/Ko= github.com/issue9/identicon v0.0.0-20160320065130-d36b54562f4c/go.mod h1:5mTb/PQNkqmq2x3IxlQZE0aSnTksJg7fg/oWmJ5SKXQ= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d h1:ig/iUfDDg06RVW8OMby+GrmW6K2nPO3AFHlEIdvJSd4= github.com/jaytaylor/html2text v0.0.0-20160923191438-8fb95d837f7d/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= @@ -376,8 +368,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lafriks/xormstore v1.3.1 h1:KpzRUamSV3zmA85Kzw+PZOU9wgMbYsNzuDzLuBMbxpA= -github.com/lafriks/xormstore v1.3.1/go.mod h1:qALRD4Vto2Ic7/A5eplMpu5V62mugtSqFysRwz8FETs= +github.com/lafriks/xormstore v1.3.2 h1:hqi3F8s/B4rz8GuEZZDuHuOxRjeuOpEI/cC7vcnWwH4= +github.com/lafriks/xormstore v1.3.2/go.mod h1:mVNIwIa25QIr8rfR7YlVjrqN/apswHkVdtLCyVYBzXw= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -503,8 +495,6 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA= github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc h1:3wIrJvFb3Pf6B/2mDBnN1G5IfUVev4X5apadQlWOczE= @@ -811,7 +801,7 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY= xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= -xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb h1:msX3zG3BPl8Ti+LDzP33/9K7BzO/WqFXk610K1kYKfo= -xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw= xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= +xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM= +xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY= diff --git a/integrations/migration-test/migration_test.go b/integrations/migration-test/migration_test.go index 3b47f0d7fc..8dc366dc3f 100644 --- a/integrations/migration-test/migration_test.go +++ b/integrations/migration-test/migration_test.go @@ -23,8 +23,8 @@ import ( "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "github.com/stretchr/testify/assert" + "xorm.io/xorm" ) var currentEngine *xorm.Engine diff --git a/models/attachment.go b/models/attachment.go index a9032f1a86..f585bda8cb 100644 --- a/models/attachment.go +++ b/models/attachment.go @@ -14,8 +14,8 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" gouuid "github.com/satori/go.uuid" + "xorm.io/xorm" ) // Attachment represent a attachment of issue/comment/release. diff --git a/models/commit_status.go b/models/commit_status.go index 6f6cbc387f..4e0f8166f3 100644 --- a/models/commit_status.go +++ b/models/commit_status.go @@ -16,7 +16,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // CommitStatusState holds the state of a Status diff --git a/models/gpg_key.go b/models/gpg_key.go index 5cfe67435e..9b690475bd 100644 --- a/models/gpg_key.go +++ b/models/gpg_key.go @@ -20,10 +20,10 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "github.com/keybase/go-crypto/openpgp" "github.com/keybase/go-crypto/openpgp/armor" "github.com/keybase/go-crypto/openpgp/packet" + "xorm.io/xorm" ) // GPGKey represents a GPG key. diff --git a/models/issue.go b/models/issue.go index c55e96168f..525152552c 100644 --- a/models/issue.go +++ b/models/issue.go @@ -19,9 +19,9 @@ import ( "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "xorm.io/builder" + "xorm.io/xorm" ) // Issue represents an issue or pull request of repository. diff --git a/models/issue_assignees.go b/models/issue_assignees.go index 1f504a9950..00ee498860 100644 --- a/models/issue_assignees.go +++ b/models/issue_assignees.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // IssueAssignees saves all issue assignees diff --git a/models/issue_comment.go b/models/issue_comment.go index ffc3c006f5..d7128bdbac 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -18,9 +18,9 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "xorm.io/builder" + "xorm.io/xorm" ) // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference. diff --git a/models/issue_label.go b/models/issue_label.go index dab5ba2827..2b77c4bc35 100644 --- a/models/issue_label.go +++ b/models/issue_label.go @@ -13,8 +13,8 @@ import ( api "code.gitea.io/gitea/modules/structs" - "github.com/go-xorm/xorm" "xorm.io/builder" + "xorm.io/xorm" ) var labelColorPattern = regexp.MustCompile("#([a-fA-F0-9]{6})") diff --git a/models/issue_milestone.go b/models/issue_milestone.go index 1587e5e341..d32cb3c7d1 100644 --- a/models/issue_milestone.go +++ b/models/issue_milestone.go @@ -12,7 +12,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // Milestone represents a milestone of repository. diff --git a/models/issue_reaction.go b/models/issue_reaction.go index ab644b4b3e..4596d32d06 100644 --- a/models/issue_reaction.go +++ b/models/issue_reaction.go @@ -11,8 +11,8 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "xorm.io/builder" + "xorm.io/xorm" ) // Reaction represents a reactions on issues and comments. diff --git a/models/issue_tracked_time.go b/models/issue_tracked_time.go index f9313b7653..f616836c85 100644 --- a/models/issue_tracked_time.go +++ b/models/issue_tracked_time.go @@ -10,8 +10,8 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" - "github.com/go-xorm/xorm" "xorm.io/builder" + "xorm.io/xorm" ) // TrackedTime represents a time that was spent for a specific issue. diff --git a/models/issue_user.go b/models/issue_user.go index d55a0dc2fb..6974a4d3cc 100644 --- a/models/issue_user.go +++ b/models/issue_user.go @@ -7,7 +7,7 @@ package models import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // IssueUser represents an issue-user relation. diff --git a/models/issue_xref.go b/models/issue_xref.go index 141a7e0e8c..4b01022bc5 100644 --- a/models/issue_xref.go +++ b/models/issue_xref.go @@ -8,8 +8,8 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/references" - "github.com/go-xorm/xorm" "github.com/unknwon/com" + "xorm.io/xorm" ) type crossReference struct { diff --git a/models/lfs_lock.go b/models/lfs_lock.go index 7ea1dc8660..ba1a452815 100644 --- a/models/lfs_lock.go +++ b/models/lfs_lock.go @@ -14,7 +14,7 @@ import ( "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // LFSLock represents a git lfs lock of repository. diff --git a/models/login_source.go b/models/login_source.go index 9381ed034f..ce03c4154f 100644 --- a/models/login_source.go +++ b/models/login_source.go @@ -21,9 +21,9 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "xorm.io/core" + "xorm.io/xorm" ) // LoginType represents an login type. diff --git a/models/migrate.go b/models/migrate.go index 85be3a312c..53838fd65e 100644 --- a/models/migrate.go +++ b/models/migrate.go @@ -4,7 +4,7 @@ package models -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" // InsertMilestones creates milestones of repository. func InsertMilestones(ms ...*Milestone) (err error) { diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 60a416c6e9..ef4f5b823f 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -21,10 +21,10 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" gouuid "github.com/satori/go.uuid" "github.com/unknwon/com" ini "gopkg.in/ini.v1" + "xorm.io/xorm" ) const minDBVersion = 4 diff --git a/models/migrations/v100.go b/models/migrations/v100.go index ac3b73e2ad..6a4e98af1f 100644 --- a/models/migrations/v100.go +++ b/models/migrations/v100.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func updateMigrationServiceTypes(x *xorm.Engine) error { diff --git a/models/migrations/v13.go b/models/migrations/v13.go index 8b6b38cadf..3c35b66ab9 100644 --- a/models/migrations/v13.go +++ b/models/migrations/v13.go @@ -9,8 +9,8 @@ import ( "fmt" "strings" - "github.com/go-xorm/xorm" "github.com/unknwon/com" + "xorm.io/xorm" ) func ldapUseSSLToSecurityProtocol(x *xorm.Engine) error { diff --git a/models/migrations/v14.go b/models/migrations/v14.go index 392f9fdba6..675c7459dd 100644 --- a/models/migrations/v14.go +++ b/models/migrations/v14.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func setCommentUpdatedWithCreated(x *xorm.Engine) (err error) { diff --git a/models/migrations/v15.go b/models/migrations/v15.go index 3492a7190b..8872f1e946 100644 --- a/models/migrations/v15.go +++ b/models/migrations/v15.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func createAllowCreateOrganizationColumn(x *xorm.Engine) error { diff --git a/models/migrations/v16.go b/models/migrations/v16.go index 5b8ec19d32..a849205b55 100644 --- a/models/migrations/v16.go +++ b/models/migrations/v16.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/modules/markup" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // Enumerate all the unit types diff --git a/models/migrations/v17.go b/models/migrations/v17.go index 2986badc97..2907b009db 100644 --- a/models/migrations/v17.go +++ b/models/migrations/v17.go @@ -8,7 +8,7 @@ import ( "fmt" "time" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func setProtectedBranchUpdatedWithCreated(x *xorm.Engine) (err error) { diff --git a/models/migrations/v18.go b/models/migrations/v18.go index 3b3cd23ccf..66a1de3499 100644 --- a/models/migrations/v18.go +++ b/models/migrations/v18.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // ExternalLoginUser makes the connecting between some existing user and additional external login sources diff --git a/models/migrations/v19.go b/models/migrations/v19.go index 7728f5add6..349d5850aa 100644 --- a/models/migrations/v19.go +++ b/models/migrations/v19.go @@ -13,8 +13,8 @@ import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "github.com/unknwon/com" + "xorm.io/xorm" ) func generateAndMigrateGitHooks(x *xorm.Engine) (err error) { diff --git a/models/migrations/v20.go b/models/migrations/v20.go index ded99e09ce..0897eada74 100644 --- a/models/migrations/v20.go +++ b/models/migrations/v20.go @@ -16,7 +16,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func useNewNameAvatars(x *xorm.Engine) error { diff --git a/models/migrations/v21.go b/models/migrations/v21.go index 65cae2ac03..2750725760 100644 --- a/models/migrations/v21.go +++ b/models/migrations/v21.go @@ -11,8 +11,8 @@ import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "github.com/unknwon/com" + "xorm.io/xorm" ) const ( diff --git a/models/migrations/v22.go b/models/migrations/v22.go index faac74343b..eb37aec17f 100644 --- a/models/migrations/v22.go +++ b/models/migrations/v22.go @@ -13,8 +13,8 @@ import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "github.com/unknwon/com" + "xorm.io/xorm" ) func generateAndMigrateWikiGitHooks(x *xorm.Engine) (err error) { diff --git a/models/migrations/v23.go b/models/migrations/v23.go index 4aadf7ef0d..50dc6cd2c7 100644 --- a/models/migrations/v23.go +++ b/models/migrations/v23.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // UserOpenID is the list of all OpenID identities of a user. diff --git a/models/migrations/v24.go b/models/migrations/v24.go index 076c710cc3..20791d7981 100644 --- a/models/migrations/v24.go +++ b/models/migrations/v24.go @@ -7,7 +7,7 @@ package migrations import ( "time" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func changeGPGKeysColumns(x *xorm.Engine) error { diff --git a/models/migrations/v25.go b/models/migrations/v25.go index a8d746590a..da74e27c28 100644 --- a/models/migrations/v25.go +++ b/models/migrations/v25.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addUserOpenIDShow(x *xorm.Engine) error { diff --git a/models/migrations/v26.go b/models/migrations/v26.go index 04277191f5..03ce2ef94b 100644 --- a/models/migrations/v26.go +++ b/models/migrations/v26.go @@ -16,8 +16,8 @@ import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "github.com/unknwon/com" + "xorm.io/xorm" ) func generateAndMigrateGitHookChains(x *xorm.Engine) (err error) { diff --git a/models/migrations/v27.go b/models/migrations/v27.go index 12e5fbcdbf..2bba0b7412 100644 --- a/models/migrations/v27.go +++ b/models/migrations/v27.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func convertIntervalToDuration(x *xorm.Engine) (err error) { diff --git a/models/migrations/v28.go b/models/migrations/v28.go index a30cbf2afb..587e944ce6 100644 --- a/models/migrations/v28.go +++ b/models/migrations/v28.go @@ -14,7 +14,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addRepoSize(x *xorm.Engine) (err error) { diff --git a/models/migrations/v29.go b/models/migrations/v29.go index eadb0f3d87..ea70a2dd77 100644 --- a/models/migrations/v29.go +++ b/models/migrations/v29.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // CommitStatus see models/status.go diff --git a/models/migrations/v30.go b/models/migrations/v30.go index 90047df8b6..5acdc5dac7 100644 --- a/models/migrations/v30.go +++ b/models/migrations/v30.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addExternalLoginUserPK(x *xorm.Engine) error { diff --git a/models/migrations/v31.go b/models/migrations/v31.go index d6cea4c51b..b3aef0d665 100644 --- a/models/migrations/v31.go +++ b/models/migrations/v31.go @@ -8,8 +8,8 @@ import ( "fmt" "time" - "github.com/go-xorm/xorm" "xorm.io/core" + "xorm.io/xorm" ) func addLoginSourceSyncEnabledColumn(x *xorm.Engine) error { diff --git a/models/migrations/v32.go b/models/migrations/v32.go index d209fc34f6..f5c021cccf 100644 --- a/models/migrations/v32.go +++ b/models/migrations/v32.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addUnitsToRepoTeam(x *xorm.Engine) error { type Team struct { diff --git a/models/migrations/v33.go b/models/migrations/v33.go index 566951db96..625c5f4a53 100644 --- a/models/migrations/v33.go +++ b/models/migrations/v33.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func removeActionColumns(x *xorm.Engine) error { diff --git a/models/migrations/v34.go b/models/migrations/v34.go index 258da41c04..26f0f565f7 100644 --- a/models/migrations/v34.go +++ b/models/migrations/v34.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // Team see models/team.go diff --git a/models/migrations/v35.go b/models/migrations/v35.go index 7746663a40..d5059c7998 100644 --- a/models/migrations/v35.go +++ b/models/migrations/v35.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addCommentIDToAction(x *xorm.Engine) error { diff --git a/models/migrations/v36.go b/models/migrations/v36.go index 06f76a26d6..729019925e 100644 --- a/models/migrations/v36.go +++ b/models/migrations/v36.go @@ -7,7 +7,7 @@ package migrations import ( "code.gitea.io/gitea/models" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func regenerateGitHooks36(x *xorm.Engine) (err error) { diff --git a/models/migrations/v37.go b/models/migrations/v37.go index 00653a780d..29e1c966f3 100644 --- a/models/migrations/v37.go +++ b/models/migrations/v37.go @@ -7,7 +7,7 @@ package migrations import ( "html" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func unescapeUserFullNames(x *xorm.Engine) (err error) { diff --git a/models/migrations/v38.go b/models/migrations/v38.go index 6060b70fe8..4e4e6628d3 100644 --- a/models/migrations/v38.go +++ b/models/migrations/v38.go @@ -9,8 +9,8 @@ import ( "code.gitea.io/gitea/models" - "github.com/go-xorm/xorm" "xorm.io/core" + "xorm.io/xorm" ) func removeCommitsUnitType(x *xorm.Engine) (err error) { diff --git a/models/migrations/v39.go b/models/migrations/v39.go index 1312cb3313..f3b32ea873 100644 --- a/models/migrations/v39.go +++ b/models/migrations/v39.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // ReleaseV39 describes the added field for Release diff --git a/models/migrations/v40.go b/models/migrations/v40.go index fffe158bf9..944377ce9b 100644 --- a/models/migrations/v40.go +++ b/models/migrations/v40.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func fixProtectedBranchCanPushValue(x *xorm.Engine) error { diff --git a/models/migrations/v41.go b/models/migrations/v41.go index 4de3ad4e99..928bb1cd3f 100644 --- a/models/migrations/v41.go +++ b/models/migrations/v41.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func removeDuplicateUnitTypes(x *xorm.Engine) error { diff --git a/models/migrations/v45.go b/models/migrations/v45.go index 99baff2c8b..eb346d7b3a 100644 --- a/models/migrations/v45.go +++ b/models/migrations/v45.go @@ -8,7 +8,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func removeIndexColumnFromRepoUnitTable(x *xorm.Engine) (err error) { diff --git a/models/migrations/v46.go b/models/migrations/v46.go index b6dd059c94..3d9c1329d8 100644 --- a/models/migrations/v46.go +++ b/models/migrations/v46.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func removeOrganizationWatchRepo(x *xorm.Engine) error { diff --git a/models/migrations/v47.go b/models/migrations/v47.go index 7a217e6f01..81f92e2f5a 100644 --- a/models/migrations/v47.go +++ b/models/migrations/v47.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addDeletedBranch(x *xorm.Engine) (err error) { diff --git a/models/migrations/v48.go b/models/migrations/v48.go index 6cea66b5ac..6365feba89 100644 --- a/models/migrations/v48.go +++ b/models/migrations/v48.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addRepoIndexerStatus(x *xorm.Engine) error { diff --git a/models/migrations/v49.go b/models/migrations/v49.go index 9e98de5cf2..4776125137 100644 --- a/models/migrations/v49.go +++ b/models/migrations/v49.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addTimetracking(x *xorm.Engine) error { diff --git a/models/migrations/v50.go b/models/migrations/v50.go index 23b1bb526e..ddc378b432 100644 --- a/models/migrations/v50.go +++ b/models/migrations/v50.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func migrateProtectedBranchStruct(x *xorm.Engine) error { diff --git a/models/migrations/v51.go b/models/migrations/v51.go index 85e903bbe7..8dadcf3349 100644 --- a/models/migrations/v51.go +++ b/models/migrations/v51.go @@ -8,7 +8,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/log" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addDefaultValueToUserProhibitLogin(x *xorm.Engine) (err error) { diff --git a/models/migrations/v52.go b/models/migrations/v52.go index ab57d27de0..6547698d5b 100644 --- a/models/migrations/v52.go +++ b/models/migrations/v52.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addLFSLock(x *xorm.Engine) error { diff --git a/models/migrations/v53.go b/models/migrations/v53.go index 7437cace25..a3068cdb00 100644 --- a/models/migrations/v53.go +++ b/models/migrations/v53.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addReactions(x *xorm.Engine) error { diff --git a/models/migrations/v54.go b/models/migrations/v54.go index 5194624f69..af1e287419 100644 --- a/models/migrations/v54.go +++ b/models/migrations/v54.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addPullRequestOptions(x *xorm.Engine) error { diff --git a/models/migrations/v55.go b/models/migrations/v55.go index c20c51616e..a259e4f001 100644 --- a/models/migrations/v55.go +++ b/models/migrations/v55.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/models" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addModeToDeploKeys(x *xorm.Engine) error { diff --git a/models/migrations/v56.go b/models/migrations/v56.go index 79f8ce0ba5..4e1cafcca2 100644 --- a/models/migrations/v56.go +++ b/models/migrations/v56.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func removeIsOwnerColumnFromOrgUser(x *xorm.Engine) (err error) { diff --git a/models/migrations/v57.go b/models/migrations/v57.go index fe4bf6b0ee..6c0ab6f496 100644 --- a/models/migrations/v57.go +++ b/models/migrations/v57.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addIssueClosedTime(x *xorm.Engine) error { diff --git a/models/migrations/v58.go b/models/migrations/v58.go index 6ec24b08c8..0fa3bcfe2d 100644 --- a/models/migrations/v58.go +++ b/models/migrations/v58.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addLabelsDescriptions(x *xorm.Engine) error { diff --git a/models/migrations/v59.go b/models/migrations/v59.go index 0a05495e76..d442f2569e 100644 --- a/models/migrations/v59.go +++ b/models/migrations/v59.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addProtectedBranchMergeWhitelist(x *xorm.Engine) error { diff --git a/models/migrations/v60.go b/models/migrations/v60.go index 13ec38241a..6482e8e4a5 100644 --- a/models/migrations/v60.go +++ b/models/migrations/v60.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addFsckEnabledToRepo(x *xorm.Engine) error { diff --git a/models/migrations/v61.go b/models/migrations/v61.go index 8d9b7e2d23..13affaf068 100644 --- a/models/migrations/v61.go +++ b/models/migrations/v61.go @@ -12,7 +12,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addSizeToAttachment(x *xorm.Engine) error { diff --git a/models/migrations/v62.go b/models/migrations/v62.go index 0c2966854b..e7f6cf6890 100644 --- a/models/migrations/v62.go +++ b/models/migrations/v62.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addLastUsedPasscodeTOTP(x *xorm.Engine) error { diff --git a/models/migrations/v63.go b/models/migrations/v63.go index 6e7d940edc..62e8a299f6 100644 --- a/models/migrations/v63.go +++ b/models/migrations/v63.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addLanguageSetting(x *xorm.Engine) error { diff --git a/models/migrations/v64.go b/models/migrations/v64.go index 00637ca046..623cceddbc 100644 --- a/models/migrations/v64.go +++ b/models/migrations/v64.go @@ -7,7 +7,7 @@ package migrations import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addMultipleAssignees(x *xorm.Engine) error { diff --git a/models/migrations/v65.go b/models/migrations/v65.go index cc199d34e2..a87f8bc76c 100644 --- a/models/migrations/v65.go +++ b/models/migrations/v65.go @@ -3,7 +3,7 @@ package migrations import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addU2FReg(x *xorm.Engine) error { diff --git a/models/migrations/v66.go b/models/migrations/v66.go index 43acfb4ea5..8e9df97fea 100644 --- a/models/migrations/v66.go +++ b/models/migrations/v66.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addLoginSourceIDToPublicKeyTable(x *xorm.Engine) error { diff --git a/models/migrations/v67.go b/models/migrations/v67.go index 6cf3dd4d19..dee744e4d3 100644 --- a/models/migrations/v67.go +++ b/models/migrations/v67.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func removeStaleWatches(x *xorm.Engine) error { diff --git a/models/migrations/v68.go b/models/migrations/v68.go index d9e80ca80e..41c1f8f71d 100644 --- a/models/migrations/v68.go +++ b/models/migrations/v68.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/modules/log" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`) diff --git a/models/migrations/v69.go b/models/migrations/v69.go index 9a6e42e712..a08747edff 100644 --- a/models/migrations/v69.go +++ b/models/migrations/v69.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func moveTeamUnitsToTeamUnitTable(x *xorm.Engine) error { diff --git a/models/migrations/v70.go b/models/migrations/v70.go index 4ce1d4ee53..ef8dd85d6d 100644 --- a/models/migrations/v70.go +++ b/models/migrations/v70.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addIssueDependencies(x *xorm.Engine) (err error) { diff --git a/models/migrations/v71.go b/models/migrations/v71.go index 004f0a3f51..0b6aff61b2 100644 --- a/models/migrations/v71.go +++ b/models/migrations/v71.go @@ -11,8 +11,8 @@ import ( "code.gitea.io/gitea/modules/generate" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "golang.org/x/crypto/pbkdf2" + "xorm.io/xorm" ) func addScratchHash(x *xorm.Engine) error { diff --git a/models/migrations/v72.go b/models/migrations/v72.go index c99b46afd2..612f58aab5 100644 --- a/models/migrations/v72.go +++ b/models/migrations/v72.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addReview(x *xorm.Engine) error { diff --git a/models/migrations/v73.go b/models/migrations/v73.go index 1265b4519e..0c06e2ba5c 100644 --- a/models/migrations/v73.go +++ b/models/migrations/v73.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addMustChangePassword(x *xorm.Engine) error { diff --git a/models/migrations/v74.go b/models/migrations/v74.go index 66e958c7fa..f3b38418b7 100644 --- a/models/migrations/v74.go +++ b/models/migrations/v74.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addApprovalWhitelistsToProtectedBranches(x *xorm.Engine) error { type ProtectedBranch struct { diff --git a/models/migrations/v75.go b/models/migrations/v75.go index 58d1d34c98..208153b9b0 100644 --- a/models/migrations/v75.go +++ b/models/migrations/v75.go @@ -5,8 +5,8 @@ package migrations import ( - "github.com/go-xorm/xorm" "xorm.io/builder" + "xorm.io/xorm" ) func clearNonusedData(x *xorm.Engine) error { diff --git a/models/migrations/v76.go b/models/migrations/v76.go index e1fd6f100b..545bff64c5 100644 --- a/models/migrations/v76.go +++ b/models/migrations/v76.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addPullRequestRebaseWithMerge(x *xorm.Engine) error { diff --git a/models/migrations/v77.go b/models/migrations/v77.go index c564d4cf54..d62fbe7fb6 100644 --- a/models/migrations/v77.go +++ b/models/migrations/v77.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addUserDefaultTheme(x *xorm.Engine) error { diff --git a/models/migrations/v78.go b/models/migrations/v78.go index 8082996b6f..e4274ca605 100644 --- a/models/migrations/v78.go +++ b/models/migrations/v78.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func renameRepoIsBareToIsEmpty(x *xorm.Engine) error { diff --git a/models/migrations/v79.go b/models/migrations/v79.go index e246393957..3c3e77b8db 100644 --- a/models/migrations/v79.go +++ b/models/migrations/v79.go @@ -7,7 +7,7 @@ package migrations import ( "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addCanCloseIssuesViaCommitInAnyBranch(x *xorm.Engine) error { diff --git a/models/migrations/v80.go b/models/migrations/v80.go index d9040da601..3c1b3315cf 100644 --- a/models/migrations/v80.go +++ b/models/migrations/v80.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addIsLockedToIssues(x *xorm.Engine) error { // Issue see models/issue.go diff --git a/models/migrations/v81.go b/models/migrations/v81.go index 48e96508d9..271d479a64 100644 --- a/models/migrations/v81.go +++ b/models/migrations/v81.go @@ -7,7 +7,7 @@ package migrations import ( "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func changeU2FCounterType(x *xorm.Engine) error { diff --git a/models/migrations/v82.go b/models/migrations/v82.go index eb73f18343..3fb4b6c59e 100644 --- a/models/migrations/v82.go +++ b/models/migrations/v82.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func fixReleaseSha1OnReleaseTable(x *xorm.Engine) error { diff --git a/models/migrations/v83.go b/models/migrations/v83.go index cdc59292ab..6707dbdf81 100644 --- a/models/migrations/v83.go +++ b/models/migrations/v83.go @@ -7,7 +7,7 @@ package migrations import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addUploaderIDForAttachment(x *xorm.Engine) error { diff --git a/models/migrations/v84.go b/models/migrations/v84.go index 4acb94b9ce..baab29fcd7 100644 --- a/models/migrations/v84.go +++ b/models/migrations/v84.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addGPGKeyImport(x *xorm.Engine) error { diff --git a/models/migrations/v85.go b/models/migrations/v85.go index 6066d5ebe9..8c92f10b6e 100644 --- a/models/migrations/v85.go +++ b/models/migrations/v85.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func hashAppToken(x *xorm.Engine) error { diff --git a/models/migrations/v86.go b/models/migrations/v86.go index 492a08c71e..39c196ca6a 100644 --- a/models/migrations/v86.go +++ b/models/migrations/v86.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addHTTPMethodToWebhook(x *xorm.Engine) error { diff --git a/models/migrations/v87.go b/models/migrations/v87.go index c8c7011a08..6b5af5be33 100644 --- a/models/migrations/v87.go +++ b/models/migrations/v87.go @@ -5,7 +5,7 @@ package migrations import ( - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addAvatarFieldToRepository(x *xorm.Engine) error { diff --git a/models/migrations/v88.go b/models/migrations/v88.go index fef425db0a..7318995a8c 100644 --- a/models/migrations/v88.go +++ b/models/migrations/v88.go @@ -8,7 +8,7 @@ import ( "crypto/sha1" "fmt" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func hashContext(context string) string { diff --git a/models/migrations/v89.go b/models/migrations/v89.go index 83d0b1a8b9..a972b07b6d 100644 --- a/models/migrations/v89.go +++ b/models/migrations/v89.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addOriginalMigrationInfo(x *xorm.Engine) error { // Issue see models/issue.go diff --git a/models/migrations/v90.go b/models/migrations/v90.go index 09aceae2f9..72f7534dc8 100644 --- a/models/migrations/v90.go +++ b/models/migrations/v90.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func changeSomeColumnsLengthOfRepo(x *xorm.Engine) error { type Repository struct { diff --git a/models/migrations/v91.go b/models/migrations/v91.go index fea71b5d3b..3c49d9b96a 100644 --- a/models/migrations/v91.go +++ b/models/migrations/v91.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addIndexOnRepositoryAndComment(x *xorm.Engine) error { type Repository struct { diff --git a/models/migrations/v92.go b/models/migrations/v92.go index 090332f151..7ad5118176 100644 --- a/models/migrations/v92.go +++ b/models/migrations/v92.go @@ -5,8 +5,8 @@ package migrations import ( - "github.com/go-xorm/xorm" "xorm.io/builder" + "xorm.io/xorm" ) func removeLingeringIndexStatus(x *xorm.Engine) error { diff --git a/models/migrations/v93.go b/models/migrations/v93.go index 0b0441cd5d..0cb9d6631f 100644 --- a/models/migrations/v93.go +++ b/models/migrations/v93.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addEmailNotificationEnabledToUser(x *xorm.Engine) error { // User see models/user.go diff --git a/models/migrations/v94.go b/models/migrations/v94.go index 5fe8c3fa12..8c1e33b647 100644 --- a/models/migrations/v94.go +++ b/models/migrations/v94.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addStatusCheckColumnsForProtectedBranches(x *xorm.Engine) error { type ProtectedBranch struct { diff --git a/models/migrations/v95.go b/models/migrations/v95.go index f6e4e41c48..94787f7501 100644 --- a/models/migrations/v95.go +++ b/models/migrations/v95.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addCrossReferenceColumns(x *xorm.Engine) error { // Comment see models/comment.go diff --git a/models/migrations/v96.go b/models/migrations/v96.go index 34f67534c2..b8eb201591 100644 --- a/models/migrations/v96.go +++ b/models/migrations/v96.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func deleteOrphanedAttachments(x *xorm.Engine) error { diff --git a/models/migrations/v97.go b/models/migrations/v97.go index fa542f2ccd..8e58886e2e 100644 --- a/models/migrations/v97.go +++ b/models/migrations/v97.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addRepoAdminChangeTeamAccessColumnForUser(x *xorm.Engine) error { type User struct { diff --git a/models/migrations/v98.go b/models/migrations/v98.go index 3b9fdbb1c5..617e1ec3d7 100644 --- a/models/migrations/v98.go +++ b/models/migrations/v98.go @@ -4,7 +4,7 @@ package migrations -import "github.com/go-xorm/xorm" +import "xorm.io/xorm" func addOriginalAuthorOnMigratedReleases(x *xorm.Engine) error { type Release struct { diff --git a/models/migrations/v99.go b/models/migrations/v99.go index 3eb287af6c..00b4509721 100644 --- a/models/migrations/v99.go +++ b/models/migrations/v99.go @@ -8,7 +8,7 @@ import ( "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) func addTaskTable(x *xorm.Engine) error { diff --git a/models/models.go b/models/models.go index ea550cb839..0454ec6add 100644 --- a/models/models.go +++ b/models/models.go @@ -14,8 +14,8 @@ import ( // Needed for the MySQL driver _ "github.com/go-sql-driver/mysql" - "github.com/go-xorm/xorm" "xorm.io/core" + "xorm.io/xorm" // Needed for the Postgresql driver _ "github.com/lib/pq" diff --git a/models/oauth2_application.go b/models/oauth2_application.go index 46355a0b3f..4df207ae16 100644 --- a/models/oauth2_application.go +++ b/models/oauth2_application.go @@ -16,10 +16,10 @@ import ( "code.gitea.io/gitea/modules/timeutil" "github.com/dgrijalva/jwt-go" - "github.com/go-xorm/xorm" uuid "github.com/satori/go.uuid" "github.com/unknwon/com" "golang.org/x/crypto/bcrypt" + "xorm.io/xorm" ) // OAuth2Application represents an OAuth2 client (RFC 6749) diff --git a/models/org.go b/models/org.go index ca3bce81a1..2cc302dac6 100644 --- a/models/org.go +++ b/models/org.go @@ -14,9 +14,9 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "xorm.io/builder" + "xorm.io/xorm" ) // IsOwnedBy returns true if given user is in the owner team. diff --git a/models/org_team.go b/models/org_team.go index 10d53e3a86..a7a179f104 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -14,8 +14,8 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "xorm.io/builder" + "xorm.io/xorm" ) const ownerTeamName = "Owners" diff --git a/models/pull.go b/models/pull.go index 962e433fb0..817ea09cca 100644 --- a/models/pull.go +++ b/models/pull.go @@ -25,8 +25,8 @@ import ( "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "github.com/unknwon/com" + "xorm.io/xorm" ) var pullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength) diff --git a/models/repo.go b/models/repo.go index 06708d24ab..3b5395ce16 100644 --- a/models/repo.go +++ b/models/repo.go @@ -37,11 +37,11 @@ import ( "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "github.com/mcuadros/go-version" "github.com/unknwon/com" ini "gopkg.in/ini.v1" "xorm.io/builder" + "xorm.io/xorm" ) var repoWorkingPool = sync.NewExclusivePool() diff --git a/models/repo_activity.go b/models/repo_activity.go index 04612ae1ef..aa5c2217e0 100644 --- a/models/repo_activity.go +++ b/models/repo_activity.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/modules/git" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // ActivityAuthorData represents statistical git commit count data diff --git a/models/repo_mirror.go b/models/repo_mirror.go index 4e91ea296a..aa0ec26808 100644 --- a/models/repo_mirror.go +++ b/models/repo_mirror.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" + "xorm.io/xorm" ) // Mirror represents mirror information of a repository. diff --git a/models/repo_unit.go b/models/repo_unit.go index 2fc1c40fa2..a6162a65e5 100644 --- a/models/repo_unit.go +++ b/models/repo_unit.go @@ -9,9 +9,9 @@ import ( "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "xorm.io/core" + "xorm.io/xorm" ) // RepoUnit describes all units of a repository diff --git a/models/review.go b/models/review.go index 454d16ee88..58660b2e3d 100644 --- a/models/review.go +++ b/models/review.go @@ -10,9 +10,9 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "xorm.io/builder" "xorm.io/core" + "xorm.io/xorm" ) // ReviewType defines the sort of feedback a review gives diff --git a/models/ssh_key.go b/models/ssh_key.go index d1132bf0c6..69699f24c1 100644 --- a/models/ssh_key.go +++ b/models/ssh_key.go @@ -28,10 +28,10 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "golang.org/x/crypto/ssh" "xorm.io/builder" + "xorm.io/xorm" ) const ( diff --git a/models/unit_tests.go b/models/unit_tests.go index b53302dad4..eb4da37fe5 100644 --- a/models/unit_tests.go +++ b/models/unit_tests.go @@ -17,11 +17,11 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "github.com/stretchr/testify/assert" "github.com/unknwon/com" "gopkg.in/testfixtures.v2" "xorm.io/core" + "xorm.io/xorm" ) // NonexistentID an ID that will never exist diff --git a/models/user.go b/models/user.go index 030e23c383..c393d8dce5 100644 --- a/models/user.go +++ b/models/user.go @@ -33,7 +33,6 @@ import ( "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "golang.org/x/crypto/argon2" "golang.org/x/crypto/bcrypt" @@ -41,6 +40,7 @@ import ( "golang.org/x/crypto/scrypt" "golang.org/x/crypto/ssh" "xorm.io/builder" + "xorm.io/xorm" ) // UserType defines the user type diff --git a/modules/auth/oauth2/oauth2.go b/modules/auth/oauth2/oauth2.go index 242254e600..20dfb15e81 100644 --- a/modules/auth/oauth2/oauth2.go +++ b/modules/auth/oauth2/oauth2.go @@ -11,7 +11,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-xorm/xorm" "github.com/lafriks/xormstore" "github.com/markbates/goth" "github.com/markbates/goth/gothic" @@ -26,6 +25,7 @@ import ( "github.com/markbates/goth/providers/openidConnect" "github.com/markbates/goth/providers/twitter" "github.com/satori/go.uuid" + "xorm.io/xorm" ) var ( diff --git a/routers/install.go b/routers/install.go index 8f3d0d5ae6..53880d2c46 100644 --- a/routers/install.go +++ b/routers/install.go @@ -20,9 +20,9 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/user" - "github.com/go-xorm/xorm" "github.com/unknwon/com" "gopkg.in/ini.v1" + "xorm.io/xorm" ) const ( diff --git a/vendor/github.com/go-xorm/xorm/.drone.yml b/vendor/github.com/go-xorm/xorm/.drone.yml deleted file mode 100644 index b162d7c8a4..0000000000 --- a/vendor/github.com/go-xorm/xorm/.drone.yml +++ /dev/null @@ -1,823 +0,0 @@ ---- -kind: pipeline -name: matrix-1 - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -workspace: - base: /go - path: src/github.com/go-xorm/xorm - -steps: -- name: git - pull: default - image: plugins/git:next - settings: - depth: 50 - tags: true - -- name: init_postgres - pull: default - image: postgres:9.5 - commands: - - "until psql -U postgres -d xorm_test -h pgsql \\\n -c \"SELECT 1;\" >/dev/null 2>&1; do sleep 1; done\n" - - "psql -U postgres -d xorm_test -h pgsql \\\n -c \"create schema xorm;\"\n" - -- name: build - pull: default - image: golang:1.10 - commands: - - go get -t -d -v ./... - - go get -u xorm.io/core - - go get -u xorm.io/builder - - go build -v - when: - event: - - push - - pull_request - -- name: test-sqlite - pull: default - image: golang:1.10 - commands: - - go get -u github.com/wadey/gocovmerge - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql - pull: default - image: golang:1.10 - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql-utf8mb4 - pull: default - image: golang:1.10 - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mymysql - pull: default - image: golang:1.10 - commands: - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres - pull: default - image: golang:1.10 - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres-schema - pull: default - image: golang:1.10 - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mssql - pull: default - image: golang:1.10 - commands: - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-tidb - pull: default - image: golang:1.10 - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" - - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt - when: - event: - - push - - pull_request - -services: -- name: mysql - pull: default - image: mysql:5.7 - environment: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: xorm_test - when: - event: - - push - - tag - - pull_request - -- name: tidb - pull: default - image: pingcap/tidb:v3.0.3 - when: - event: - - push - - tag - - pull_request - -- name: pgsql - pull: default - image: postgres:9.5 - environment: - POSTGRES_DB: xorm_test - POSTGRES_USER: postgres - when: - event: - - push - - tag - - pull_request - -- name: mssql - pull: default - image: microsoft/mssql-server-linux:latest - environment: - ACCEPT_EULA: Y - SA_PASSWORD: yourStrong(!)Password - MSSQL_PID: Developer - when: - event: - - push - - tag - - pull_request - ---- -kind: pipeline -name: matrix-2 - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -workspace: - base: /go - path: src/github.com/go-xorm/xorm - -steps: -- name: git - pull: default - image: plugins/git:next - settings: - depth: 50 - tags: true - -- name: init_postgres - pull: default - image: postgres:9.5 - commands: - - "until psql -U postgres -d xorm_test -h pgsql \\\n -c \"SELECT 1;\" >/dev/null 2>&1; do sleep 1; done\n" - - "psql -U postgres -d xorm_test -h pgsql \\\n -c \"create schema xorm;\"\n" - -- name: build - pull: default - image: golang:1.11 - environment: - GO111MODULE: "off" - commands: - - go get -t -d -v ./... - - go get -u xorm.io/core - - go get -u xorm.io/builder - - go build -v - when: - event: - - push - - pull_request - -- name: build-gomod - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - go build -v - when: - event: - - push - - pull_request - -- name: test-sqlite - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql-utf8mb4 - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mymysql - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres-schema - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mssql - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - - when: - event: - - push - - pull_request - -- name: test-tidb - pull: default - image: golang:1.11 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" - - go get github.com/wadey/gocovmerge - - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt - when: - event: - - push - - pull_request - -services: -- name: mysql - pull: default - image: mysql:5.7 - environment: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: xorm_test - when: - event: - - push - - tag - - pull_request - -- name: tidb - pull: default - image: pingcap/tidb:v3.0.3 - when: - event: - - push - - tag - - pull_request - -- name: pgsql - pull: default - image: postgres:9.5 - environment: - POSTGRES_DB: xorm_test - POSTGRES_USER: postgres - when: - event: - - push - - tag - - pull_request - -- name: mssql - pull: default - image: microsoft/mssql-server-linux:latest - environment: - ACCEPT_EULA: Y - SA_PASSWORD: yourStrong(!)Password - MSSQL_PID: Developer - when: - event: - - push - - tag - - pull_request - ---- -kind: pipeline -name: matrix-3 - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -workspace: - base: /go - path: src/github.com/go-xorm/xorm - -steps: -- name: git - pull: default - image: plugins/git:next - settings: - depth: 50 - tags: true - -- name: build - pull: default - image: golang:1.12 - environment: - GO111MODULE: "off" - commands: - - go get -t -d -v ./... - - go get -u xorm.io/core - - go get -u xorm.io/builder - - go build -v - when: - event: - - push - - pull_request - -- name: build-gomod - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - go build -v - when: - event: - - push - - pull_request - -- name: test-sqlite - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql-utf8mb4 - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mymysql - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres-schema - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mssql - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-tidb - pull: default - image: golang:1.12 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" - - go get github.com/wadey/gocovmerge - - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt - when: - event: - - push - - pull_request - -services: -- name: mysql - pull: default - image: mysql:5.7 - environment: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: xorm_test - when: - event: - - push - - tag - - pull_request - -- name: tidb - pull: default - image: pingcap/tidb:v3.0.3 - when: - event: - - push - - tag - - pull_request - -- name: pgsql - pull: default - image: postgres:9.5 - environment: - POSTGRES_DB: xorm_test - POSTGRES_USER: postgres - when: - event: - - push - - tag - - pull_request - -- name: mssql - pull: default - image: microsoft/mssql-server-linux:latest - environment: - ACCEPT_EULA: Y - SA_PASSWORD: yourStrong(!)Password - MSSQL_PID: Developer - when: - event: - - push - - tag - - pull_request - ---- -kind: pipeline -name: go1.13 - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -workspace: - base: /go - path: src/github.com/go-xorm/xorm - -steps: -- name: git - pull: default - image: plugins/git:next - settings: - depth: 50 - tags: true - -- name: build - pull: default - image: golang:1.13 - environment: - GO111MODULE: "off" - commands: - - go get -t -d -v ./... - - go get -u xorm.io/core - - go get -u xorm.io/builder - - go build -v - when: - event: - - push - - pull_request - -- name: build-gomod - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - go build -v - when: - event: - - push - - pull_request - -- name: test-sqlite - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" - - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mysql-utf8mb4 - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mymysql - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" - - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-postgres-schema - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" - - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-mssql - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - when: - event: - - push - - pull_request - -- name: test-tidb - pull: default - image: golang:1.13 - environment: - GO111MODULE: "on" - GOPROXY: "https://goproxy.cn" - commands: - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" - - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" - - go get github.com/wadey/gocovmerge - - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt - when: - event: - - push - - pull_request - -services: -- name: mysql - pull: default - image: mysql:5.7 - environment: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: xorm_test - when: - event: - - push - - tag - - pull_request - -- name: tidb - pull: default - image: pingcap/tidb:v3.0.3 - when: - event: - - push - - tag - - pull_request - -- name: pgsql - pull: default - image: postgres:9.5 - environment: - POSTGRES_DB: xorm_test - POSTGRES_USER: postgres - when: - event: - - push - - tag - - pull_request - -- name: mssql - pull: default - image: microsoft/mssql-server-linux:latest - environment: - ACCEPT_EULA: Y - SA_PASSWORD: yourStrong(!)Password - MSSQL_PID: Developer - when: - event: - - push - - tag - - pull_request \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/.gitignore b/vendor/github.com/go-xorm/xorm/.gitignore deleted file mode 100644 index f1757b9830..0000000000 --- a/vendor/github.com/go-xorm/xorm/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so -*.db - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe - -*.log -.vendor -temp_test.go -.vscode -xorm.test -*.sqlite3 -test.db.sql - -.idea/ diff --git a/vendor/github.com/go-xorm/xorm/CONTRIBUTING.md b/vendor/github.com/go-xorm/xorm/CONTRIBUTING.md deleted file mode 100644 index 37f4bc5fa8..0000000000 --- a/vendor/github.com/go-xorm/xorm/CONTRIBUTING.md +++ /dev/null @@ -1,46 +0,0 @@ -## Contributing to xorm - -`xorm` has a backlog of [pull requests](https://help.github.com/articles/using-pull-requests), but contributions are still very -much welcome. You can help with patch review, submitting bug reports, -or adding new functionality. There is no formal style guide, but -please conform to the style of existing code and general Go formatting -conventions when submitting patches. - -* [fork a repo](https://help.github.com/articles/fork-a-repo) -* [creating a pull request ](https://help.github.com/articles/creating-a-pull-request) - -### Language - -Since `xorm` is a world-wide open source project, please describe your issues or code changes in English as soon as possible. - -### Sign your codes with comments -``` -// !! your comments - -e.g., - -// !lunny! this is comments made by lunny -``` - -### Patch review - -Help review existing open [pull requests](https://help.github.com/articles/using-pull-requests) by commenting on the code or -proposed functionality. - -### Bug reports - -We appreciate any bug reports, but especially ones with self-contained -(doesn't depend on code outside of xorm), minimal (can't be simplified -further) test cases. It's especially helpful if you can submit a pull -request with just the failing test case(you can find some example test file like [session_get_test.go](https://github.com/go-xorm/xorm/blob/master/session_get_test.go)). - -If you implements a new database interface, you maybe need to add a test_.sh file. -For example, [mysql_test.go](https://github.com/go-xorm/xorm/blob/master/test_mysql.sh) - -### New functionality - -There are a number of pending patches for new functionality, so -additional feature patches will take a while to merge. Still, patches -are generally reviewed based on usefulness and complexity in addition -to time-in-queue, so if you have a knockout idea, take a shot. Feel -free to open an issue discussion your proposed patch beforehand. diff --git a/vendor/github.com/go-xorm/xorm/LICENSE b/vendor/github.com/go-xorm/xorm/LICENSE deleted file mode 100644 index 84d2ae5386..0000000000 --- a/vendor/github.com/go-xorm/xorm/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013 - 2015 The Xorm Authors -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/go-xorm/xorm/README.md b/vendor/github.com/go-xorm/xorm/README.md deleted file mode 100644 index 62b40ba304..0000000000 --- a/vendor/github.com/go-xorm/xorm/README.md +++ /dev/null @@ -1,503 +0,0 @@ -# xorm - -[中文](https://github.com/go-xorm/xorm/blob/master/README_CN.md) - -Xorm is a simple and powerful ORM for Go. - -[![CircleCI](https://circleci.com/gh/go-xorm/xorm.svg?style=shield)](https://circleci.com/gh/go-xorm/xorm) [![codecov](https://codecov.io/gh/go-xorm/xorm/branch/master/graph/badge.svg)](https://codecov.io/gh/go-xorm/xorm) -[![](https://goreportcard.com/badge/github.com/go-xorm/xorm)](https://goreportcard.com/report/github.com/go-xorm/xorm) -[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](https://discord.gg/HuR2CF3) - -## Features - -* Struct <-> Table Mapping Support - -* Chainable APIs - -* Transaction Support - -* Both ORM and raw SQL operation Support - -* Sync database schema Support - -* Query Cache speed up - -* Database Reverse support, See [Xorm Tool README](https://github.com/go-xorm/cmd/blob/master/README.md) - -* Simple cascade loading support - -* Optimistic Locking support - -* SQL Builder support via [xorm.io/builder](https://xorm.io/builder) - -* Automatical Read/Write seperatelly - -* Postgres schema support - -* Context Cache support - -## Drivers Support - -Drivers for Go's sql package which currently support database/sql includes: - -* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) - -* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/tree/master/godrv) - -* Postgres: [github.com/lib/pq](https://github.com/lib/pq) - -* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb) - -* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) - -* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) - -* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment) - -## Installation - - go get github.com/go-xorm/xorm - -## Documents - -* [Manual](http://xorm.io/docs) - -* [GoDoc](http://godoc.org/github.com/go-xorm/xorm) - -## Quick Start - -* Create Engine - -```Go -engine, err := xorm.NewEngine(driverName, dataSourceName) -``` - -* Define a struct and Sync2 table struct to database - -```Go -type User struct { - Id int64 - Name string - Salt string - Age int - Passwd string `xorm:"varchar(200)"` - Created time.Time `xorm:"created"` - Updated time.Time `xorm:"updated"` -} - -err := engine.Sync2(new(User)) -``` - -* Create Engine Group - -```Go -dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName} -engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice) -``` - -```Go -masterEngine, err := xorm.NewEngine(driverName, masterDataSourceName) -slave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName) -slave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName) -engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine}) -``` - -Then all place where `engine` you can just use `engineGroup`. - -* `Query` runs a SQL string, the returned results is `[]map[string][]byte`, `QueryString` returns `[]map[string]string`, `QueryInterface` returns `[]map[string]interface{}`. - -```Go -results, err := engine.Query("select * from user") -results, err := engine.Where("a = 1").Query() - -results, err := engine.QueryString("select * from user") -results, err := engine.Where("a = 1").QueryString() - -results, err := engine.QueryInterface("select * from user") -results, err := engine.Where("a = 1").QueryInterface() -``` - -* `Exec` runs a SQL string, it returns `affected` and `error` - -```Go -affected, err := engine.Exec("update user set age = ? where name = ?", age, name) -``` - -* `Insert` one or multiple records to database - -```Go -affected, err := engine.Insert(&user) -// INSERT INTO struct () values () - -affected, err := engine.Insert(&user1, &user2) -// INSERT INTO struct1 () values () -// INSERT INTO struct2 () values () - -affected, err := engine.Insert(&users) -// INSERT INTO struct () values (),(),() - -affected, err := engine.Insert(&user1, &users) -// INSERT INTO struct1 () values () -// INSERT INTO struct2 () values (),(),() -``` - -* `Get` query one record from database - -```Go -has, err := engine.Get(&user) -// SELECT * FROM user LIMIT 1 - -has, err := engine.Where("name = ?", name).Desc("id").Get(&user) -// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1 - -var name string -has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name) -// SELECT name FROM user WHERE id = ? - -var id int64 -has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id) -has, err := engine.SQL("select id from user").Get(&id) -// SELECT id FROM user WHERE name = ? - -var valuesMap = make(map[string]string) -has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap) -// SELECT * FROM user WHERE id = ? - -var valuesSlice = make([]interface{}, len(cols)) -has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice) -// SELECT col1, col2, col3 FROM user WHERE id = ? -``` - -* `Exist` check if one record exist on table - -```Go -has, err := testEngine.Exist(new(RecordExist)) -// SELECT * FROM record_exist LIMIT 1 - -has, err = testEngine.Exist(&RecordExist{ - Name: "test1", - }) -// SELECT * FROM record_exist WHERE name = ? LIMIT 1 - -has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{}) -// SELECT * FROM record_exist WHERE name = ? LIMIT 1 - -has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist() -// select * from record_exist where name = ? - -has, err = testEngine.Table("record_exist").Exist() -// SELECT * FROM record_exist LIMIT 1 - -has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist() -// SELECT * FROM record_exist WHERE name = ? LIMIT 1 -``` - -* `Find` query multiple records from database, also you can use join and extends - -```Go -var users []User -err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users) -// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0 - -type Detail struct { - Id int64 - UserId int64 `xorm:"index"` -} - -type UserDetail struct { - User `xorm:"extends"` - Detail `xorm:"extends"` -} - -var users []UserDetail -err := engine.Table("user").Select("user.*, detail.*"). - Join("INNER", "detail", "detail.user_id = user.id"). - Where("user.name = ?", name).Limit(10, 0). - Find(&users) -// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0 -``` - -* `Iterate` and `Rows` query multiple records and record by record handle, there are two methods Iterate and Rows - -```Go -err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error { - user := bean.(*User) - return nil -}) -// SELECT * FROM user - -err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error { - user := bean.(*User) - return nil -}) -// SELECT * FROM user Limit 0, 100 -// SELECT * FROM user Limit 101, 100 - -rows, err := engine.Rows(&User{Name:name}) -// SELECT * FROM user -defer rows.Close() -bean := new(Struct) -for rows.Next() { - err = rows.Scan(bean) -} -``` - -* `Update` update one or more records, default will update non-empty and non-zero fields except when you use Cols, AllCols and so on. - -```Go -affected, err := engine.ID(1).Update(&user) -// UPDATE user SET ... Where id = ? - -affected, err := engine.Update(&user, &User{Name:name}) -// UPDATE user SET ... Where name = ? - -var ids = []int64{1, 2, 3} -affected, err := engine.In("id", ids).Update(&user) -// UPDATE user SET ... Where id IN (?, ?, ?) - -// force update indicated columns by Cols -affected, err := engine.ID(1).Cols("age").Update(&User{Name:name, Age: 12}) -// UPDATE user SET age = ?, updated=? Where id = ? - -// force NOT update indicated columns by Omit -affected, err := engine.ID(1).Omit("name").Update(&User{Name:name, Age: 12}) -// UPDATE user SET age = ?, updated=? Where id = ? - -affected, err := engine.ID(1).AllCols().Update(&user) -// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ? -``` - -* `Delete` delete one or more records, Delete MUST have condition - -```Go -affected, err := engine.Where(...).Delete(&user) -// DELETE FROM user Where ... - -affected, err := engine.ID(2).Delete(&user) -// DELETE FROM user Where id = ? -``` - -* `Count` count records - -```Go -counts, err := engine.Count(&user) -// SELECT count(*) AS total FROM user -``` - -* `FindAndCount` combines function `Find` with `Count` which is usually used in query by page - -```Go -var users []User -counts, err := engine.FindAndCount(&users) -``` - -* `Sum` sum functions - -```Go -agesFloat64, err := engine.Sum(&user, "age") -// SELECT sum(age) AS total FROM user - -agesInt64, err := engine.SumInt(&user, "age") -// SELECT sum(age) AS total FROM user - -sumFloat64Slice, err := engine.Sums(&user, "age", "score") -// SELECT sum(age), sum(score) FROM user - -sumInt64Slice, err := engine.SumsInt(&user, "age", "score") -// SELECT sum(age), sum(score) FROM user -``` - -* Query conditions builder - -```Go -err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users) -// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?) -``` - -* Multiple operations in one go routine, no transation here but resue session memory - -```Go -session := engine.NewSession() -defer session.Close() - -user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} -if _, err := session.Insert(&user1); err != nil { - return err -} - -user2 := Userinfo{Username: "yyy"} -if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { - return err -} - -if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { - return err -} - -return nil -``` - -* Transation should on one go routine. There is transaction and resue session memory - -```Go -session := engine.NewSession() -defer session.Close() - -// add Begin() before any action -if err := session.Begin(); err != nil { - // if returned then will rollback automatically - return err -} - -user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} -if _, err := session.Insert(&user1); err != nil { - return err -} - -user2 := Userinfo{Username: "yyy"} -if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { - return err -} - -if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { - return err -} - -// add Commit() after all actions -return session.Commit() -``` - -* Or you can use `Transaction` to replace above codes. - -```Go -res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) { - user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} - if _, err := session.Insert(&user1); err != nil { - return nil, err - } - - user2 := Userinfo{Username: "yyy"} - if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { - return nil, err - } - - if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { - return nil, err - } - return nil, nil -}) -``` - -* Context Cache, if enabled, current query result will be cached on session and be used by next same statement on the same session. - -```Go - sess := engine.NewSession() - defer sess.Close() - - var context = xorm.NewMemoryContextCache() - - var c2 ContextGetStruct - has, err := sess.ID(1).ContextCache(context).Get(&c2) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, 1, c2.Id) - assert.EqualValues(t, "1", c2.Name) - sql, args := sess.LastSQL() - assert.True(t, len(sql) > 0) - assert.True(t, len(args) > 0) - - var c3 ContextGetStruct - has, err = sess.ID(1).ContextCache(context).Get(&c3) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, 1, c3.Id) - assert.EqualValues(t, "1", c3.Name) - sql, args = sess.LastSQL() - assert.True(t, len(sql) == 0) - assert.True(t, len(args) == 0) -``` - -## Contributing - -If you want to pull request, please see [CONTRIBUTING](https://github.com/go-xorm/xorm/blob/master/CONTRIBUTING.md). And we also provide [Xorm on Google Groups](https://groups.google.com/forum/#!forum/xorm) to discuss. - -## Credits - -### Contributors - -This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. - - -### Backers - -Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/xorm#backer)] - - - -### Sponsors - -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/xorm#sponsor)] - -## Changelog - -* **v0.7.0** - * Some bugs fixed - -* **v0.6.6** - * Some bugs fixed - -* **v0.6.5** - * Postgres schema support - * vgo support - * Add FindAndCount - * Database special params support via NewEngineWithParams - * Some bugs fixed - -* **v0.6.4** - * Automatical Read/Write seperatelly - * Query/QueryString/QueryInterface and action with Where/And - * Get support non-struct variables - * BufferSize on Iterate - * fix some other bugs. - -[More changes ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16) - -## Cases - -* [studygolang](http://studygolang.com/) - [github.com/studygolang/studygolang](https://github.com/studygolang/studygolang) - -* [Gitea](http://gitea.io) - [github.com/go-gitea/gitea](http://github.com/go-gitea/gitea) - -* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs) - -* [grafana](https://grafana.com/) - [github.com/grafana/grafana](http://github.com/grafana/grafana) - -* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader) - -* [Wego](http://github.com/go-tango/wego) - -* [Docker.cn](https://docker.cn/) - -* [Xorm Adapter](https://github.com/casbin/xorm-adapter) for [Casbin](https://github.com/casbin/casbin) - [github.com/casbin/xorm-adapter](https://github.com/casbin/xorm-adapter) - -* [Gorevel](http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel) - -* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker) - -* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild) - -* [Sudo China](http://sudochina.com) - [github.com/insionng/toropress](http://github.com/insionng/toropress) - -* [Godaily](http://godaily.org) - [github.com/govc/godaily](http://github.com/govc/godaily) - -* [YouGam](http://www.yougam.com/) - -* [GoCMS - github.com/zzboy/GoCMS](https://github.com/zzdboy/GoCMS) - -* [GoBBS - gobbs.domolo.com](http://gobbs.domolo.com/) - -* [go-blog](http://wangcheng.me) - [github.com/easykoo/go-blog](https://github.com/easykoo/go-blog) - -## LICENSE - -BSD License [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/) diff --git a/vendor/github.com/go-xorm/xorm/README_CN.md b/vendor/github.com/go-xorm/xorm/README_CN.md deleted file mode 100644 index 0cec6ed5c6..0000000000 --- a/vendor/github.com/go-xorm/xorm/README_CN.md +++ /dev/null @@ -1,500 +0,0 @@ -# xorm - -[English](https://github.com/go-xorm/xorm/blob/master/README.md) - -xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。 - -[![CircleCI](https://circleci.com/gh/go-xorm/xorm.svg?style=shield)](https://circleci.com/gh/go-xorm/xorm) [![codecov](https://codecov.io/gh/go-xorm/xorm/branch/master/graph/badge.svg)](https://codecov.io/gh/go-xorm/xorm) -[![](https://goreportcard.com/badge/github.com/go-xorm/xorm)](https://goreportcard.com/report/github.com/go-xorm/xorm) -[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](https://discord.gg/HuR2CF3) - -## 特性 - -* 支持Struct和数据库表之间的灵活映射,并支持自动同步 - -* 事务支持 - -* 同时支持原始SQL语句和ORM操作的混合执行 - -* 使用连写来简化调用 - -* 支持使用Id, In, Where, Limit, Join, Having, Table, Sql, Cols等函数和结构体等方式作为条件 - -* 支持级联加载Struct - -* Schema支持(仅Postgres) - -* 支持缓存 - -* 支持根据数据库自动生成xorm的结构体 - -* 支持记录版本(即乐观锁) - -* 内置SQL Builder支持 - -* 上下文缓存支持 - -## 驱动支持 - -目前支持的Go数据库驱动和对应的数据库如下: - -* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) - -* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv) - -* Postgres: [github.com/lib/pq](https://github.com/lib/pq) - -* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb) - -* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) - -* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) - -* MsSql: [github.com/lunny/godbc](https://github.com/lunny/godbc) - -* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (试验性支持) - -## 安装 - - go get github.com/go-xorm/xorm - -## 文档 - -* [操作指南](http://xorm.io/docs) - -* [GoWalker代码文档](http://gowalker.org/github.com/go-xorm/xorm) - -* [Godoc代码文档](http://godoc.org/github.com/go-xorm/xorm) - -# 快速开始 - -* 第一步创建引擎,driverName, dataSourceName和database/sql接口相同 - -```Go -engine, err := xorm.NewEngine(driverName, dataSourceName) -``` - -* 定义一个和表同步的结构体,并且自动同步结构体到数据库 - -```Go -type User struct { - Id int64 - Name string - Salt string - Age int - Passwd string `xorm:"varchar(200)"` - Created time.Time `xorm:"created"` - Updated time.Time `xorm:"updated"` -} - -err := engine.Sync2(new(User)) -``` - -* 创建Engine组 - -```Go -dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName} -engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice) -``` - -```Go -masterEngine, err := xorm.NewEngine(driverName, masterDataSourceName) -slave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName) -slave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName) -engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine}) -``` - -所有使用 `engine` 都可以简单的用 `engineGroup` 来替换。 - -* `Query` 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte。`QueryString` 返回 []map[string]string, `QueryInterface` 返回 `[]map[string]interface{}`. - -```Go -results, err := engine.Query("select * from user") -results, err := engine.Where("a = 1").Query() - -results, err := engine.QueryString("select * from user") -results, err := engine.Where("a = 1").QueryString() - -results, err := engine.QueryInterface("select * from user") -results, err := engine.Where("a = 1").QueryInterface() -``` - -* `Exec` 执行一个SQL语句 - -```Go -affected, err := engine.Exec("update user set age = ? where name = ?", age, name) -``` - -* `Insert` 插入一条或者多条记录 - -```Go -affected, err := engine.Insert(&user) -// INSERT INTO struct () values () - -affected, err := engine.Insert(&user1, &user2) -// INSERT INTO struct1 () values () -// INSERT INTO struct2 () values () - -affected, err := engine.Insert(&users) -// INSERT INTO struct () values (),(),() - -affected, err := engine.Insert(&user1, &users) -// INSERT INTO struct1 () values () -// INSERT INTO struct2 () values (),(),() -``` - -* `Get` 查询单条记录 - -```Go -has, err := engine.Get(&user) -// SELECT * FROM user LIMIT 1 - -has, err := engine.Where("name = ?", name).Desc("id").Get(&user) -// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1 - -var name string -has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name) -// SELECT name FROM user WHERE id = ? - -var id int64 -has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id) -has, err := engine.SQL("select id from user").Get(&id) -// SELECT id FROM user WHERE name = ? - -var valuesMap = make(map[string]string) -has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap) -// SELECT * FROM user WHERE id = ? - -var valuesSlice = make([]interface{}, len(cols)) -has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice) -// SELECT col1, col2, col3 FROM user WHERE id = ? -``` - -* `Exist` 检测记录是否存在 - -```Go -has, err := testEngine.Exist(new(RecordExist)) -// SELECT * FROM record_exist LIMIT 1 - -has, err = testEngine.Exist(&RecordExist{ - Name: "test1", - }) -// SELECT * FROM record_exist WHERE name = ? LIMIT 1 - -has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{}) -// SELECT * FROM record_exist WHERE name = ? LIMIT 1 - -has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist() -// select * from record_exist where name = ? - -has, err = testEngine.Table("record_exist").Exist() -// SELECT * FROM record_exist LIMIT 1 - -has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist() -// SELECT * FROM record_exist WHERE name = ? LIMIT 1 -``` - -* `Find` 查询多条记录,当然可以使用Join和extends来组合使用 - -```Go -var users []User -err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users) -// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0 - -type Detail struct { - Id int64 - UserId int64 `xorm:"index"` -} - -type UserDetail struct { - User `xorm:"extends"` - Detail `xorm:"extends"` -} - -var users []UserDetail -err := engine.Table("user").Select("user.*, detail.*") - Join("INNER", "detail", "detail.user_id = user.id"). - Where("user.name = ?", name).Limit(10, 0). - Find(&users) -// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0 -``` - -* `Iterate` 和 `Rows` 根据条件遍历数据库,可以有两种方式: Iterate and Rows - -```Go -err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error { - user := bean.(*User) - return nil -}) -// SELECT * FROM user - -err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error { - user := bean.(*User) - return nil -}) -// SELECT * FROM user Limit 0, 100 -// SELECT * FROM user Limit 101, 100 - -rows, err := engine.Rows(&User{Name:name}) -// SELECT * FROM user -defer rows.Close() -bean := new(Struct) -for rows.Next() { - err = rows.Scan(bean) -} -``` - -* `Update` 更新数据,除非使用Cols,AllCols函数指明,默认只更新非空和非0的字段 - -```Go -affected, err := engine.ID(1).Update(&user) -// UPDATE user SET ... Where id = ? - -affected, err := engine.Update(&user, &User{Name:name}) -// UPDATE user SET ... Where name = ? - -var ids = []int64{1, 2, 3} -affected, err := engine.In(ids).Update(&user) -// UPDATE user SET ... Where id IN (?, ?, ?) - -// force update indicated columns by Cols -affected, err := engine.ID(1).Cols("age").Update(&User{Name:name, Age: 12}) -// UPDATE user SET age = ?, updated=? Where id = ? - -// force NOT update indicated columns by Omit -affected, err := engine.ID(1).Omit("name").Update(&User{Name:name, Age: 12}) -// UPDATE user SET age = ?, updated=? Where id = ? - -affected, err := engine.ID(1).AllCols().Update(&user) -// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ? -``` - -* `Delete` 删除记录,需要注意,删除必须至少有一个条件,否则会报错。要清空数据库可以用EmptyTable - -```Go -affected, err := engine.Where(...).Delete(&user) -// DELETE FROM user Where ... - -affected, err := engine.ID(2).Delete(&user) -// DELETE FROM user Where id = ? -``` - -* `Count` 获取记录条数 - -```Go -counts, err := engine.Count(&user) -// SELECT count(*) AS total FROM user -``` - -* `Sum` 求和函数 - -```Go -agesFloat64, err := engine.Sum(&user, "age") -// SELECT sum(age) AS total FROM user - -agesInt64, err := engine.SumInt(&user, "age") -// SELECT sum(age) AS total FROM user - -sumFloat64Slice, err := engine.Sums(&user, "age", "score") -// SELECT sum(age), sum(score) FROM user - -sumInt64Slice, err := engine.SumsInt(&user, "age", "score") -// SELECT sum(age), sum(score) FROM user -``` - -* 条件编辑器 - -```Go -err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users) -// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?) -``` - -* 在一个Go程中多次操作数据库,但没有事务 - -```Go -session := engine.NewSession() -defer session.Close() - -user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} -if _, err := session.Insert(&user1); err != nil { - return err -} - -user2 := Userinfo{Username: "yyy"} -if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { - return err -} - -if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { - return err -} - -return nil -``` - -* 在一个Go程中有事务 - -```Go -session := engine.NewSession() -defer session.Close() - -// add Begin() before any action -if err := session.Begin(); err != nil { - // if returned then will rollback automatically - return err -} - -user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} -if _, err := session.Insert(&user1); err != nil { - return err -} - -user2 := Userinfo{Username: "yyy"} -if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { - return err -} - -if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { - return err -} - -// add Commit() after all actions -return session.Commit() -``` - -* 事务的简写方法 - -```Go -res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) { - user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} - if _, err := session.Insert(&user1); err != nil { - return nil, err - } - - user2 := Userinfo{Username: "yyy"} - if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { - return nil, err - } - - if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { - return nil, err - } - return nil, nil -}) -``` - -* 上下文缓存,如果启用,那么针对单个对象的查询将会被缓存到系统中,可以被下一个查询使用。 - -```Go - sess := engine.NewSession() - defer sess.Close() - - var context = xorm.NewMemoryContextCache() - - var c2 ContextGetStruct - has, err := sess.ID(1).ContextCache(context).Get(&c2) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, 1, c2.Id) - assert.EqualValues(t, "1", c2.Name) - sql, args := sess.LastSQL() - assert.True(t, len(sql) > 0) - assert.True(t, len(args) > 0) - - var c3 ContextGetStruct - has, err = sess.ID(1).ContextCache(context).Get(&c3) - assert.NoError(t, err) - assert.True(t, has) - assert.EqualValues(t, 1, c3.Id) - assert.EqualValues(t, "1", c3.Name) - sql, args = sess.LastSQL() - assert.True(t, len(sql) == 0) - assert.True(t, len(args) == 0) -``` - -## 贡献 - -如果您也想为Xorm贡献您的力量,请查看 [CONTRIBUTING](https://github.com/go-xorm/xorm/blob/master/CONTRIBUTING.md)。您也可以加入QQ群 技术帮助和讨论。 -群一:280360085 (已满) -群二:795010183 - -## Credits - -### Contributors - -感谢所有的贡献者. [[Contribute](CONTRIBUTING.md)]. - - -### Backers - -感谢我们所有的 backers! 🙏 [[成为 backer](https://opencollective.com/xorm#backer)] - - - -### Sponsors - -成为 sponsor 来支持 xorm。您的 logo 将会被显示并被链接到您的网站。 [[成为 sponsor](https://opencollective.com/xorm#sponsor)] - -# 案例 - -* [Go语言中文网](http://studygolang.com/) - [github.com/studygolang/studygolang](https://github.com/studygolang/studygolang) - -* [Gitea](http://gitea.io) - [github.com/go-gitea/gitea](http://github.com/go-gitea/gitea) - -* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs) - -* [grafana](https://grafana.com/) - [github.com/grafana/grafana](http://github.com/grafana/grafana) - -* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader) - -* [Wego](http://github.com/go-tango/wego) - -* [Docker.cn](https://docker.cn/) - -* [Xorm Adapter](https://github.com/casbin/xorm-adapter) for [Casbin](https://github.com/casbin/casbin) - [github.com/casbin/xorm-adapter](https://github.com/casbin/xorm-adapter) - -* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker) - -* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild) - -* [Sudo China](http://sudochina.com) - [github.com/insionng/toropress](http://github.com/insionng/toropress) - -* [Godaily](http://godaily.org) - [github.com/govc/godaily](http://github.com/govc/godaily) - -* [YouGam](http://www.yougam.com/) - -* [GoCMS - github.com/zzboy/GoCMS](https://github.com/zzdboy/GoCMS) - -* [GoBBS - gobbs.domolo.com](http://gobbs.domolo.com/) - -* [go-blog](http://wangcheng.me) - [github.com/easykoo/go-blog](https://github.com/easykoo/go-blog) - - -## 更新日志 - -* **v0.7.0** - * 修正部分Bug - -* **v0.6.6** - * 修正部分Bug - -* **v0.6.5** - * 通过 engine.SetSchema 来支持 schema,当前仅支持Postgres - * vgo 支持 - * 新增 `FindAndCount` 函数 - * 通过 `NewEngineWithParams` 支持数据库特别参数 - * 修正部分Bug - -* **v0.6.4** - * 自动读写分离支持 - * Query/QueryString/QueryInterface 支持与 Where/And 合用 - * `Get` 支持获取非结构体变量 - * `Iterate` 支持 `BufferSize` - * 修正部分Bug - -[更多更新日志...](https://github.com/go-xorm/manual-zh-CN/tree/master/chapter-16) - -## LICENSE - -BSD License -[http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/) diff --git a/vendor/github.com/go-xorm/xorm/cache_lru.go b/vendor/github.com/go-xorm/xorm/cache_lru.go deleted file mode 100644 index ab948bd28e..0000000000 --- a/vendor/github.com/go-xorm/xorm/cache_lru.go +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "container/list" - "fmt" - "sync" - "time" - - "xorm.io/core" -) - -// LRUCacher implments cache object facilities -type LRUCacher struct { - idList *list.List - sqlList *list.List - idIndex map[string]map[string]*list.Element - sqlIndex map[string]map[string]*list.Element - store core.CacheStore - mutex sync.Mutex - MaxElementSize int - Expired time.Duration - GcInterval time.Duration -} - -// NewLRUCacher creates a cacher -func NewLRUCacher(store core.CacheStore, maxElementSize int) *LRUCacher { - return NewLRUCacher2(store, 3600*time.Second, maxElementSize) -} - -// NewLRUCacher2 creates a cache include different params -func NewLRUCacher2(store core.CacheStore, expired time.Duration, maxElementSize int) *LRUCacher { - cacher := &LRUCacher{store: store, idList: list.New(), - sqlList: list.New(), Expired: expired, - GcInterval: core.CacheGcInterval, MaxElementSize: maxElementSize, - sqlIndex: make(map[string]map[string]*list.Element), - idIndex: make(map[string]map[string]*list.Element), - } - cacher.RunGC() - return cacher -} - -// RunGC run once every m.GcInterval -func (m *LRUCacher) RunGC() { - time.AfterFunc(m.GcInterval, func() { - m.RunGC() - m.GC() - }) -} - -// GC check ids lit and sql list to remove all element expired -func (m *LRUCacher) GC() { - m.mutex.Lock() - defer m.mutex.Unlock() - var removedNum int - for e := m.idList.Front(); e != nil; { - if removedNum <= core.CacheGcMaxRemoved && - time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired { - removedNum++ - next := e.Next() - node := e.Value.(*idNode) - m.delBean(node.tbName, node.id) - e = next - } else { - break - } - } - - removedNum = 0 - for e := m.sqlList.Front(); e != nil; { - if removedNum <= core.CacheGcMaxRemoved && - time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired { - removedNum++ - next := e.Next() - node := e.Value.(*sqlNode) - m.delIds(node.tbName, node.sql) - e = next - } else { - break - } - } -} - -// GetIds returns all bean's ids according to sql and parameter from cache -func (m *LRUCacher) GetIds(tableName, sql string) interface{} { - m.mutex.Lock() - defer m.mutex.Unlock() - if _, ok := m.sqlIndex[tableName]; !ok { - m.sqlIndex[tableName] = make(map[string]*list.Element) - } - if v, err := m.store.Get(sql); err == nil { - if el, ok := m.sqlIndex[tableName][sql]; !ok { - el = m.sqlList.PushBack(newSQLNode(tableName, sql)) - m.sqlIndex[tableName][sql] = el - } else { - lastTime := el.Value.(*sqlNode).lastVisit - // if expired, remove the node and return nil - if time.Now().Sub(lastTime) > m.Expired { - m.delIds(tableName, sql) - return nil - } - m.sqlList.MoveToBack(el) - el.Value.(*sqlNode).lastVisit = time.Now() - } - return v - } - - m.delIds(tableName, sql) - return nil -} - -// GetBean returns bean according tableName and id from cache -func (m *LRUCacher) GetBean(tableName string, id string) interface{} { - m.mutex.Lock() - defer m.mutex.Unlock() - if _, ok := m.idIndex[tableName]; !ok { - m.idIndex[tableName] = make(map[string]*list.Element) - } - tid := genID(tableName, id) - if v, err := m.store.Get(tid); err == nil { - if el, ok := m.idIndex[tableName][id]; ok { - lastTime := el.Value.(*idNode).lastVisit - // if expired, remove the node and return nil - if time.Now().Sub(lastTime) > m.Expired { - m.delBean(tableName, id) - return nil - } - m.idList.MoveToBack(el) - el.Value.(*idNode).lastVisit = time.Now() - } else { - el = m.idList.PushBack(newIDNode(tableName, id)) - m.idIndex[tableName][id] = el - } - return v - } - - // store bean is not exist, then remove memory's index - m.delBean(tableName, id) - return nil -} - -// clearIds clears all sql-ids mapping on table tableName from cache -func (m *LRUCacher) clearIds(tableName string) { - if tis, ok := m.sqlIndex[tableName]; ok { - for sql, v := range tis { - m.sqlList.Remove(v) - m.store.Del(sql) - } - } - m.sqlIndex[tableName] = make(map[string]*list.Element) -} - -// ClearIds clears all sql-ids mapping on table tableName from cache -func (m *LRUCacher) ClearIds(tableName string) { - m.mutex.Lock() - m.clearIds(tableName) - m.mutex.Unlock() -} - -func (m *LRUCacher) clearBeans(tableName string) { - if tis, ok := m.idIndex[tableName]; ok { - for id, v := range tis { - m.idList.Remove(v) - tid := genID(tableName, id) - m.store.Del(tid) - } - } - m.idIndex[tableName] = make(map[string]*list.Element) -} - -// ClearBeans clears all beans in some table -func (m *LRUCacher) ClearBeans(tableName string) { - m.mutex.Lock() - m.clearBeans(tableName) - m.mutex.Unlock() -} - -// PutIds pus ids into table -func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) { - m.mutex.Lock() - if _, ok := m.sqlIndex[tableName]; !ok { - m.sqlIndex[tableName] = make(map[string]*list.Element) - } - if el, ok := m.sqlIndex[tableName][sql]; !ok { - el = m.sqlList.PushBack(newSQLNode(tableName, sql)) - m.sqlIndex[tableName][sql] = el - } else { - el.Value.(*sqlNode).lastVisit = time.Now() - } - m.store.Put(sql, ids) - if m.sqlList.Len() > m.MaxElementSize { - e := m.sqlList.Front() - node := e.Value.(*sqlNode) - m.delIds(node.tbName, node.sql) - } - m.mutex.Unlock() -} - -// PutBean puts beans into table -func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) { - m.mutex.Lock() - var el *list.Element - var ok bool - - if el, ok = m.idIndex[tableName][id]; !ok { - el = m.idList.PushBack(newIDNode(tableName, id)) - m.idIndex[tableName][id] = el - } else { - el.Value.(*idNode).lastVisit = time.Now() - } - - m.store.Put(genID(tableName, id), obj) - if m.idList.Len() > m.MaxElementSize { - e := m.idList.Front() - node := e.Value.(*idNode) - m.delBean(node.tbName, node.id) - } - m.mutex.Unlock() -} - -func (m *LRUCacher) delIds(tableName, sql string) { - if _, ok := m.sqlIndex[tableName]; ok { - if el, ok := m.sqlIndex[tableName][sql]; ok { - delete(m.sqlIndex[tableName], sql) - m.sqlList.Remove(el) - } - } - m.store.Del(sql) -} - -// DelIds deletes ids -func (m *LRUCacher) DelIds(tableName, sql string) { - m.mutex.Lock() - m.delIds(tableName, sql) - m.mutex.Unlock() -} - -func (m *LRUCacher) delBean(tableName string, id string) { - tid := genID(tableName, id) - if el, ok := m.idIndex[tableName][id]; ok { - delete(m.idIndex[tableName], id) - m.idList.Remove(el) - m.clearIds(tableName) - } - m.store.Del(tid) -} - -// DelBean deletes beans in some table -func (m *LRUCacher) DelBean(tableName string, id string) { - m.mutex.Lock() - m.delBean(tableName, id) - m.mutex.Unlock() -} - -type idNode struct { - tbName string - id string - lastVisit time.Time -} - -type sqlNode struct { - tbName string - sql string - lastVisit time.Time -} - -func genSQLKey(sql string, args interface{}) string { - return fmt.Sprintf("%v-%v", sql, args) -} - -func genID(prefix string, id string) string { - return fmt.Sprintf("%v-%v", prefix, id) -} - -func newIDNode(tbName string, id string) *idNode { - return &idNode{tbName, id, time.Now()} -} - -func newSQLNode(tbName, sql string) *sqlNode { - return &sqlNode{tbName, sql, time.Now()} -} diff --git a/vendor/github.com/go-xorm/xorm/cache_memory_store.go b/vendor/github.com/go-xorm/xorm/cache_memory_store.go deleted file mode 100644 index 0c483f4583..0000000000 --- a/vendor/github.com/go-xorm/xorm/cache_memory_store.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "sync" - - "xorm.io/core" -) - -var _ core.CacheStore = NewMemoryStore() - -// MemoryStore represents in-memory store -type MemoryStore struct { - store map[interface{}]interface{} - mutex sync.RWMutex -} - -// NewMemoryStore creates a new store in memory -func NewMemoryStore() *MemoryStore { - return &MemoryStore{store: make(map[interface{}]interface{})} -} - -// Put puts object into store -func (s *MemoryStore) Put(key string, value interface{}) error { - s.mutex.Lock() - defer s.mutex.Unlock() - s.store[key] = value - return nil -} - -// Get gets object from store -func (s *MemoryStore) Get(key string) (interface{}, error) { - s.mutex.RLock() - defer s.mutex.RUnlock() - if v, ok := s.store[key]; ok { - return v, nil - } - - return nil, ErrNotExist -} - -// Del deletes object -func (s *MemoryStore) Del(key string) error { - s.mutex.Lock() - defer s.mutex.Unlock() - delete(s.store, key) - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/context_cache.go b/vendor/github.com/go-xorm/xorm/context_cache.go deleted file mode 100644 index 1bc2288496..0000000000 --- a/vendor/github.com/go-xorm/xorm/context_cache.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2018 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -// ContextCache is the interface that operates the cache data. -type ContextCache interface { - // Put puts value into cache with key. - Put(key string, val interface{}) - // Get gets cached value by given key. - Get(key string) interface{} -} - -type memoryContextCache map[string]interface{} - -// NewMemoryContextCache return memoryContextCache -func NewMemoryContextCache() memoryContextCache { - return make(map[string]interface{}) -} - -// Put puts value into cache with key. -func (m memoryContextCache) Put(key string, val interface{}) { - m[key] = val -} - -// Get gets cached value by given key. -func (m memoryContextCache) Get(key string) interface{} { - return m[key] -} diff --git a/vendor/github.com/go-xorm/xorm/convert.go b/vendor/github.com/go-xorm/xorm/convert.go deleted file mode 100644 index 2316ca0b4d..0000000000 --- a/vendor/github.com/go-xorm/xorm/convert.go +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql/driver" - "errors" - "fmt" - "reflect" - "strconv" - "time" -) - -var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error - -func strconvErr(err error) error { - if ne, ok := err.(*strconv.NumError); ok { - return ne.Err - } - return err -} - -func cloneBytes(b []byte) []byte { - if b == nil { - return nil - } else { - c := make([]byte, len(b)) - copy(c, b) - return c - } -} - -func asString(src interface{}) string { - switch v := src.(type) { - case string: - return v - case []byte: - return string(v) - } - rv := reflect.ValueOf(src) - switch rv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.FormatInt(rv.Int(), 10) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return strconv.FormatUint(rv.Uint(), 10) - case reflect.Float64: - return strconv.FormatFloat(rv.Float(), 'g', -1, 64) - case reflect.Float32: - return strconv.FormatFloat(rv.Float(), 'g', -1, 32) - case reflect.Bool: - return strconv.FormatBool(rv.Bool()) - } - return fmt.Sprintf("%v", src) -} - -func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { - switch rv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.AppendInt(buf, rv.Int(), 10), true - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return strconv.AppendUint(buf, rv.Uint(), 10), true - case reflect.Float32: - return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true - case reflect.Float64: - return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true - case reflect.Bool: - return strconv.AppendBool(buf, rv.Bool()), true - case reflect.String: - s := rv.String() - return append(buf, s...), true - } - return -} - -// convertAssign copies to dest the value in src, converting it if possible. -// An error is returned if the copy would result in loss of information. -// dest should be a pointer type. -func convertAssign(dest, src interface{}) error { - // Common cases, without reflect. - switch s := src.(type) { - case string: - switch d := dest.(type) { - case *string: - if d == nil { - return errNilPtr - } - *d = s - return nil - case *[]byte: - if d == nil { - return errNilPtr - } - *d = []byte(s) - return nil - } - case []byte: - switch d := dest.(type) { - case *string: - if d == nil { - return errNilPtr - } - *d = string(s) - return nil - case *interface{}: - if d == nil { - return errNilPtr - } - *d = cloneBytes(s) - return nil - case *[]byte: - if d == nil { - return errNilPtr - } - *d = cloneBytes(s) - return nil - } - - case time.Time: - switch d := dest.(type) { - case *string: - *d = s.Format(time.RFC3339Nano) - return nil - case *[]byte: - if d == nil { - return errNilPtr - } - *d = []byte(s.Format(time.RFC3339Nano)) - return nil - } - case nil: - switch d := dest.(type) { - case *interface{}: - if d == nil { - return errNilPtr - } - *d = nil - return nil - case *[]byte: - if d == nil { - return errNilPtr - } - *d = nil - return nil - } - } - - var sv reflect.Value - - switch d := dest.(type) { - case *string: - sv = reflect.ValueOf(src) - switch sv.Kind() { - case reflect.Bool, - reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, - reflect.Float32, reflect.Float64: - *d = asString(src) - return nil - } - case *[]byte: - sv = reflect.ValueOf(src) - if b, ok := asBytes(nil, sv); ok { - *d = b - return nil - } - case *bool: - bv, err := driver.Bool.ConvertValue(src) - if err == nil { - *d = bv.(bool) - } - return err - case *interface{}: - *d = src - return nil - } - - dpv := reflect.ValueOf(dest) - if dpv.Kind() != reflect.Ptr { - return errors.New("destination not a pointer") - } - if dpv.IsNil() { - return errNilPtr - } - - if !sv.IsValid() { - sv = reflect.ValueOf(src) - } - - dv := reflect.Indirect(dpv) - if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { - switch b := src.(type) { - case []byte: - dv.Set(reflect.ValueOf(cloneBytes(b))) - default: - dv.Set(sv) - } - return nil - } - - if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { - dv.Set(sv.Convert(dv.Type())) - return nil - } - - switch dv.Kind() { - case reflect.Ptr: - if src == nil { - dv.Set(reflect.Zero(dv.Type())) - return nil - } - - dv.Set(reflect.New(dv.Type().Elem())) - return convertAssign(dv.Interface(), src) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - s := asString(src) - i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) - if err != nil { - err = strconvErr(err) - return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) - } - dv.SetInt(i64) - return nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - s := asString(src) - u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) - if err != nil { - err = strconvErr(err) - return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) - } - dv.SetUint(u64) - return nil - case reflect.Float32, reflect.Float64: - s := asString(src) - f64, err := strconv.ParseFloat(s, dv.Type().Bits()) - if err != nil { - err = strconvErr(err) - return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) - } - dv.SetFloat(f64) - return nil - case reflect.String: - dv.SetString(asString(src)) - return nil - } - - return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) -} - -func asKind(vv reflect.Value, tp reflect.Type) (interface{}, error) { - switch tp.Kind() { - case reflect.Int64: - return vv.Int(), nil - case reflect.Int: - return int(vv.Int()), nil - case reflect.Int32: - return int32(vv.Int()), nil - case reflect.Int16: - return int16(vv.Int()), nil - case reflect.Int8: - return int8(vv.Int()), nil - case reflect.Uint64: - return vv.Uint(), nil - case reflect.Uint: - return uint(vv.Uint()), nil - case reflect.Uint32: - return uint32(vv.Uint()), nil - case reflect.Uint16: - return uint16(vv.Uint()), nil - case reflect.Uint8: - return uint8(vv.Uint()), nil - case reflect.String: - return vv.String(), nil - case reflect.Slice: - if tp.Elem().Kind() == reflect.Uint8 { - v, err := strconv.ParseInt(string(vv.Interface().([]byte)), 10, 64) - if err != nil { - return nil, err - } - return v, nil - } - - } - return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv) -} - -func convertFloat(v interface{}) (float64, error) { - switch v.(type) { - case float32: - return float64(v.(float32)), nil - case float64: - return v.(float64), nil - case string: - i, err := strconv.ParseFloat(v.(string), 64) - if err != nil { - return 0, err - } - return i, nil - case []byte: - i, err := strconv.ParseFloat(string(v.([]byte)), 64) - if err != nil { - return 0, err - } - return i, nil - } - return 0, fmt.Errorf("unsupported type: %v", v) -} - -func convertInt(v interface{}) (int64, error) { - switch v.(type) { - case int: - return int64(v.(int)), nil - case int8: - return int64(v.(int8)), nil - case int16: - return int64(v.(int16)), nil - case int32: - return int64(v.(int32)), nil - case int64: - return v.(int64), nil - case []byte: - i, err := strconv.ParseInt(string(v.([]byte)), 10, 64) - if err != nil { - return 0, err - } - return i, nil - case string: - i, err := strconv.ParseInt(v.(string), 10, 64) - if err != nil { - return 0, err - } - return i, nil - } - return 0, fmt.Errorf("unsupported type: %v", v) -} - -func asBool(bs []byte) (bool, error) { - if len(bs) == 0 { - return false, nil - } - if bs[0] == 0x00 { - return false, nil - } else if bs[0] == 0x01 { - return true, nil - } - return strconv.ParseBool(string(bs)) -} diff --git a/vendor/github.com/go-xorm/xorm/dialect_mssql.go b/vendor/github.com/go-xorm/xorm/dialect_mssql.go deleted file mode 100644 index 29070da2fb..0000000000 --- a/vendor/github.com/go-xorm/xorm/dialect_mssql.go +++ /dev/null @@ -1,567 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "net/url" - "strconv" - "strings" - - "xorm.io/core" -) - -var ( - mssqlReservedWords = map[string]bool{ - "ADD": true, - "EXTERNAL": true, - "PROCEDURE": true, - "ALL": true, - "FETCH": true, - "PUBLIC": true, - "ALTER": true, - "FILE": true, - "RAISERROR": true, - "AND": true, - "FILLFACTOR": true, - "READ": true, - "ANY": true, - "FOR": true, - "READTEXT": true, - "AS": true, - "FOREIGN": true, - "RECONFIGURE": true, - "ASC": true, - "FREETEXT": true, - "REFERENCES": true, - "AUTHORIZATION": true, - "FREETEXTTABLE": true, - "REPLICATION": true, - "BACKUP": true, - "FROM": true, - "RESTORE": true, - "BEGIN": true, - "FULL": true, - "RESTRICT": true, - "BETWEEN": true, - "FUNCTION": true, - "RETURN": true, - "BREAK": true, - "GOTO": true, - "REVERT": true, - "BROWSE": true, - "GRANT": true, - "REVOKE": true, - "BULK": true, - "GROUP": true, - "RIGHT": true, - "BY": true, - "HAVING": true, - "ROLLBACK": true, - "CASCADE": true, - "HOLDLOCK": true, - "ROWCOUNT": true, - "CASE": true, - "IDENTITY": true, - "ROWGUIDCOL": true, - "CHECK": true, - "IDENTITY_INSERT": true, - "RULE": true, - "CHECKPOINT": true, - "IDENTITYCOL": true, - "SAVE": true, - "CLOSE": true, - "IF": true, - "SCHEMA": true, - "CLUSTERED": true, - "IN": true, - "SECURITYAUDIT": true, - "COALESCE": true, - "INDEX": true, - "SELECT": true, - "COLLATE": true, - "INNER": true, - "SEMANTICKEYPHRASETABLE": true, - "COLUMN": true, - "INSERT": true, - "SEMANTICSIMILARITYDETAILSTABLE": true, - "COMMIT": true, - "INTERSECT": true, - "SEMANTICSIMILARITYTABLE": true, - "COMPUTE": true, - "INTO": true, - "SESSION_USER": true, - "CONSTRAINT": true, - "IS": true, - "SET": true, - "CONTAINS": true, - "JOIN": true, - "SETUSER": true, - "CONTAINSTABLE": true, - "KEY": true, - "SHUTDOWN": true, - "CONTINUE": true, - "KILL": true, - "SOME": true, - "CONVERT": true, - "LEFT": true, - "STATISTICS": true, - "CREATE": true, - "LIKE": true, - "SYSTEM_USER": true, - "CROSS": true, - "LINENO": true, - "TABLE": true, - "CURRENT": true, - "LOAD": true, - "TABLESAMPLE": true, - "CURRENT_DATE": true, - "MERGE": true, - "TEXTSIZE": true, - "CURRENT_TIME": true, - "NATIONAL": true, - "THEN": true, - "CURRENT_TIMESTAMP": true, - "NOCHECK": true, - "TO": true, - "CURRENT_USER": true, - "NONCLUSTERED": true, - "TOP": true, - "CURSOR": true, - "NOT": true, - "TRAN": true, - "DATABASE": true, - "NULL": true, - "TRANSACTION": true, - "DBCC": true, - "NULLIF": true, - "TRIGGER": true, - "DEALLOCATE": true, - "OF": true, - "TRUNCATE": true, - "DECLARE": true, - "OFF": true, - "TRY_CONVERT": true, - "DEFAULT": true, - "OFFSETS": true, - "TSEQUAL": true, - "DELETE": true, - "ON": true, - "UNION": true, - "DENY": true, - "OPEN": true, - "UNIQUE": true, - "DESC": true, - "OPENDATASOURCE": true, - "UNPIVOT": true, - "DISK": true, - "OPENQUERY": true, - "UPDATE": true, - "DISTINCT": true, - "OPENROWSET": true, - "UPDATETEXT": true, - "DISTRIBUTED": true, - "OPENXML": true, - "USE": true, - "DOUBLE": true, - "OPTION": true, - "USER": true, - "DROP": true, - "OR": true, - "VALUES": true, - "DUMP": true, - "ORDER": true, - "VARYING": true, - "ELSE": true, - "OUTER": true, - "VIEW": true, - "END": true, - "OVER": true, - "WAITFOR": true, - "ERRLVL": true, - "PERCENT": true, - "WHEN": true, - "ESCAPE": true, - "PIVOT": true, - "WHERE": true, - "EXCEPT": true, - "PLAN": true, - "WHILE": true, - "EXEC": true, - "PRECISION": true, - "WITH": true, - "EXECUTE": true, - "PRIMARY": true, - "WITHIN": true, - "EXISTS": true, - "PRINT": true, - "WRITETEXT": true, - "EXIT": true, - "PROC": true, - } -) - -type mssql struct { - core.Base -} - -func (db *mssql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { - return db.Base.Init(d, db, uri, drivername, dataSourceName) -} - -func (db *mssql) SqlType(c *core.Column) string { - var res string - switch t := c.SQLType.Name; t { - case core.Bool: - res = core.Bit - if strings.EqualFold(c.Default, "true") { - c.Default = "1" - } else if strings.EqualFold(c.Default, "false") { - c.Default = "0" - } - case core.Serial: - c.IsAutoIncrement = true - c.IsPrimaryKey = true - c.Nullable = false - res = core.Int - case core.BigSerial: - c.IsAutoIncrement = true - c.IsPrimaryKey = true - c.Nullable = false - res = core.BigInt - case core.Bytea, core.Blob, core.Binary, core.TinyBlob, core.MediumBlob, core.LongBlob: - res = core.VarBinary - if c.Length == 0 { - c.Length = 50 - } - case core.TimeStamp: - res = core.DateTime - case core.TimeStampz: - res = "DATETIMEOFFSET" - c.Length = 7 - case core.MediumInt: - res = core.Int - case core.Text, core.MediumText, core.TinyText, core.LongText, core.Json: - res = core.Varchar + "(MAX)" - case core.Double: - res = core.Real - case core.Uuid: - res = core.Varchar - c.Length = 40 - case core.TinyInt: - res = core.TinyInt - c.Length = 0 - case core.BigInt: - res = core.BigInt - c.Length = 0 - default: - res = t - } - - if res == core.Int { - return core.Int - } - - hasLen1 := (c.Length > 0) - hasLen2 := (c.Length2 > 0) - - if hasLen2 { - res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" - } else if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } - return res -} - -func (db *mssql) SupportInsertMany() bool { - return true -} - -func (db *mssql) IsReserved(name string) bool { - _, ok := mssqlReservedWords[name] - return ok -} - -func (db *mssql) Quote(name string) string { - return "\"" + name + "\"" -} - -func (db *mssql) SupportEngine() bool { - return false -} - -func (db *mssql) AutoIncrStr() string { - return "IDENTITY" -} - -func (db *mssql) DropTableSql(tableName string) string { - return fmt.Sprintf("IF EXISTS (SELECT * FROM sysobjects WHERE id = "+ - "object_id(N'%s') and OBJECTPROPERTY(id, N'IsUserTable') = 1) "+ - "DROP TABLE \"%s\"", tableName, tableName) -} - -func (db *mssql) SupportCharset() bool { - return false -} - -func (db *mssql) IndexOnTable() bool { - return true -} - -func (db *mssql) IndexCheckSql(tableName, idxName string) (string, []interface{}) { - args := []interface{}{idxName} - sql := "select name from sysindexes where id=object_id('" + tableName + "') and name=?" - return sql, args -} - -/*func (db *mssql) ColumnCheckSql(tableName, colName string) (string, []interface{}) { - args := []interface{}{tableName, colName} - sql := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?` - return sql, args -}*/ - -func (db *mssql) IsColumnExist(tableName, colName string) (bool, error) { - query := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?` - - return db.HasRecords(query, tableName, colName) -} - -func (db *mssql) TableCheckSql(tableName string) (string, []interface{}) { - args := []interface{}{} - sql := "select * from sysobjects where id = object_id(N'" + tableName + "') and OBJECTPROPERTY(id, N'IsUserTable') = 1" - return sql, args -} - -func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { - args := []interface{}{} - s := `select a.name as name, b.name as ctype,a.max_length,a.precision,a.scale,a.is_nullable as nullable, - "default_is_null" = (CASE WHEN c.text is null THEN 1 ELSE 0 END), - replace(replace(isnull(c.text,''),'(',''),')','') as vdefault, - ISNULL(i.is_primary_key, 0), a.is_identity as is_identity - from sys.columns a - left join sys.types b on a.user_type_id=b.user_type_id - left join sys.syscomments c on a.default_object_id=c.id - LEFT OUTER JOIN - sys.index_columns ic ON ic.object_id = a.object_id AND ic.column_id = a.column_id - LEFT OUTER JOIN - sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id - where a.object_id=object_id('` + tableName + `')` - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, nil, err - } - defer rows.Close() - - cols := make(map[string]*core.Column) - colSeq := make([]string, 0) - for rows.Next() { - var name, ctype, vdefault string - var maxLen, precision, scale int - var nullable, isPK, defaultIsNull, isIncrement bool - err = rows.Scan(&name, &ctype, &maxLen, &precision, &scale, &nullable, &defaultIsNull, &vdefault, &isPK, &isIncrement) - if err != nil { - return nil, nil, err - } - - col := new(core.Column) - col.Indexes = make(map[string]int) - col.Name = strings.Trim(name, "` ") - col.Nullable = nullable - col.DefaultIsEmpty = defaultIsNull - if !defaultIsNull { - col.Default = vdefault - } - col.IsPrimaryKey = isPK - col.IsAutoIncrement = isIncrement - ct := strings.ToUpper(ctype) - if ct == "DECIMAL" { - col.Length = precision - col.Length2 = scale - } else { - col.Length = maxLen - } - switch ct { - case "DATETIMEOFFSET": - col.SQLType = core.SQLType{Name: core.TimeStampz, DefaultLength: 0, DefaultLength2: 0} - case "NVARCHAR": - col.SQLType = core.SQLType{Name: core.NVarchar, DefaultLength: 0, DefaultLength2: 0} - case "IMAGE": - col.SQLType = core.SQLType{Name: core.VarBinary, DefaultLength: 0, DefaultLength2: 0} - default: - if _, ok := core.SqlTypes[ct]; ok { - col.SQLType = core.SQLType{Name: ct, DefaultLength: 0, DefaultLength2: 0} - } else { - return nil, nil, fmt.Errorf("Unknown colType %v for %v - %v", ct, tableName, col.Name) - } - } - - cols[col.Name] = col - colSeq = append(colSeq, col.Name) - } - return colSeq, cols, nil -} - -func (db *mssql) GetTables() ([]*core.Table, error) { - args := []interface{}{} - s := `select name from sysobjects where xtype ='U'` - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - tables := make([]*core.Table, 0) - for rows.Next() { - table := core.NewEmptyTable() - var name string - err = rows.Scan(&name) - if err != nil { - return nil, err - } - table.Name = strings.Trim(name, "` ") - tables = append(tables, table) - } - return tables, nil -} - -func (db *mssql) GetIndexes(tableName string) (map[string]*core.Index, error) { - args := []interface{}{tableName} - s := `SELECT -IXS.NAME AS [INDEX_NAME], -C.NAME AS [COLUMN_NAME], -IXS.is_unique AS [IS_UNIQUE] -FROM SYS.INDEXES IXS -INNER JOIN SYS.INDEX_COLUMNS IXCS -ON IXS.OBJECT_ID=IXCS.OBJECT_ID AND IXS.INDEX_ID = IXCS.INDEX_ID -INNER JOIN SYS.COLUMNS C ON IXS.OBJECT_ID=C.OBJECT_ID -AND IXCS.COLUMN_ID=C.COLUMN_ID -WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =? -` - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - indexes := make(map[string]*core.Index, 0) - for rows.Next() { - var indexType int - var indexName, colName, isUnique string - - err = rows.Scan(&indexName, &colName, &isUnique) - if err != nil { - return nil, err - } - - i, err := strconv.ParseBool(isUnique) - if err != nil { - return nil, err - } - - if i { - indexType = core.UniqueType - } else { - indexType = core.IndexType - } - - colName = strings.Trim(colName, "` ") - var isRegular bool - if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { - indexName = indexName[5+len(tableName):] - isRegular = true - } - - var index *core.Index - var ok bool - if index, ok = indexes[indexName]; !ok { - index = new(core.Index) - index.Type = indexType - index.Name = indexName - index.IsRegular = isRegular - indexes[indexName] = index - } - index.AddColumn(colName) - } - return indexes, nil -} - -func (db *mssql) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string { - var sql string - if tableName == "" { - tableName = table.Name - } - - sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE " - - sql += db.Quote(tableName) + " (" - - pkList := table.PrimaryKeys - - for _, colName := range table.ColumnsSeq() { - col := table.GetColumn(colName) - if col.IsPrimaryKey && len(pkList) == 1 { - sql += col.String(db) - } else { - sql += col.StringNoPk(db) - } - sql = strings.TrimSpace(sql) - sql += ", " - } - - if len(pkList) > 1 { - sql += "PRIMARY KEY ( " - sql += strings.Join(pkList, ",") - sql += " ), " - } - - sql = sql[:len(sql)-2] + ")" - sql += ";" - return sql -} - -func (db *mssql) ForUpdateSql(query string) string { - return query -} - -func (db *mssql) Filters() []core.Filter { - return []core.Filter{&core.IdFilter{}, &core.QuoteFilter{}} -} - -type odbcDriver struct { -} - -func (p *odbcDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { - var dbName string - - if strings.HasPrefix(dataSourceName, "sqlserver://") { - u, err := url.Parse(dataSourceName) - if err != nil { - return nil, err - } - dbName = u.Query().Get("database") - } else { - kv := strings.Split(dataSourceName, ";") - for _, c := range kv { - vv := strings.Split(strings.TrimSpace(c), "=") - if len(vv) == 2 { - switch strings.ToLower(vv[0]) { - case "database": - dbName = vv[1] - } - } - } - } - if dbName == "" { - return nil, errors.New("no db name provided") - } - return &core.Uri{DbName: dbName, DbType: core.MSSQL}, nil -} diff --git a/vendor/github.com/go-xorm/xorm/dialect_mysql.go b/vendor/github.com/go-xorm/xorm/dialect_mysql.go deleted file mode 100644 index cf1dbb6f21..0000000000 --- a/vendor/github.com/go-xorm/xorm/dialect_mysql.go +++ /dev/null @@ -1,654 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "crypto/tls" - "errors" - "fmt" - "regexp" - "strconv" - "strings" - "time" - - "xorm.io/core" -) - -var ( - mysqlReservedWords = map[string]bool{ - "ADD": true, - "ALL": true, - "ALTER": true, - "ANALYZE": true, - "AND": true, - "AS": true, - "ASC": true, - "ASENSITIVE": true, - "BEFORE": true, - "BETWEEN": true, - "BIGINT": true, - "BINARY": true, - "BLOB": true, - "BOTH": true, - "BY": true, - "CALL": true, - "CASCADE": true, - "CASE": true, - "CHANGE": true, - "CHAR": true, - "CHARACTER": true, - "CHECK": true, - "COLLATE": true, - "COLUMN": true, - "CONDITION": true, - "CONNECTION": true, - "CONSTRAINT": true, - "CONTINUE": true, - "CONVERT": true, - "CREATE": true, - "CROSS": true, - "CURRENT_DATE": true, - "CURRENT_TIME": true, - "CURRENT_TIMESTAMP": true, - "CURRENT_USER": true, - "CURSOR": true, - "DATABASE": true, - "DATABASES": true, - "DAY_HOUR": true, - "DAY_MICROSECOND": true, - "DAY_MINUTE": true, - "DAY_SECOND": true, - "DEC": true, - "DECIMAL": true, - "DECLARE": true, - "DEFAULT": true, - "DELAYED": true, - "DELETE": true, - "DESC": true, - "DESCRIBE": true, - "DETERMINISTIC": true, - "DISTINCT": true, - "DISTINCTROW": true, - "DIV": true, - "DOUBLE": true, - "DROP": true, - "DUAL": true, - "EACH": true, - "ELSE": true, - "ELSEIF": true, - "ENCLOSED": true, - "ESCAPED": true, - "EXISTS": true, - "EXIT": true, - "EXPLAIN": true, - "FALSE": true, - "FETCH": true, - "FLOAT": true, - "FLOAT4": true, - "FLOAT8": true, - "FOR": true, - "FORCE": true, - "FOREIGN": true, - "FROM": true, - "FULLTEXT": true, - "GOTO": true, - "GRANT": true, - "GROUP": true, - "HAVING": true, - "HIGH_PRIORITY": true, - "HOUR_MICROSECOND": true, - "HOUR_MINUTE": true, - "HOUR_SECOND": true, - "IF": true, - "IGNORE": true, - "IN": true, "INDEX": true, - "INFILE": true, "INNER": true, "INOUT": true, - "INSENSITIVE": true, "INSERT": true, "INT": true, - "INT1": true, "INT2": true, "INT3": true, - "INT4": true, "INT8": true, "INTEGER": true, - "INTERVAL": true, "INTO": true, "IS": true, - "ITERATE": true, "JOIN": true, "KEY": true, - "KEYS": true, "KILL": true, "LABEL": true, - "LEADING": true, "LEAVE": true, "LEFT": true, - "LIKE": true, "LIMIT": true, "LINEAR": true, - "LINES": true, "LOAD": true, "LOCALTIME": true, - "LOCALTIMESTAMP": true, "LOCK": true, "LONG": true, - "LONGBLOB": true, "LONGTEXT": true, "LOOP": true, - "LOW_PRIORITY": true, "MATCH": true, "MEDIUMBLOB": true, - "MEDIUMINT": true, "MEDIUMTEXT": true, "MIDDLEINT": true, - "MINUTE_MICROSECOND": true, "MINUTE_SECOND": true, "MOD": true, - "MODIFIES": true, "NATURAL": true, "NOT": true, - "NO_WRITE_TO_BINLOG": true, "NULL": true, "NUMERIC": true, - "ON OPTIMIZE": true, "OPTION": true, - "OPTIONALLY": true, "OR": true, "ORDER": true, - "OUT": true, "OUTER": true, "OUTFILE": true, - "PRECISION": true, "PRIMARY": true, "PROCEDURE": true, - "PURGE": true, "RAID0": true, "RANGE": true, - "READ": true, "READS": true, "REAL": true, - "REFERENCES": true, "REGEXP": true, "RELEASE": true, - "RENAME": true, "REPEAT": true, "REPLACE": true, - "REQUIRE": true, "RESTRICT": true, "RETURN": true, - "REVOKE": true, "RIGHT": true, "RLIKE": true, - "SCHEMA": true, "SCHEMAS": true, "SECOND_MICROSECOND": true, - "SELECT": true, "SENSITIVE": true, "SEPARATOR": true, - "SET": true, "SHOW": true, "SMALLINT": true, - "SPATIAL": true, "SPECIFIC": true, "SQL": true, - "SQLEXCEPTION": true, "SQLSTATE": true, "SQLWARNING": true, - "SQL_BIG_RESULT": true, "SQL_CALC_FOUND_ROWS": true, "SQL_SMALL_RESULT": true, - "SSL": true, "STARTING": true, "STRAIGHT_JOIN": true, - "TABLE": true, "TERMINATED": true, "THEN": true, - "TINYBLOB": true, "TINYINT": true, "TINYTEXT": true, - "TO": true, "TRAILING": true, "TRIGGER": true, - "TRUE": true, "UNDO": true, "UNION": true, - "UNIQUE": true, "UNLOCK": true, "UNSIGNED": true, - "UPDATE": true, "USAGE": true, "USE": true, - "USING": true, "UTC_DATE": true, "UTC_TIME": true, - "UTC_TIMESTAMP": true, "VALUES": true, "VARBINARY": true, - "VARCHAR": true, - "VARCHARACTER": true, - "VARYING": true, - "WHEN": true, - "WHERE": true, - "WHILE": true, - "WITH": true, - "WRITE": true, - "X509": true, - "XOR": true, - "YEAR_MONTH": true, - "ZEROFILL": true, - } -) - -type mysql struct { - core.Base - net string - addr string - params map[string]string - loc *time.Location - timeout time.Duration - tls *tls.Config - allowAllFiles bool - allowOldPasswords bool - clientFoundRows bool - rowFormat string -} - -func (db *mysql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { - return db.Base.Init(d, db, uri, drivername, dataSourceName) -} - -func (db *mysql) SetParams(params map[string]string) { - rowFormat, ok := params["rowFormat"] - if ok { - var t = strings.ToUpper(rowFormat) - switch t { - case "COMPACT": - fallthrough - case "REDUNDANT": - fallthrough - case "DYNAMIC": - fallthrough - case "COMPRESSED": - db.rowFormat = t - break - default: - break - } - } -} - -func (db *mysql) SqlType(c *core.Column) string { - var res string - switch t := c.SQLType.Name; t { - case core.Bool: - res = core.TinyInt - c.Length = 1 - case core.Serial: - c.IsAutoIncrement = true - c.IsPrimaryKey = true - c.Nullable = false - res = core.Int - case core.BigSerial: - c.IsAutoIncrement = true - c.IsPrimaryKey = true - c.Nullable = false - res = core.BigInt - case core.Bytea: - res = core.Blob - case core.TimeStampz: - res = core.Char - c.Length = 64 - case core.Enum: // mysql enum - res = core.Enum - res += "(" - opts := "" - for v := range c.EnumOptions { - opts += fmt.Sprintf(",'%v'", v) - } - res += strings.TrimLeft(opts, ",") - res += ")" - case core.Set: // mysql set - res = core.Set - res += "(" - opts := "" - for v := range c.SetOptions { - opts += fmt.Sprintf(",'%v'", v) - } - res += strings.TrimLeft(opts, ",") - res += ")" - case core.NVarchar: - res = core.Varchar - case core.Uuid: - res = core.Varchar - c.Length = 40 - case core.Json: - res = core.Text - default: - res = t - } - - hasLen1 := (c.Length > 0) - hasLen2 := (c.Length2 > 0) - - if res == core.BigInt && !hasLen1 && !hasLen2 { - c.Length = 20 - hasLen1 = true - } - - if hasLen2 { - res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" - } else if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } - return res -} - -func (db *mysql) SupportInsertMany() bool { - return true -} - -func (db *mysql) IsReserved(name string) bool { - _, ok := mysqlReservedWords[name] - return ok -} - -func (db *mysql) Quote(name string) string { - return "`" + name + "`" -} - -func (db *mysql) SupportEngine() bool { - return true -} - -func (db *mysql) AutoIncrStr() string { - return "AUTO_INCREMENT" -} - -func (db *mysql) SupportCharset() bool { - return true -} - -func (db *mysql) IndexOnTable() bool { - return true -} - -func (db *mysql) IndexCheckSql(tableName, idxName string) (string, []interface{}) { - args := []interface{}{db.DbName, tableName, idxName} - sql := "SELECT `INDEX_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS`" - sql += " WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `INDEX_NAME`=?" - return sql, args -} - -/*func (db *mysql) ColumnCheckSql(tableName, colName string) (string, []interface{}) { - args := []interface{}{db.DbName, tableName, colName} - sql := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?" - return sql, args -}*/ - -func (db *mysql) TableCheckSql(tableName string) (string, []interface{}) { - args := []interface{}{db.DbName, tableName} - sql := "SELECT `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? and `TABLE_NAME`=?" - return sql, args -} - -func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { - args := []interface{}{db.DbName, tableName} - s := "SELECT `COLUMN_NAME`, `IS_NULLABLE`, `COLUMN_DEFAULT`, `COLUMN_TYPE`," + - " `COLUMN_KEY`, `EXTRA`,`COLUMN_COMMENT` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, nil, err - } - defer rows.Close() - - cols := make(map[string]*core.Column) - colSeq := make([]string, 0) - for rows.Next() { - col := new(core.Column) - col.Indexes = make(map[string]int) - - var columnName, isNullable, colType, colKey, extra, comment string - var colDefault *string - err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment) - if err != nil { - return nil, nil, err - } - col.Name = strings.Trim(columnName, "` ") - col.Comment = comment - if "YES" == isNullable { - col.Nullable = true - } - - if colDefault != nil { - col.Default = *colDefault - col.DefaultIsEmpty = false - } else { - col.DefaultIsEmpty = true - } - - cts := strings.Split(colType, "(") - colName := cts[0] - colType = strings.ToUpper(colName) - var len1, len2 int - if len(cts) == 2 { - idx := strings.Index(cts[1], ")") - if colType == core.Enum && cts[1][0] == '\'' { // enum - options := strings.Split(cts[1][0:idx], ",") - col.EnumOptions = make(map[string]int) - for k, v := range options { - v = strings.TrimSpace(v) - v = strings.Trim(v, "'") - col.EnumOptions[v] = k - } - } else if colType == core.Set && cts[1][0] == '\'' { - options := strings.Split(cts[1][0:idx], ",") - col.SetOptions = make(map[string]int) - for k, v := range options { - v = strings.TrimSpace(v) - v = strings.Trim(v, "'") - col.SetOptions[v] = k - } - } else { - lens := strings.Split(cts[1][0:idx], ",") - len1, err = strconv.Atoi(strings.TrimSpace(lens[0])) - if err != nil { - return nil, nil, err - } - if len(lens) == 2 { - len2, err = strconv.Atoi(lens[1]) - if err != nil { - return nil, nil, err - } - } - } - } - if colType == "FLOAT UNSIGNED" { - colType = "FLOAT" - } - if colType == "DOUBLE UNSIGNED" { - colType = "DOUBLE" - } - col.Length = len1 - col.Length2 = len2 - if _, ok := core.SqlTypes[colType]; ok { - col.SQLType = core.SQLType{Name: colType, DefaultLength: len1, DefaultLength2: len2} - } else { - return nil, nil, fmt.Errorf("Unknown colType %v", colType) - } - - if colKey == "PRI" { - col.IsPrimaryKey = true - } - if colKey == "UNI" { - // col.is - } - - if extra == "auto_increment" { - col.IsAutoIncrement = true - } - - if !col.DefaultIsEmpty { - if col.SQLType.IsText() { - col.Default = "'" + col.Default + "'" - } else if col.SQLType.IsTime() && col.Default != "CURRENT_TIMESTAMP" { - col.Default = "'" + col.Default + "'" - } - } - cols[col.Name] = col - colSeq = append(colSeq, col.Name) - } - return colSeq, cols, nil -} - -func (db *mysql) GetTables() ([]*core.Table, error) { - args := []interface{}{db.DbName} - s := "SELECT `TABLE_NAME`, `ENGINE`, `TABLE_ROWS`, `AUTO_INCREMENT`, `TABLE_COMMENT` from " + - "`INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? AND (`ENGINE`='MyISAM' OR `ENGINE` = 'InnoDB' OR `ENGINE` = 'TokuDB')" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - tables := make([]*core.Table, 0) - for rows.Next() { - table := core.NewEmptyTable() - var name, engine, tableRows, comment string - var autoIncr *string - err = rows.Scan(&name, &engine, &tableRows, &autoIncr, &comment) - if err != nil { - return nil, err - } - - table.Name = name - table.Comment = comment - table.StoreEngine = engine - tables = append(tables, table) - } - return tables, nil -} - -func (db *mysql) GetIndexes(tableName string) (map[string]*core.Index, error) { - args := []interface{}{db.DbName, tableName} - s := "SELECT `INDEX_NAME`, `NON_UNIQUE`, `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - indexes := make(map[string]*core.Index, 0) - for rows.Next() { - var indexType int - var indexName, colName, nonUnique string - err = rows.Scan(&indexName, &nonUnique, &colName) - if err != nil { - return nil, err - } - - if indexName == "PRIMARY" { - continue - } - - if "YES" == nonUnique || nonUnique == "1" { - indexType = core.IndexType - } else { - indexType = core.UniqueType - } - - colName = strings.Trim(colName, "` ") - var isRegular bool - if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { - indexName = indexName[5+len(tableName):] - isRegular = true - } - - var index *core.Index - var ok bool - if index, ok = indexes[indexName]; !ok { - index = new(core.Index) - index.IsRegular = isRegular - index.Type = indexType - index.Name = indexName - indexes[indexName] = index - } - index.AddColumn(colName) - } - return indexes, nil -} - -func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string { - var sql string - sql = "CREATE TABLE IF NOT EXISTS " - if tableName == "" { - tableName = table.Name - } - - sql += db.Quote(tableName) - sql += " (" - - if len(table.ColumnsSeq()) > 0 { - pkList := table.PrimaryKeys - - for _, colName := range table.ColumnsSeq() { - col := table.GetColumn(colName) - if col.IsPrimaryKey && len(pkList) == 1 { - sql += col.String(db) - } else { - sql += col.StringNoPk(db) - } - sql = strings.TrimSpace(sql) - if len(col.Comment) > 0 { - sql += " COMMENT '" + col.Comment + "'" - } - sql += ", " - } - - if len(pkList) > 1 { - sql += "PRIMARY KEY ( " - sql += db.Quote(strings.Join(pkList, db.Quote(","))) - sql += " ), " - } - - sql = sql[:len(sql)-2] - } - sql += ")" - - if storeEngine != "" { - sql += " ENGINE=" + storeEngine - } - - if len(charset) == 0 { - charset = db.URI().Charset - } - if len(charset) != 0 { - sql += " DEFAULT CHARSET " + charset - } - - if db.rowFormat != "" { - sql += " ROW_FORMAT=" + db.rowFormat - } - return sql -} - -func (db *mysql) Filters() []core.Filter { - return []core.Filter{&core.IdFilter{}} -} - -type mymysqlDriver struct { -} - -func (p *mymysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { - db := &core.Uri{DbType: core.MYSQL} - - pd := strings.SplitN(dataSourceName, "*", 2) - if len(pd) == 2 { - // Parse protocol part of URI - p := strings.SplitN(pd[0], ":", 2) - if len(p) != 2 { - return nil, errors.New("Wrong protocol part of URI") - } - db.Proto = p[0] - options := strings.Split(p[1], ",") - db.Raddr = options[0] - for _, o := range options[1:] { - kv := strings.SplitN(o, "=", 2) - var k, v string - if len(kv) == 2 { - k, v = kv[0], kv[1] - } else { - k, v = o, "true" - } - switch k { - case "laddr": - db.Laddr = v - case "timeout": - to, err := time.ParseDuration(v) - if err != nil { - return nil, err - } - db.Timeout = to - default: - return nil, errors.New("Unknown option: " + k) - } - } - // Remove protocol part - pd = pd[1:] - } - // Parse database part of URI - dup := strings.SplitN(pd[0], "/", 3) - if len(dup) != 3 { - return nil, errors.New("Wrong database part of URI") - } - db.DbName = dup[0] - db.User = dup[1] - db.Passwd = dup[2] - - return db, nil -} - -type mysqlDriver struct { -} - -func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { - dsnPattern := regexp.MustCompile( - `^(?:(?P.*?)(?::(?P.*))?@)?` + // [user[:password]@] - `(?:(?P[^\(]*)(?:\((?P[^\)]*)\))?)?` + // [net[(addr)]] - `\/(?P.*?)` + // /dbname - `(?:\?(?P[^\?]*))?$`) // [?param1=value1¶mN=valueN] - matches := dsnPattern.FindStringSubmatch(dataSourceName) - // tlsConfigRegister := make(map[string]*tls.Config) - names := dsnPattern.SubexpNames() - - uri := &core.Uri{DbType: core.MYSQL} - - for i, match := range matches { - switch names[i] { - case "dbname": - uri.DbName = match - case "params": - if len(match) > 0 { - kvs := strings.Split(match, "&") - for _, kv := range kvs { - splits := strings.Split(kv, "=") - if len(splits) == 2 { - switch splits[0] { - case "charset": - uri.Charset = splits[1] - } - } - } - } - - } - } - return uri, nil -} diff --git a/vendor/github.com/go-xorm/xorm/dialect_oracle.go b/vendor/github.com/go-xorm/xorm/dialect_oracle.go deleted file mode 100644 index 15010ca5a3..0000000000 --- a/vendor/github.com/go-xorm/xorm/dialect_oracle.go +++ /dev/null @@ -1,902 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "regexp" - "strconv" - "strings" - - "xorm.io/core" -) - -var ( - oracleReservedWords = map[string]bool{ - "ACCESS": true, - "ACCOUNT": true, - "ACTIVATE": true, - "ADD": true, - "ADMIN": true, - "ADVISE": true, - "AFTER": true, - "ALL": true, - "ALL_ROWS": true, - "ALLOCATE": true, - "ALTER": true, - "ANALYZE": true, - "AND": true, - "ANY": true, - "ARCHIVE": true, - "ARCHIVELOG": true, - "ARRAY": true, - "AS": true, - "ASC": true, - "AT": true, - "AUDIT": true, - "AUTHENTICATED": true, - "AUTHORIZATION": true, - "AUTOEXTEND": true, - "AUTOMATIC": true, - "BACKUP": true, - "BECOME": true, - "BEFORE": true, - "BEGIN": true, - "BETWEEN": true, - "BFILE": true, - "BITMAP": true, - "BLOB": true, - "BLOCK": true, - "BODY": true, - "BY": true, - "CACHE": true, - "CACHE_INSTANCES": true, - "CANCEL": true, - "CASCADE": true, - "CAST": true, - "CFILE": true, - "CHAINED": true, - "CHANGE": true, - "CHAR": true, - "CHAR_CS": true, - "CHARACTER": true, - "CHECK": true, - "CHECKPOINT": true, - "CHOOSE": true, - "CHUNK": true, - "CLEAR": true, - "CLOB": true, - "CLONE": true, - "CLOSE": true, - "CLOSE_CACHED_OPEN_CURSORS": true, - "CLUSTER": true, - "COALESCE": true, - "COLUMN": true, - "COLUMNS": true, - "COMMENT": true, - "COMMIT": true, - "COMMITTED": true, - "COMPATIBILITY": true, - "COMPILE": true, - "COMPLETE": true, - "COMPOSITE_LIMIT": true, - "COMPRESS": true, - "COMPUTE": true, - "CONNECT": true, - "CONNECT_TIME": true, - "CONSTRAINT": true, - "CONSTRAINTS": true, - "CONTENTS": true, - "CONTINUE": true, - "CONTROLFILE": true, - "CONVERT": true, - "COST": true, - "CPU_PER_CALL": true, - "CPU_PER_SESSION": true, - "CREATE": true, - "CURRENT": true, - "CURRENT_SCHEMA": true, - "CURREN_USER": true, - "CURSOR": true, - "CYCLE": true, - "DANGLING": true, - "DATABASE": true, - "DATAFILE": true, - "DATAFILES": true, - "DATAOBJNO": true, - "DATE": true, - "DBA": true, - "DBHIGH": true, - "DBLOW": true, - "DBMAC": true, - "DEALLOCATE": true, - "DEBUG": true, - "DEC": true, - "DECIMAL": true, - "DECLARE": true, - "DEFAULT": true, - "DEFERRABLE": true, - "DEFERRED": true, - "DEGREE": true, - "DELETE": true, - "DEREF": true, - "DESC": true, - "DIRECTORY": true, - "DISABLE": true, - "DISCONNECT": true, - "DISMOUNT": true, - "DISTINCT": true, - "DISTRIBUTED": true, - "DML": true, - "DOUBLE": true, - "DROP": true, - "DUMP": true, - "EACH": true, - "ELSE": true, - "ENABLE": true, - "END": true, - "ENFORCE": true, - "ENTRY": true, - "ESCAPE": true, - "EXCEPT": true, - "EXCEPTIONS": true, - "EXCHANGE": true, - "EXCLUDING": true, - "EXCLUSIVE": true, - "EXECUTE": true, - "EXISTS": true, - "EXPIRE": true, - "EXPLAIN": true, - "EXTENT": true, - "EXTENTS": true, - "EXTERNALLY": true, - "FAILED_LOGIN_ATTEMPTS": true, - "FALSE": true, - "FAST": true, - "FILE": true, - "FIRST_ROWS": true, - "FLAGGER": true, - "FLOAT": true, - "FLOB": true, - "FLUSH": true, - "FOR": true, - "FORCE": true, - "FOREIGN": true, - "FREELIST": true, - "FREELISTS": true, - "FROM": true, - "FULL": true, - "FUNCTION": true, - "GLOBAL": true, - "GLOBALLY": true, - "GLOBAL_NAME": true, - "GRANT": true, - "GROUP": true, - "GROUPS": true, - "HASH": true, - "HASHKEYS": true, - "HAVING": true, - "HEADER": true, - "HEAP": true, - "IDENTIFIED": true, - "IDGENERATORS": true, - "IDLE_TIME": true, - "IF": true, - "IMMEDIATE": true, - "IN": true, - "INCLUDING": true, - "INCREMENT": true, - "INDEX": true, - "INDEXED": true, - "INDEXES": true, - "INDICATOR": true, - "IND_PARTITION": true, - "INITIAL": true, - "INITIALLY": true, - "INITRANS": true, - "INSERT": true, - "INSTANCE": true, - "INSTANCES": true, - "INSTEAD": true, - "INT": true, - "INTEGER": true, - "INTERMEDIATE": true, - "INTERSECT": true, - "INTO": true, - "IS": true, - "ISOLATION": true, - "ISOLATION_LEVEL": true, - "KEEP": true, - "KEY": true, - "KILL": true, - "LABEL": true, - "LAYER": true, - "LESS": true, - "LEVEL": true, - "LIBRARY": true, - "LIKE": true, - "LIMIT": true, - "LINK": true, - "LIST": true, - "LOB": true, - "LOCAL": true, - "LOCK": true, - "LOCKED": true, - "LOG": true, - "LOGFILE": true, - "LOGGING": true, - "LOGICAL_READS_PER_CALL": true, - "LOGICAL_READS_PER_SESSION": true, - "LONG": true, - "MANAGE": true, - "MASTER": true, - "MAX": true, - "MAXARCHLOGS": true, - "MAXDATAFILES": true, - "MAXEXTENTS": true, - "MAXINSTANCES": true, - "MAXLOGFILES": true, - "MAXLOGHISTORY": true, - "MAXLOGMEMBERS": true, - "MAXSIZE": true, - "MAXTRANS": true, - "MAXVALUE": true, - "MIN": true, - "MEMBER": true, - "MINIMUM": true, - "MINEXTENTS": true, - "MINUS": true, - "MINVALUE": true, - "MLSLABEL": true, - "MLS_LABEL_FORMAT": true, - "MODE": true, - "MODIFY": true, - "MOUNT": true, - "MOVE": true, - "MTS_DISPATCHERS": true, - "MULTISET": true, - "NATIONAL": true, - "NCHAR": true, - "NCHAR_CS": true, - "NCLOB": true, - "NEEDED": true, - "NESTED": true, - "NETWORK": true, - "NEW": true, - "NEXT": true, - "NOARCHIVELOG": true, - "NOAUDIT": true, - "NOCACHE": true, - "NOCOMPRESS": true, - "NOCYCLE": true, - "NOFORCE": true, - "NOLOGGING": true, - "NOMAXVALUE": true, - "NOMINVALUE": true, - "NONE": true, - "NOORDER": true, - "NOOVERRIDE": true, - "NOPARALLEL": true, - "NOREVERSE": true, - "NORMAL": true, - "NOSORT": true, - "NOT": true, - "NOTHING": true, - "NOWAIT": true, - "NULL": true, - "NUMBER": true, - "NUMERIC": true, - "NVARCHAR2": true, - "OBJECT": true, - "OBJNO": true, - "OBJNO_REUSE": true, - "OF": true, - "OFF": true, - "OFFLINE": true, - "OID": true, - "OIDINDEX": true, - "OLD": true, - "ON": true, - "ONLINE": true, - "ONLY": true, - "OPCODE": true, - "OPEN": true, - "OPTIMAL": true, - "OPTIMIZER_GOAL": true, - "OPTION": true, - "OR": true, - "ORDER": true, - "ORGANIZATION": true, - "OSLABEL": true, - "OVERFLOW": true, - "OWN": true, - "PACKAGE": true, - "PARALLEL": true, - "PARTITION": true, - "PASSWORD": true, - "PASSWORD_GRACE_TIME": true, - "PASSWORD_LIFE_TIME": true, - "PASSWORD_LOCK_TIME": true, - "PASSWORD_REUSE_MAX": true, - "PASSWORD_REUSE_TIME": true, - "PASSWORD_VERIFY_FUNCTION": true, - "PCTFREE": true, - "PCTINCREASE": true, - "PCTTHRESHOLD": true, - "PCTUSED": true, - "PCTVERSION": true, - "PERCENT": true, - "PERMANENT": true, - "PLAN": true, - "PLSQL_DEBUG": true, - "POST_TRANSACTION": true, - "PRECISION": true, - "PRESERVE": true, - "PRIMARY": true, - "PRIOR": true, - "PRIVATE": true, - "PRIVATE_SGA": true, - "PRIVILEGE": true, - "PRIVILEGES": true, - "PROCEDURE": true, - "PROFILE": true, - "PUBLIC": true, - "PURGE": true, - "QUEUE": true, - "QUOTA": true, - "RANGE": true, - "RAW": true, - "RBA": true, - "READ": true, - "READUP": true, - "REAL": true, - "REBUILD": true, - "RECOVER": true, - "RECOVERABLE": true, - "RECOVERY": true, - "REF": true, - "REFERENCES": true, - "REFERENCING": true, - "REFRESH": true, - "RENAME": true, - "REPLACE": true, - "RESET": true, - "RESETLOGS": true, - "RESIZE": true, - "RESOURCE": true, - "RESTRICTED": true, - "RETURN": true, - "RETURNING": true, - "REUSE": true, - "REVERSE": true, - "REVOKE": true, - "ROLE": true, - "ROLES": true, - "ROLLBACK": true, - "ROW": true, - "ROWID": true, - "ROWNUM": true, - "ROWS": true, - "RULE": true, - "SAMPLE": true, - "SAVEPOINT": true, - "SB4": true, - "SCAN_INSTANCES": true, - "SCHEMA": true, - "SCN": true, - "SCOPE": true, - "SD_ALL": true, - "SD_INHIBIT": true, - "SD_SHOW": true, - "SEGMENT": true, - "SEG_BLOCK": true, - "SEG_FILE": true, - "SELECT": true, - "SEQUENCE": true, - "SERIALIZABLE": true, - "SESSION": true, - "SESSION_CACHED_CURSORS": true, - "SESSIONS_PER_USER": true, - "SET": true, - "SHARE": true, - "SHARED": true, - "SHARED_POOL": true, - "SHRINK": true, - "SIZE": true, - "SKIP": true, - "SKIP_UNUSABLE_INDEXES": true, - "SMALLINT": true, - "SNAPSHOT": true, - "SOME": true, - "SORT": true, - "SPECIFICATION": true, - "SPLIT": true, - "SQL_TRACE": true, - "STANDBY": true, - "START": true, - "STATEMENT_ID": true, - "STATISTICS": true, - "STOP": true, - "STORAGE": true, - "STORE": true, - "STRUCTURE": true, - "SUCCESSFUL": true, - "SWITCH": true, - "SYS_OP_ENFORCE_NOT_NULL$": true, - "SYS_OP_NTCIMG$": true, - "SYNONYM": true, - "SYSDATE": true, - "SYSDBA": true, - "SYSOPER": true, - "SYSTEM": true, - "TABLE": true, - "TABLES": true, - "TABLESPACE": true, - "TABLESPACE_NO": true, - "TABNO": true, - "TEMPORARY": true, - "THAN": true, - "THE": true, - "THEN": true, - "THREAD": true, - "TIMESTAMP": true, - "TIME": true, - "TO": true, - "TOPLEVEL": true, - "TRACE": true, - "TRACING": true, - "TRANSACTION": true, - "TRANSITIONAL": true, - "TRIGGER": true, - "TRIGGERS": true, - "TRUE": true, - "TRUNCATE": true, - "TX": true, - "TYPE": true, - "UB2": true, - "UBA": true, - "UID": true, - "UNARCHIVED": true, - "UNDO": true, - "UNION": true, - "UNIQUE": true, - "UNLIMITED": true, - "UNLOCK": true, - "UNRECOVERABLE": true, - "UNTIL": true, - "UNUSABLE": true, - "UNUSED": true, - "UPDATABLE": true, - "UPDATE": true, - "USAGE": true, - "USE": true, - "USER": true, - "USING": true, - "VALIDATE": true, - "VALIDATION": true, - "VALUE": true, - "VALUES": true, - "VARCHAR": true, - "VARCHAR2": true, - "VARYING": true, - "VIEW": true, - "WHEN": true, - "WHENEVER": true, - "WHERE": true, - "WITH": true, - "WITHOUT": true, - "WORK": true, - "WRITE": true, - "WRITEDOWN": true, - "WRITEUP": true, - "XID": true, - "YEAR": true, - "ZONE": true, - } -) - -type oracle struct { - core.Base -} - -func (db *oracle) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { - return db.Base.Init(d, db, uri, drivername, dataSourceName) -} - -func (db *oracle) SqlType(c *core.Column) string { - var res string - switch t := c.SQLType.Name; t { - case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt, core.Bool, core.Serial, core.BigSerial: - res = "NUMBER" - case core.Binary, core.VarBinary, core.Blob, core.TinyBlob, core.MediumBlob, core.LongBlob, core.Bytea: - return core.Blob - case core.Time, core.DateTime, core.TimeStamp: - res = core.TimeStamp - case core.TimeStampz: - res = "TIMESTAMP WITH TIME ZONE" - case core.Float, core.Double, core.Numeric, core.Decimal: - res = "NUMBER" - case core.Text, core.MediumText, core.LongText, core.Json: - res = "CLOB" - case core.Char, core.Varchar, core.TinyText: - res = "VARCHAR2" - default: - res = t - } - - hasLen1 := (c.Length > 0) - hasLen2 := (c.Length2 > 0) - - if hasLen2 { - res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" - } else if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } - return res -} - -func (db *oracle) AutoIncrStr() string { - return "AUTO_INCREMENT" -} - -func (db *oracle) SupportInsertMany() bool { - return true -} - -func (db *oracle) IsReserved(name string) bool { - _, ok := oracleReservedWords[name] - return ok -} - -func (db *oracle) Quote(name string) string { - return "[" + name + "]" -} - -func (db *oracle) SupportEngine() bool { - return false -} - -func (db *oracle) SupportCharset() bool { - return false -} - -func (db *oracle) SupportDropIfExists() bool { - return false -} - -func (db *oracle) IndexOnTable() bool { - return false -} - -func (db *oracle) DropTableSql(tableName string) string { - return fmt.Sprintf("DROP TABLE `%s`", tableName) -} - -func (db *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string { - var sql string - sql = "CREATE TABLE " - if tableName == "" { - tableName = table.Name - } - - sql += db.Quote(tableName) + " (" - - pkList := table.PrimaryKeys - - for _, colName := range table.ColumnsSeq() { - col := table.GetColumn(colName) - /*if col.IsPrimaryKey && len(pkList) == 1 { - sql += col.String(b.dialect) - } else {*/ - sql += col.StringNoPk(db) - // } - sql = strings.TrimSpace(sql) - sql += ", " - } - - if len(pkList) > 0 { - sql += "PRIMARY KEY ( " - sql += db.Quote(strings.Join(pkList, db.Quote(","))) - sql += " ), " - } - - sql = sql[:len(sql)-2] + ")" - if db.SupportEngine() && storeEngine != "" { - sql += " ENGINE=" + storeEngine - } - if db.SupportCharset() { - if len(charset) == 0 { - charset = db.URI().Charset - } - if len(charset) > 0 { - sql += " DEFAULT CHARSET " + charset - } - } - return sql -} - -func (db *oracle) IndexCheckSql(tableName, idxName string) (string, []interface{}) { - args := []interface{}{tableName, idxName} - return `SELECT INDEX_NAME FROM USER_INDEXES ` + - `WHERE TABLE_NAME = :1 AND INDEX_NAME = :2`, args -} - -func (db *oracle) TableCheckSql(tableName string) (string, []interface{}) { - args := []interface{}{tableName} - return `SELECT table_name FROM user_tables WHERE table_name = :1`, args -} - -func (db *oracle) MustDropTable(tableName string) error { - sql, args := db.TableCheckSql(tableName) - db.LogSQL(sql, args) - - rows, err := db.DB().Query(sql, args...) - if err != nil { - return err - } - defer rows.Close() - - if !rows.Next() { - return nil - } - - sql = "Drop Table \"" + tableName + "\"" - db.LogSQL(sql, args) - - _, err = db.DB().Exec(sql) - return err -} - -/*func (db *oracle) ColumnCheckSql(tableName, colName string) (string, []interface{}) { - args := []interface{}{strings.ToUpper(tableName), strings.ToUpper(colName)} - return "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = ?" + - " AND column_name = ?", args -}*/ - -func (db *oracle) IsColumnExist(tableName, colName string) (bool, error) { - args := []interface{}{tableName, colName} - query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" + - " AND column_name = :2" - db.LogSQL(query, args) - - rows, err := db.DB().Query(query, args...) - if err != nil { - return false, err - } - defer rows.Close() - - if rows.Next() { - return true, nil - } - return false, nil -} - -func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { - args := []interface{}{tableName} - s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," + - "nullable FROM USER_TAB_COLUMNS WHERE table_name = :1" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, nil, err - } - defer rows.Close() - - cols := make(map[string]*core.Column) - colSeq := make([]string, 0) - for rows.Next() { - col := new(core.Column) - col.Indexes = make(map[string]int) - - var colName, colDefault, nullable, dataType, dataPrecision, dataScale *string - var dataLen int - - err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision, - &dataScale, &nullable) - if err != nil { - return nil, nil, err - } - - col.Name = strings.Trim(*colName, `" `) - if colDefault != nil { - col.Default = *colDefault - col.DefaultIsEmpty = false - } - - if *nullable == "Y" { - col.Nullable = true - } else { - col.Nullable = false - } - - var ignore bool - - var dt string - var len1, len2 int - dts := strings.Split(*dataType, "(") - dt = dts[0] - if len(dts) > 1 { - lens := strings.Split(dts[1][:len(dts[1])-1], ",") - if len(lens) > 1 { - len1, _ = strconv.Atoi(lens[0]) - len2, _ = strconv.Atoi(lens[1]) - } else { - len1, _ = strconv.Atoi(lens[0]) - } - } - - switch dt { - case "VARCHAR2": - col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: len1, DefaultLength2: len2} - case "NVARCHAR2": - col.SQLType = core.SQLType{Name: core.NVarchar, DefaultLength: len1, DefaultLength2: len2} - case "TIMESTAMP WITH TIME ZONE": - col.SQLType = core.SQLType{Name: core.TimeStampz, DefaultLength: 0, DefaultLength2: 0} - case "NUMBER": - col.SQLType = core.SQLType{Name: core.Double, DefaultLength: len1, DefaultLength2: len2} - case "LONG", "LONG RAW": - col.SQLType = core.SQLType{Name: core.Text, DefaultLength: 0, DefaultLength2: 0} - case "RAW": - col.SQLType = core.SQLType{Name: core.Binary, DefaultLength: 0, DefaultLength2: 0} - case "ROWID": - col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: 18, DefaultLength2: 0} - case "AQ$_SUBSCRIBERS": - ignore = true - default: - col.SQLType = core.SQLType{Name: strings.ToUpper(dt), DefaultLength: len1, DefaultLength2: len2} - } - - if ignore { - continue - } - - if _, ok := core.SqlTypes[col.SQLType.Name]; !ok { - return nil, nil, fmt.Errorf("Unknown colType %v %v", *dataType, col.SQLType) - } - - col.Length = dataLen - - if col.SQLType.IsText() || col.SQLType.IsTime() { - if !col.DefaultIsEmpty { - col.Default = "'" + col.Default + "'" - } - } - cols[col.Name] = col - colSeq = append(colSeq, col.Name) - } - - return colSeq, cols, nil -} - -func (db *oracle) GetTables() ([]*core.Table, error) { - args := []interface{}{} - s := "SELECT table_name FROM user_tables" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - tables := make([]*core.Table, 0) - for rows.Next() { - table := core.NewEmptyTable() - err = rows.Scan(&table.Name) - if err != nil { - return nil, err - } - - tables = append(tables, table) - } - return tables, nil -} - -func (db *oracle) GetIndexes(tableName string) (map[string]*core.Index, error) { - args := []interface{}{tableName} - s := "SELECT t.column_name,i.uniqueness,i.index_name FROM user_ind_columns t,user_indexes i " + - "WHERE t.index_name = i.index_name and t.table_name = i.table_name and t.table_name =:1" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - indexes := make(map[string]*core.Index, 0) - for rows.Next() { - var indexType int - var indexName, colName, uniqueness string - - err = rows.Scan(&colName, &uniqueness, &indexName) - if err != nil { - return nil, err - } - - indexName = strings.Trim(indexName, `" `) - - var isRegular bool - if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { - indexName = indexName[5+len(tableName):] - isRegular = true - } - - if uniqueness == "UNIQUE" { - indexType = core.UniqueType - } else { - indexType = core.IndexType - } - - var index *core.Index - var ok bool - if index, ok = indexes[indexName]; !ok { - index = new(core.Index) - index.Type = indexType - index.Name = indexName - index.IsRegular = isRegular - indexes[indexName] = index - } - index.AddColumn(colName) - } - return indexes, nil -} - -func (db *oracle) Filters() []core.Filter { - return []core.Filter{&core.QuoteFilter{}, &core.SeqFilter{Prefix: ":", Start: 1}, &core.IdFilter{}} -} - -type goracleDriver struct { -} - -func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { - db := &core.Uri{DbType: core.ORACLE} - dsnPattern := regexp.MustCompile( - `^(?:(?P.*?)(?::(?P.*))?@)?` + // [user[:password]@] - `(?:(?P[^\(]*)(?:\((?P[^\)]*)\))?)?` + // [net[(addr)]] - `\/(?P.*?)` + // /dbname - `(?:\?(?P[^\?]*))?$`) // [?param1=value1¶mN=valueN] - matches := dsnPattern.FindStringSubmatch(dataSourceName) - // tlsConfigRegister := make(map[string]*tls.Config) - names := dsnPattern.SubexpNames() - - for i, match := range matches { - switch names[i] { - case "dbname": - db.DbName = match - } - } - if db.DbName == "" { - return nil, errors.New("dbname is empty") - } - return db, nil -} - -type oci8Driver struct { -} - -// dataSourceName=user/password@ipv4:port/dbname -// dataSourceName=user/password@[ipv6]:port/dbname -func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) { - db := &core.Uri{DbType: core.ORACLE} - dsnPattern := regexp.MustCompile( - `^(?P.*)\/(?P.*)@` + // user:password@ - `(?P.*)` + // ip:port - `\/(?P.*)`) // dbname - matches := dsnPattern.FindStringSubmatch(dataSourceName) - names := dsnPattern.SubexpNames() - for i, match := range matches { - switch names[i] { - case "dbname": - db.DbName = match - } - } - if db.DbName == "" { - return nil, errors.New("dbname is empty") - } - return db, nil -} diff --git a/vendor/github.com/go-xorm/xorm/dialect_postgres.go b/vendor/github.com/go-xorm/xorm/dialect_postgres.go deleted file mode 100644 index ccef3086b2..0000000000 --- a/vendor/github.com/go-xorm/xorm/dialect_postgres.go +++ /dev/null @@ -1,1253 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "net/url" - "strconv" - "strings" - - "xorm.io/core" -) - -// from http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html -var ( - postgresReservedWords = map[string]bool{ - "A": true, - "ABORT": true, - "ABS": true, - "ABSENT": true, - "ABSOLUTE": true, - "ACCESS": true, - "ACCORDING": true, - "ACTION": true, - "ADA": true, - "ADD": true, - "ADMIN": true, - "AFTER": true, - "AGGREGATE": true, - "ALL": true, - "ALLOCATE": true, - "ALSO": true, - "ALTER": true, - "ALWAYS": true, - "ANALYSE": true, - "ANALYZE": true, - "AND": true, - "ANY": true, - "ARE": true, - "ARRAY": true, - "ARRAY_AGG": true, - "ARRAY_MAX_CARDINALITY": true, - "AS": true, - "ASC": true, - "ASENSITIVE": true, - "ASSERTION": true, - "ASSIGNMENT": true, - "ASYMMETRIC": true, - "AT": true, - "ATOMIC": true, - "ATTRIBUTE": true, - "ATTRIBUTES": true, - "AUTHORIZATION": true, - "AVG": true, - "BACKWARD": true, - "BASE64": true, - "BEFORE": true, - "BEGIN": true, - "BEGIN_FRAME": true, - "BEGIN_PARTITION": true, - "BERNOULLI": true, - "BETWEEN": true, - "BIGINT": true, - "BINARY": true, - "BIT": true, - "BIT_LENGTH": true, - "BLOB": true, - "BLOCKED": true, - "BOM": true, - "BOOLEAN": true, - "BOTH": true, - "BREADTH": true, - "BY": true, - "C": true, - "CACHE": true, - "CALL": true, - "CALLED": true, - "CARDINALITY": true, - "CASCADE": true, - "CASCADED": true, - "CASE": true, - "CAST": true, - "CATALOG": true, - "CATALOG_NAME": true, - "CEIL": true, - "CEILING": true, - "CHAIN": true, - "CHAR": true, - "CHARACTER": true, - "CHARACTERISTICS": true, - "CHARACTERS": true, - "CHARACTER_LENGTH": true, - "CHARACTER_SET_CATALOG": true, - "CHARACTER_SET_NAME": true, - "CHARACTER_SET_SCHEMA": true, - "CHAR_LENGTH": true, - "CHECK": true, - "CHECKPOINT": true, - "CLASS": true, - "CLASS_ORIGIN": true, - "CLOB": true, - "CLOSE": true, - "CLUSTER": true, - "COALESCE": true, - "COBOL": true, - "COLLATE": true, - "COLLATION": true, - "COLLATION_CATALOG": true, - "COLLATION_NAME": true, - "COLLATION_SCHEMA": true, - "COLLECT": true, - "COLUMN": true, - "COLUMNS": true, - "COLUMN_NAME": true, - "COMMAND_FUNCTION": true, - "COMMAND_FUNCTION_CODE": true, - "COMMENT": true, - "COMMENTS": true, - "COMMIT": true, - "COMMITTED": true, - "CONCURRENTLY": true, - "CONDITION": true, - "CONDITION_NUMBER": true, - "CONFIGURATION": true, - "CONNECT": true, - "CONNECTION": true, - "CONNECTION_NAME": true, - "CONSTRAINT": true, - "CONSTRAINTS": true, - "CONSTRAINT_CATALOG": true, - "CONSTRAINT_NAME": true, - "CONSTRAINT_SCHEMA": true, - "CONSTRUCTOR": true, - "CONTAINS": true, - "CONTENT": true, - "CONTINUE": true, - "CONTROL": true, - "CONVERSION": true, - "CONVERT": true, - "COPY": true, - "CORR": true, - "CORRESPONDING": true, - "COST": true, - "COUNT": true, - "COVAR_POP": true, - "COVAR_SAMP": true, - "CREATE": true, - "CROSS": true, - "CSV": true, - "CUBE": true, - "CUME_DIST": true, - "CURRENT": true, - "CURRENT_CATALOG": true, - "CURRENT_DATE": true, - "CURRENT_DEFAULT_TRANSFORM_GROUP": true, - "CURRENT_PATH": true, - "CURRENT_ROLE": true, - "CURRENT_ROW": true, - "CURRENT_SCHEMA": true, - "CURRENT_TIME": true, - "CURRENT_TIMESTAMP": true, - "CURRENT_TRANSFORM_GROUP_FOR_TYPE": true, - "CURRENT_USER": true, - "CURSOR": true, - "CURSOR_NAME": true, - "CYCLE": true, - "DATA": true, - "DATABASE": true, - "DATALINK": true, - "DATE": true, - "DATETIME_INTERVAL_CODE": true, - "DATETIME_INTERVAL_PRECISION": true, - "DAY": true, - "DB": true, - "DEALLOCATE": true, - "DEC": true, - "DECIMAL": true, - "DECLARE": true, - "DEFAULT": true, - "DEFAULTS": true, - "DEFERRABLE": true, - "DEFERRED": true, - "DEFINED": true, - "DEFINER": true, - "DEGREE": true, - "DELETE": true, - "DELIMITER": true, - "DELIMITERS": true, - "DENSE_RANK": true, - "DEPTH": true, - "DEREF": true, - "DERIVED": true, - "DESC": true, - "DESCRIBE": true, - "DESCRIPTOR": true, - "DETERMINISTIC": true, - "DIAGNOSTICS": true, - "DICTIONARY": true, - "DISABLE": true, - "DISCARD": true, - "DISCONNECT": true, - "DISPATCH": true, - "DISTINCT": true, - "DLNEWCOPY": true, - "DLPREVIOUSCOPY": true, - "DLURLCOMPLETE": true, - "DLURLCOMPLETEONLY": true, - "DLURLCOMPLETEWRITE": true, - "DLURLPATH": true, - "DLURLPATHONLY": true, - "DLURLPATHWRITE": true, - "DLURLSCHEME": true, - "DLURLSERVER": true, - "DLVALUE": true, - "DO": true, - "DOCUMENT": true, - "DOMAIN": true, - "DOUBLE": true, - "DROP": true, - "DYNAMIC": true, - "DYNAMIC_FUNCTION": true, - "DYNAMIC_FUNCTION_CODE": true, - "EACH": true, - "ELEMENT": true, - "ELSE": true, - "EMPTY": true, - "ENABLE": true, - "ENCODING": true, - "ENCRYPTED": true, - "END": true, - "END-EXEC": true, - "END_FRAME": true, - "END_PARTITION": true, - "ENFORCED": true, - "ENUM": true, - "EQUALS": true, - "ESCAPE": true, - "EVENT": true, - "EVERY": true, - "EXCEPT": true, - "EXCEPTION": true, - "EXCLUDE": true, - "EXCLUDING": true, - "EXCLUSIVE": true, - "EXEC": true, - "EXECUTE": true, - "EXISTS": true, - "EXP": true, - "EXPLAIN": true, - "EXPRESSION": true, - "EXTENSION": true, - "EXTERNAL": true, - "EXTRACT": true, - "FALSE": true, - "FAMILY": true, - "FETCH": true, - "FILE": true, - "FILTER": true, - "FINAL": true, - "FIRST": true, - "FIRST_VALUE": true, - "FLAG": true, - "FLOAT": true, - "FLOOR": true, - "FOLLOWING": true, - "FOR": true, - "FORCE": true, - "FOREIGN": true, - "FORTRAN": true, - "FORWARD": true, - "FOUND": true, - "FRAME_ROW": true, - "FREE": true, - "FREEZE": true, - "FROM": true, - "FS": true, - "FULL": true, - "FUNCTION": true, - "FUNCTIONS": true, - "FUSION": true, - "G": true, - "GENERAL": true, - "GENERATED": true, - "GET": true, - "GLOBAL": true, - "GO": true, - "GOTO": true, - "GRANT": true, - "GRANTED": true, - "GREATEST": true, - "GROUP": true, - "GROUPING": true, - "GROUPS": true, - "HANDLER": true, - "HAVING": true, - "HEADER": true, - "HEX": true, - "HIERARCHY": true, - "HOLD": true, - "HOUR": true, - "ID": true, - "IDENTITY": true, - "IF": true, - "IGNORE": true, - "ILIKE": true, - "IMMEDIATE": true, - "IMMEDIATELY": true, - "IMMUTABLE": true, - "IMPLEMENTATION": true, - "IMPLICIT": true, - "IMPORT": true, - "IN": true, - "INCLUDING": true, - "INCREMENT": true, - "INDENT": true, - "INDEX": true, - "INDEXES": true, - "INDICATOR": true, - "INHERIT": true, - "INHERITS": true, - "INITIALLY": true, - "INLINE": true, - "INNER": true, - "INOUT": true, - "INPUT": true, - "INSENSITIVE": true, - "INSERT": true, - "INSTANCE": true, - "INSTANTIABLE": true, - "INSTEAD": true, - "INT": true, - "INTEGER": true, - "INTEGRITY": true, - "INTERSECT": true, - "INTERSECTION": true, - "INTERVAL": true, - "INTO": true, - "INVOKER": true, - "IS": true, - "ISNULL": true, - "ISOLATION": true, - "JOIN": true, - "K": true, - "KEY": true, - "KEY_MEMBER": true, - "KEY_TYPE": true, - "LABEL": true, - "LAG": true, - "LANGUAGE": true, - "LARGE": true, - "LAST": true, - "LAST_VALUE": true, - "LATERAL": true, - "LC_COLLATE": true, - "LC_CTYPE": true, - "LEAD": true, - "LEADING": true, - "LEAKPROOF": true, - "LEAST": true, - "LEFT": true, - "LENGTH": true, - "LEVEL": true, - "LIBRARY": true, - "LIKE": true, - "LIKE_REGEX": true, - "LIMIT": true, - "LINK": true, - "LISTEN": true, - "LN": true, - "LOAD": true, - "LOCAL": true, - "LOCALTIME": true, - "LOCALTIMESTAMP": true, - "LOCATION": true, - "LOCATOR": true, - "LOCK": true, - "LOWER": true, - "M": true, - "MAP": true, - "MAPPING": true, - "MATCH": true, - "MATCHED": true, - "MATERIALIZED": true, - "MAX": true, - "MAXVALUE": true, - "MAX_CARDINALITY": true, - "MEMBER": true, - "MERGE": true, - "MESSAGE_LENGTH": true, - "MESSAGE_OCTET_LENGTH": true, - "MESSAGE_TEXT": true, - "METHOD": true, - "MIN": true, - "MINUTE": true, - "MINVALUE": true, - "MOD": true, - "MODE": true, - "MODIFIES": true, - "MODULE": true, - "MONTH": true, - "MORE": true, - "MOVE": true, - "MULTISET": true, - "MUMPS": true, - "NAME": true, - "NAMES": true, - "NAMESPACE": true, - "NATIONAL": true, - "NATURAL": true, - "NCHAR": true, - "NCLOB": true, - "NESTING": true, - "NEW": true, - "NEXT": true, - "NFC": true, - "NFD": true, - "NFKC": true, - "NFKD": true, - "NIL": true, - "NO": true, - "NONE": true, - "NORMALIZE": true, - "NORMALIZED": true, - "NOT": true, - "NOTHING": true, - "NOTIFY": true, - "NOTNULL": true, - "NOWAIT": true, - "NTH_VALUE": true, - "NTILE": true, - "NULL": true, - "NULLABLE": true, - "NULLIF": true, - "NULLS": true, - "NUMBER": true, - "NUMERIC": true, - "OBJECT": true, - "OCCURRENCES_REGEX": true, - "OCTETS": true, - "OCTET_LENGTH": true, - "OF": true, - "OFF": true, - "OFFSET": true, - "OIDS": true, - "OLD": true, - "ON": true, - "ONLY": true, - "OPEN": true, - "OPERATOR": true, - "OPTION": true, - "OPTIONS": true, - "OR": true, - "ORDER": true, - "ORDERING": true, - "ORDINALITY": true, - "OTHERS": true, - "OUT": true, - "OUTER": true, - "OUTPUT": true, - "OVER": true, - "OVERLAPS": true, - "OVERLAY": true, - "OVERRIDING": true, - "OWNED": true, - "OWNER": true, - "P": true, - "PAD": true, - "PARAMETER": true, - "PARAMETER_MODE": true, - "PARAMETER_NAME": true, - "PARAMETER_ORDINAL_POSITION": true, - "PARAMETER_SPECIFIC_CATALOG": true, - "PARAMETER_SPECIFIC_NAME": true, - "PARAMETER_SPECIFIC_SCHEMA": true, - "PARSER": true, - "PARTIAL": true, - "PARTITION": true, - "PASCAL": true, - "PASSING": true, - "PASSTHROUGH": true, - "PASSWORD": true, - "PATH": true, - "PERCENT": true, - "PERCENTILE_CONT": true, - "PERCENTILE_DISC": true, - "PERCENT_RANK": true, - "PERIOD": true, - "PERMISSION": true, - "PLACING": true, - "PLANS": true, - "PLI": true, - "PORTION": true, - "POSITION": true, - "POSITION_REGEX": true, - "POWER": true, - "PRECEDES": true, - "PRECEDING": true, - "PRECISION": true, - "PREPARE": true, - "PREPARED": true, - "PRESERVE": true, - "PRIMARY": true, - "PRIOR": true, - "PRIVILEGES": true, - "PROCEDURAL": true, - "PROCEDURE": true, - "PROGRAM": true, - "PUBLIC": true, - "QUOTE": true, - "RANGE": true, - "RANK": true, - "READ": true, - "READS": true, - "REAL": true, - "REASSIGN": true, - "RECHECK": true, - "RECOVERY": true, - "RECURSIVE": true, - "REF": true, - "REFERENCES": true, - "REFERENCING": true, - "REFRESH": true, - "REGR_AVGX": true, - "REGR_AVGY": true, - "REGR_COUNT": true, - "REGR_INTERCEPT": true, - "REGR_R2": true, - "REGR_SLOPE": true, - "REGR_SXX": true, - "REGR_SXY": true, - "REGR_SYY": true, - "REINDEX": true, - "RELATIVE": true, - "RELEASE": true, - "RENAME": true, - "REPEATABLE": true, - "REPLACE": true, - "REPLICA": true, - "REQUIRING": true, - "RESET": true, - "RESPECT": true, - "RESTART": true, - "RESTORE": true, - "RESTRICT": true, - "RESULT": true, - "RETURN": true, - "RETURNED_CARDINALITY": true, - "RETURNED_LENGTH": true, - "RETURNED_OCTET_LENGTH": true, - "RETURNED_SQLSTATE": true, - "RETURNING": true, - "RETURNS": true, - "REVOKE": true, - "RIGHT": true, - "ROLE": true, - "ROLLBACK": true, - "ROLLUP": true, - "ROUTINE": true, - "ROUTINE_CATALOG": true, - "ROUTINE_NAME": true, - "ROUTINE_SCHEMA": true, - "ROW": true, - "ROWS": true, - "ROW_COUNT": true, - "ROW_NUMBER": true, - "RULE": true, - "SAVEPOINT": true, - "SCALE": true, - "SCHEMA": true, - "SCHEMA_NAME": true, - "SCOPE": true, - "SCOPE_CATALOG": true, - "SCOPE_NAME": true, - "SCOPE_SCHEMA": true, - "SCROLL": true, - "SEARCH": true, - "SECOND": true, - "SECTION": true, - "SECURITY": true, - "SELECT": true, - "SELECTIVE": true, - "SELF": true, - "SENSITIVE": true, - "SEQUENCE": true, - "SEQUENCES": true, - "SERIALIZABLE": true, - "SERVER": true, - "SERVER_NAME": true, - "SESSION": true, - "SESSION_USER": true, - "SET": true, - "SETOF": true, - "SETS": true, - "SHARE": true, - "SHOW": true, - "SIMILAR": true, - "SIMPLE": true, - "SIZE": true, - "SMALLINT": true, - "SNAPSHOT": true, - "SOME": true, - "SOURCE": true, - "SPACE": true, - "SPECIFIC": true, - "SPECIFICTYPE": true, - "SPECIFIC_NAME": true, - "SQL": true, - "SQLCODE": true, - "SQLERROR": true, - "SQLEXCEPTION": true, - "SQLSTATE": true, - "SQLWARNING": true, - "SQRT": true, - "STABLE": true, - "STANDALONE": true, - "START": true, - "STATE": true, - "STATEMENT": true, - "STATIC": true, - "STATISTICS": true, - "STDDEV_POP": true, - "STDDEV_SAMP": true, - "STDIN": true, - "STDOUT": true, - "STORAGE": true, - "STRICT": true, - "STRIP": true, - "STRUCTURE": true, - "STYLE": true, - "SUBCLASS_ORIGIN": true, - "SUBMULTISET": true, - "SUBSTRING": true, - "SUBSTRING_REGEX": true, - "SUCCEEDS": true, - "SUM": true, - "SYMMETRIC": true, - "SYSID": true, - "SYSTEM": true, - "SYSTEM_TIME": true, - "SYSTEM_USER": true, - "T": true, - "TABLE": true, - "TABLES": true, - "TABLESAMPLE": true, - "TABLESPACE": true, - "TABLE_NAME": true, - "TEMP": true, - "TEMPLATE": true, - "TEMPORARY": true, - "TEXT": true, - "THEN": true, - "TIES": true, - "TIME": true, - "TIMESTAMP": true, - "TIMEZONE_HOUR": true, - "TIMEZONE_MINUTE": true, - "TO": true, - "TOKEN": true, - "TOP_LEVEL_COUNT": true, - "TRAILING": true, - "TRANSACTION": true, - "TRANSACTIONS_COMMITTED": true, - "TRANSACTIONS_ROLLED_BACK": true, - "TRANSACTION_ACTIVE": true, - "TRANSFORM": true, - "TRANSFORMS": true, - "TRANSLATE": true, - "TRANSLATE_REGEX": true, - "TRANSLATION": true, - "TREAT": true, - "TRIGGER": true, - "TRIGGER_CATALOG": true, - "TRIGGER_NAME": true, - "TRIGGER_SCHEMA": true, - "TRIM": true, - "TRIM_ARRAY": true, - "TRUE": true, - "TRUNCATE": true, - "TRUSTED": true, - "TYPE": true, - "TYPES": true, - "UESCAPE": true, - "UNBOUNDED": true, - "UNCOMMITTED": true, - "UNDER": true, - "UNENCRYPTED": true, - "UNION": true, - "UNIQUE": true, - "UNKNOWN": true, - "UNLINK": true, - "UNLISTEN": true, - "UNLOGGED": true, - "UNNAMED": true, - "UNNEST": true, - "UNTIL": true, - "UNTYPED": true, - "UPDATE": true, - "UPPER": true, - "URI": true, - "USAGE": true, - "USER": true, - "USER_DEFINED_TYPE_CATALOG": true, - "USER_DEFINED_TYPE_CODE": true, - "USER_DEFINED_TYPE_NAME": true, - "USER_DEFINED_TYPE_SCHEMA": true, - "USING": true, - "VACUUM": true, - "VALID": true, - "VALIDATE": true, - "VALIDATOR": true, - "VALUE": true, - "VALUES": true, - "VALUE_OF": true, - "VARBINARY": true, - "VARCHAR": true, - "VARIADIC": true, - "VARYING": true, - "VAR_POP": true, - "VAR_SAMP": true, - "VERBOSE": true, - "VERSION": true, - "VERSIONING": true, - "VIEW": true, - "VOLATILE": true, - "WHEN": true, - "WHENEVER": true, - "WHERE": true, - "WHITESPACE": true, - "WIDTH_BUCKET": true, - "WINDOW": true, - "WITH": true, - "WITHIN": true, - "WITHOUT": true, - "WORK": true, - "WRAPPER": true, - "WRITE": true, - "XML": true, - "XMLAGG": true, - "XMLATTRIBUTES": true, - "XMLBINARY": true, - "XMLCAST": true, - "XMLCOMMENT": true, - "XMLCONCAT": true, - "XMLDECLARATION": true, - "XMLDOCUMENT": true, - "XMLELEMENT": true, - "XMLEXISTS": true, - "XMLFOREST": true, - "XMLITERATE": true, - "XMLNAMESPACES": true, - "XMLPARSE": true, - "XMLPI": true, - "XMLQUERY": true, - "XMLROOT": true, - "XMLSCHEMA": true, - "XMLSERIALIZE": true, - "XMLTABLE": true, - "XMLTEXT": true, - "XMLVALIDATE": true, - "YEAR": true, - "YES": true, - "ZONE": true, - } - - // DefaultPostgresSchema default postgres schema - DefaultPostgresSchema = "public" -) - -const postgresPublicSchema = "public" - -type postgres struct { - core.Base -} - -func (db *postgres) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { - err := db.Base.Init(d, db, uri, drivername, dataSourceName) - if err != nil { - return err - } - if db.Schema == "" { - db.Schema = DefaultPostgresSchema - } - return nil -} - -func (db *postgres) SqlType(c *core.Column) string { - var res string - switch t := c.SQLType.Name; t { - case core.TinyInt: - res = core.SmallInt - return res - case core.Bit: - res = core.Boolean - return res - case core.MediumInt, core.Int, core.Integer: - if c.IsAutoIncrement { - return core.Serial - } - return core.Integer - case core.BigInt: - if c.IsAutoIncrement { - return core.BigSerial - } - return core.BigInt - case core.Serial, core.BigSerial: - c.IsAutoIncrement = true - c.Nullable = false - res = t - case core.Binary, core.VarBinary: - return core.Bytea - case core.DateTime: - res = core.TimeStamp - case core.TimeStampz: - return "timestamp with time zone" - case core.Float: - res = core.Real - case core.TinyText, core.MediumText, core.LongText: - res = core.Text - case core.NVarchar: - res = core.Varchar - case core.Uuid: - return core.Uuid - case core.Blob, core.TinyBlob, core.MediumBlob, core.LongBlob: - return core.Bytea - case core.Double: - return "DOUBLE PRECISION" - default: - if c.IsAutoIncrement { - return core.Serial - } - res = t - } - - if strings.EqualFold(res, "bool") { - // for bool, we don't need length information - return res - } - hasLen1 := (c.Length > 0) - hasLen2 := (c.Length2 > 0) - - if hasLen2 { - res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" - } else if hasLen1 { - res += "(" + strconv.Itoa(c.Length) + ")" - } - return res -} - -func (db *postgres) SupportInsertMany() bool { - return true -} - -func (db *postgres) IsReserved(name string) bool { - _, ok := postgresReservedWords[name] - return ok -} - -func (db *postgres) Quote(name string) string { - name = strings.Replace(name, ".", `"."`, -1) - return "\"" + name + "\"" -} - -func (db *postgres) AutoIncrStr() string { - return "" -} - -func (db *postgres) SupportEngine() bool { - return false -} - -func (db *postgres) SupportCharset() bool { - return false -} - -func (db *postgres) IndexOnTable() bool { - return false -} - -func (db *postgres) IndexCheckSql(tableName, idxName string) (string, []interface{}) { - if len(db.Schema) == 0 { - args := []interface{}{tableName, idxName} - return `SELECT indexname FROM pg_indexes WHERE tablename = ? AND indexname = ?`, args - } - - args := []interface{}{db.Schema, tableName, idxName} - return `SELECT indexname FROM pg_indexes ` + - `WHERE schemaname = ? AND tablename = ? AND indexname = ?`, args -} - -func (db *postgres) TableCheckSql(tableName string) (string, []interface{}) { - if len(db.Schema) == 0 { - args := []interface{}{tableName} - return `SELECT tablename FROM pg_tables WHERE tablename = ?`, args - } - - args := []interface{}{db.Schema, tableName} - return `SELECT tablename FROM pg_tables WHERE schemaname = ? AND tablename = ?`, args -} - -func (db *postgres) ModifyColumnSql(tableName string, col *core.Column) string { - if len(db.Schema) == 0 { - return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s", - tableName, col.Name, db.SqlType(col)) - } - return fmt.Sprintf("alter table %s.%s ALTER COLUMN %s TYPE %s", - db.Schema, tableName, col.Name, db.SqlType(col)) -} - -func (db *postgres) DropIndexSql(tableName string, index *core.Index) string { - quote := db.Quote - idxName := index.Name - - tableName = strings.Replace(tableName, `"`, "", -1) - tableName = strings.Replace(tableName, `.`, "_", -1) - - if !strings.HasPrefix(idxName, "UQE_") && - !strings.HasPrefix(idxName, "IDX_") { - if index.Type == core.UniqueType { - idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name) - } else { - idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) - } - } - if db.Uri.Schema != "" { - idxName = db.Uri.Schema + "." + idxName - } - return fmt.Sprintf("DROP INDEX %v", quote(idxName)) -} - -func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) { - args := []interface{}{db.Schema, tableName, colName} - query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = $1 AND table_name = $2" + - " AND column_name = $3" - if len(db.Schema) == 0 { - args = []interface{}{tableName, colName} - query = "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" + - " AND column_name = $2" - } - db.LogSQL(query, args) - - rows, err := db.DB().Query(query, args...) - if err != nil { - return false, err - } - defer rows.Close() - - return rows.Next(), nil -} - -func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { - args := []interface{}{tableName} - s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, - CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey, - CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey -FROM pg_attribute f - JOIN pg_class c ON c.oid = f.attrelid JOIN pg_type t ON t.oid = f.atttypid - LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum - LEFT JOIN pg_namespace n ON n.oid = c.relnamespace - LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey) - LEFT JOIN pg_class AS g ON p.confrelid = g.oid - LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name -WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.attnum;` - - var f string - if len(db.Schema) != 0 { - args = append(args, db.Schema) - f = " AND s.table_schema = $2" - } - s = fmt.Sprintf(s, f) - - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, nil, err - } - defer rows.Close() - - cols := make(map[string]*core.Column) - colSeq := make([]string, 0) - - for rows.Next() { - col := new(core.Column) - col.Indexes = make(map[string]int) - - var colName, isNullable, dataType string - var maxLenStr, colDefault *string - var isPK, isUnique bool - err = rows.Scan(&colName, &colDefault, &isNullable, &dataType, &maxLenStr, &isPK, &isUnique) - if err != nil { - return nil, nil, err - } - - // fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, isPK, isUnique) - var maxLen int - if maxLenStr != nil { - maxLen, err = strconv.Atoi(*maxLenStr) - if err != nil { - return nil, nil, err - } - } - - col.Name = strings.Trim(colName, `" `) - - if colDefault != nil { - col.Default = *colDefault - col.DefaultIsEmpty = false - if strings.HasPrefix(col.Default, "nextval(") { - col.IsAutoIncrement = true - } - } else { - col.DefaultIsEmpty = true - } - - if isPK { - col.IsPrimaryKey = true - } - - col.Nullable = (isNullable == "YES") - - switch dataType { - case "character varying", "character": - col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: 0, DefaultLength2: 0} - case "timestamp without time zone": - col.SQLType = core.SQLType{Name: core.DateTime, DefaultLength: 0, DefaultLength2: 0} - case "timestamp with time zone": - col.SQLType = core.SQLType{Name: core.TimeStampz, DefaultLength: 0, DefaultLength2: 0} - case "double precision": - col.SQLType = core.SQLType{Name: core.Double, DefaultLength: 0, DefaultLength2: 0} - case "boolean": - col.SQLType = core.SQLType{Name: core.Bool, DefaultLength: 0, DefaultLength2: 0} - case "time without time zone": - col.SQLType = core.SQLType{Name: core.Time, DefaultLength: 0, DefaultLength2: 0} - case "oid": - col.SQLType = core.SQLType{Name: core.BigInt, DefaultLength: 0, DefaultLength2: 0} - default: - col.SQLType = core.SQLType{Name: strings.ToUpper(dataType), DefaultLength: 0, DefaultLength2: 0} - } - if _, ok := core.SqlTypes[col.SQLType.Name]; !ok { - return nil, nil, fmt.Errorf("Unknown colType: %v", dataType) - } - - col.Length = maxLen - - if !col.DefaultIsEmpty { - if col.SQLType.IsText() { - if strings.HasSuffix(col.Default, "::character varying") { - col.Default = strings.TrimRight(col.Default, "::character varying") - } else if !strings.HasPrefix(col.Default, "'") { - col.Default = "'" + col.Default + "'" - } - } else if col.SQLType.IsTime() { - if strings.HasSuffix(col.Default, "::timestamp without time zone") { - col.Default = strings.TrimRight(col.Default, "::timestamp without time zone") - } - } - } - cols[col.Name] = col - colSeq = append(colSeq, col.Name) - } - - return colSeq, cols, nil -} - -func (db *postgres) GetTables() ([]*core.Table, error) { - args := []interface{}{} - s := "SELECT tablename FROM pg_tables" - if len(db.Schema) != 0 { - args = append(args, db.Schema) - s = s + " WHERE schemaname = $1" - } - - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - tables := make([]*core.Table, 0) - for rows.Next() { - table := core.NewEmptyTable() - var name string - err = rows.Scan(&name) - if err != nil { - return nil, err - } - table.Name = name - tables = append(tables, table) - } - return tables, nil -} - -func getIndexColName(indexdef string) []string { - var colNames []string - - cs := strings.Split(indexdef, "(") - for _, v := range strings.Split(strings.Split(cs[1], ")")[0], ",") { - colNames = append(colNames, strings.Split(strings.TrimLeft(v, " "), " ")[0]) - } - - return colNames -} - -func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) { - args := []interface{}{tableName} - s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1") - if len(db.Schema) != 0 { - args = append(args, db.Schema) - s = s + " AND schemaname=$2" - } - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - indexes := make(map[string]*core.Index, 0) - for rows.Next() { - var indexType int - var indexName, indexdef string - var colNames []string - err = rows.Scan(&indexName, &indexdef) - if err != nil { - return nil, err - } - indexName = strings.Trim(indexName, `" `) - if strings.HasSuffix(indexName, "_pkey") { - continue - } - if strings.HasPrefix(indexdef, "CREATE UNIQUE INDEX") { - indexType = core.UniqueType - } else { - indexType = core.IndexType - } - colNames = getIndexColName(indexdef) - var isRegular bool - if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { - newIdxName := indexName[5+len(tableName):] - isRegular = true - if newIdxName != "" { - indexName = newIdxName - } - } - - index := &core.Index{Name: indexName, Type: indexType, Cols: make([]string, 0)} - for _, colName := range colNames { - index.Cols = append(index.Cols, strings.Trim(colName, `" `)) - } - index.IsRegular = isRegular - indexes[index.Name] = index - } - return indexes, nil -} - -func (db *postgres) Filters() []core.Filter { - return []core.Filter{&core.IdFilter{}, &core.QuoteFilter{}, &core.SeqFilter{Prefix: "$", Start: 1}} -} - -type pqDriver struct { -} - -type values map[string]string - -func (vs values) Set(k, v string) { - vs[k] = v -} - -func (vs values) Get(k string) (v string) { - return vs[k] -} - -func parseURL(connstr string) (string, error) { - u, err := url.Parse(connstr) - if err != nil { - return "", err - } - - if u.Scheme != "postgresql" && u.Scheme != "postgres" { - return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) - } - - escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`) - - if u.Path != "" { - return escaper.Replace(u.Path[1:]), nil - } - - return "", nil -} - -func parseOpts(name string, o values) error { - if len(name) == 0 { - return fmt.Errorf("invalid options: %s", name) - } - - name = strings.TrimSpace(name) - - ps := strings.Split(name, " ") - for _, p := range ps { - kv := strings.Split(p, "=") - if len(kv) < 2 { - return fmt.Errorf("invalid option: %q", p) - } - o.Set(kv[0], kv[1]) - } - - return nil -} - -func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { - db := &core.Uri{DbType: core.POSTGRES} - var err error - - if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") { - db.DbName, err = parseURL(dataSourceName) - if err != nil { - return nil, err - } - } else { - o := make(values) - err = parseOpts(dataSourceName, o) - if err != nil { - return nil, err - } - - db.DbName = o.Get("dbname") - } - - if db.DbName == "" { - return nil, errors.New("dbname is empty") - } - - return db, nil -} - -type pqDriverPgx struct { - pqDriver -} - -func (pgx *pqDriverPgx) Parse(driverName, dataSourceName string) (*core.Uri, error) { - // Remove the leading characters for driver to work - if len(dataSourceName) >= 9 && dataSourceName[0] == 0 { - dataSourceName = dataSourceName[9:] - } - return pgx.pqDriver.Parse(driverName, dataSourceName) -} diff --git a/vendor/github.com/go-xorm/xorm/dialect_sqlite3.go b/vendor/github.com/go-xorm/xorm/dialect_sqlite3.go deleted file mode 100644 index 0a290f3c48..0000000000 --- a/vendor/github.com/go-xorm/xorm/dialect_sqlite3.go +++ /dev/null @@ -1,492 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql" - "errors" - "fmt" - "regexp" - "strings" - - "xorm.io/core" -) - -var ( - sqlite3ReservedWords = map[string]bool{ - "ABORT": true, - "ACTION": true, - "ADD": true, - "AFTER": true, - "ALL": true, - "ALTER": true, - "ANALYZE": true, - "AND": true, - "AS": true, - "ASC": true, - "ATTACH": true, - "AUTOINCREMENT": true, - "BEFORE": true, - "BEGIN": true, - "BETWEEN": true, - "BY": true, - "CASCADE": true, - "CASE": true, - "CAST": true, - "CHECK": true, - "COLLATE": true, - "COLUMN": true, - "COMMIT": true, - "CONFLICT": true, - "CONSTRAINT": true, - "CREATE": true, - "CROSS": true, - "CURRENT_DATE": true, - "CURRENT_TIME": true, - "CURRENT_TIMESTAMP": true, - "DATABASE": true, - "DEFAULT": true, - "DEFERRABLE": true, - "DEFERRED": true, - "DELETE": true, - "DESC": true, - "DETACH": true, - "DISTINCT": true, - "DROP": true, - "EACH": true, - "ELSE": true, - "END": true, - "ESCAPE": true, - "EXCEPT": true, - "EXCLUSIVE": true, - "EXISTS": true, - "EXPLAIN": true, - "FAIL": true, - "FOR": true, - "FOREIGN": true, - "FROM": true, - "FULL": true, - "GLOB": true, - "GROUP": true, - "HAVING": true, - "IF": true, - "IGNORE": true, - "IMMEDIATE": true, - "IN": true, - "INDEX": true, - "INDEXED": true, - "INITIALLY": true, - "INNER": true, - "INSERT": true, - "INSTEAD": true, - "INTERSECT": true, - "INTO": true, - "IS": true, - "ISNULL": true, - "JOIN": true, - "KEY": true, - "LEFT": true, - "LIKE": true, - "LIMIT": true, - "MATCH": true, - "NATURAL": true, - "NO": true, - "NOT": true, - "NOTNULL": true, - "NULL": true, - "OF": true, - "OFFSET": true, - "ON": true, - "OR": true, - "ORDER": true, - "OUTER": true, - "PLAN": true, - "PRAGMA": true, - "PRIMARY": true, - "QUERY": true, - "RAISE": true, - "RECURSIVE": true, - "REFERENCES": true, - "REGEXP": true, - "REINDEX": true, - "RELEASE": true, - "RENAME": true, - "REPLACE": true, - "RESTRICT": true, - "RIGHT": true, - "ROLLBACK": true, - "ROW": true, - "SAVEPOINT": true, - "SELECT": true, - "SET": true, - "TABLE": true, - "TEMP": true, - "TEMPORARY": true, - "THEN": true, - "TO": true, - "TRANSACTI": true, - "TRIGGER": true, - "UNION": true, - "UNIQUE": true, - "UPDATE": true, - "USING": true, - "VACUUM": true, - "VALUES": true, - "VIEW": true, - "VIRTUAL": true, - "WHEN": true, - "WHERE": true, - "WITH": true, - "WITHOUT": true, - } -) - -type sqlite3 struct { - core.Base -} - -func (db *sqlite3) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { - return db.Base.Init(d, db, uri, drivername, dataSourceName) -} - -func (db *sqlite3) SqlType(c *core.Column) string { - switch t := c.SQLType.Name; t { - case core.Bool: - if c.Default == "true" { - c.Default = "1" - } else if c.Default == "false" { - c.Default = "0" - } - return core.Integer - case core.Date, core.DateTime, core.TimeStamp, core.Time: - return core.DateTime - case core.TimeStampz: - return core.Text - case core.Char, core.Varchar, core.NVarchar, core.TinyText, - core.Text, core.MediumText, core.LongText, core.Json: - return core.Text - case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt: - return core.Integer - case core.Float, core.Double, core.Real: - return core.Real - case core.Decimal, core.Numeric: - return core.Numeric - case core.TinyBlob, core.Blob, core.MediumBlob, core.LongBlob, core.Bytea, core.Binary, core.VarBinary: - return core.Blob - case core.Serial, core.BigSerial: - c.IsPrimaryKey = true - c.IsAutoIncrement = true - c.Nullable = false - return core.Integer - default: - return t - } -} - -func (db *sqlite3) FormatBytes(bs []byte) string { - return fmt.Sprintf("X'%x'", bs) -} - -func (db *sqlite3) SupportInsertMany() bool { - return true -} - -func (db *sqlite3) IsReserved(name string) bool { - _, ok := sqlite3ReservedWords[name] - return ok -} - -func (db *sqlite3) Quote(name string) string { - return "`" + name + "`" -} - -func (db *sqlite3) AutoIncrStr() string { - return "AUTOINCREMENT" -} - -func (db *sqlite3) SupportEngine() bool { - return false -} - -func (db *sqlite3) SupportCharset() bool { - return false -} - -func (db *sqlite3) IndexOnTable() bool { - return false -} - -func (db *sqlite3) IndexCheckSql(tableName, idxName string) (string, []interface{}) { - args := []interface{}{idxName} - return "SELECT name FROM sqlite_master WHERE type='index' and name = ?", args -} - -func (db *sqlite3) TableCheckSql(tableName string) (string, []interface{}) { - args := []interface{}{tableName} - return "SELECT name FROM sqlite_master WHERE type='table' and name = ?", args -} - -func (db *sqlite3) DropIndexSql(tableName string, index *core.Index) string { - // var unique string - quote := db.Quote - idxName := index.Name - - if !strings.HasPrefix(idxName, "UQE_") && - !strings.HasPrefix(idxName, "IDX_") { - if index.Type == core.UniqueType { - idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name) - } else { - idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) - } - } - return fmt.Sprintf("DROP INDEX %v", quote(idxName)) -} - -func (db *sqlite3) ForUpdateSql(query string) string { - return query -} - -/*func (db *sqlite3) ColumnCheckSql(tableName, colName string) (string, []interface{}) { - args := []interface{}{tableName} - sql := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))" - return sql, args -}*/ - -func (db *sqlite3) IsColumnExist(tableName, colName string) (bool, error) { - args := []interface{}{tableName} - query := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))" - db.LogSQL(query, args) - rows, err := db.DB().Query(query, args...) - if err != nil { - return false, err - } - defer rows.Close() - - if rows.Next() { - return true, nil - } - return false, nil -} - -// splitColStr splits a sqlite col strings as fields -func splitColStr(colStr string) []string { - colStr = strings.TrimSpace(colStr) - var results = make([]string, 0, 10) - var lastIdx int - var hasC, hasQuote bool - for i, c := range colStr { - if c == ' ' && !hasQuote { - if hasC { - results = append(results, colStr[lastIdx:i]) - hasC = false - } - } else { - if c == '\'' { - hasQuote = !hasQuote - } - if !hasC { - lastIdx = i - } - hasC = true - if i == len(colStr)-1 { - results = append(results, colStr[lastIdx:i+1]) - } - } - } - return results -} - -func parseString(colStr string) (*core.Column, error) { - fields := splitColStr(colStr) - col := new(core.Column) - col.Indexes = make(map[string]int) - col.Nullable = true - col.DefaultIsEmpty = true - - for idx, field := range fields { - if idx == 0 { - col.Name = strings.Trim(strings.Trim(field, "`[] "), `"`) - continue - } else if idx == 1 { - col.SQLType = core.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0} - continue - } - switch field { - case "PRIMARY": - col.IsPrimaryKey = true - case "AUTOINCREMENT": - col.IsAutoIncrement = true - case "NULL": - if fields[idx-1] == "NOT" { - col.Nullable = false - } else { - col.Nullable = true - } - case "DEFAULT": - col.Default = fields[idx+1] - col.DefaultIsEmpty = false - } - } - return col, nil -} - -func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { - args := []interface{}{tableName} - s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?" - db.LogSQL(s, args) - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, nil, err - } - defer rows.Close() - - var name string - for rows.Next() { - err = rows.Scan(&name) - if err != nil { - return nil, nil, err - } - break - } - - if name == "" { - return nil, nil, errors.New("no table named " + tableName) - } - - nStart := strings.Index(name, "(") - nEnd := strings.LastIndex(name, ")") - reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`) - colCreates := reg.FindAllString(name[nStart+1:nEnd], -1) - cols := make(map[string]*core.Column) - colSeq := make([]string, 0) - - for _, colStr := range colCreates { - reg = regexp.MustCompile(`,\s`) - colStr = reg.ReplaceAllString(colStr, ",") - if strings.HasPrefix(strings.TrimSpace(colStr), "PRIMARY KEY") { - parts := strings.Split(strings.TrimSpace(colStr), "(") - if len(parts) == 2 { - pkCols := strings.Split(strings.TrimRight(strings.TrimSpace(parts[1]), ")"), ",") - for _, pk := range pkCols { - if col, ok := cols[strings.Trim(strings.TrimSpace(pk), "`")]; ok { - col.IsPrimaryKey = true - } - } - } - continue - } - - col, err := parseString(colStr) - if err != nil { - return colSeq, cols, err - } - - cols[col.Name] = col - colSeq = append(colSeq, col.Name) - } - return colSeq, cols, nil -} - -func (db *sqlite3) GetTables() ([]*core.Table, error) { - args := []interface{}{} - s := "SELECT name FROM sqlite_master WHERE type='table'" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - tables := make([]*core.Table, 0) - for rows.Next() { - table := core.NewEmptyTable() - err = rows.Scan(&table.Name) - if err != nil { - return nil, err - } - if table.Name == "sqlite_sequence" { - continue - } - tables = append(tables, table) - } - return tables, nil -} - -func (db *sqlite3) GetIndexes(tableName string) (map[string]*core.Index, error) { - args := []interface{}{tableName} - s := "SELECT sql FROM sqlite_master WHERE type='index' and tbl_name = ?" - db.LogSQL(s, args) - - rows, err := db.DB().Query(s, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - indexes := make(map[string]*core.Index, 0) - for rows.Next() { - var tmpSQL sql.NullString - err = rows.Scan(&tmpSQL) - if err != nil { - return nil, err - } - - if !tmpSQL.Valid { - continue - } - sql := tmpSQL.String - - index := new(core.Index) - nNStart := strings.Index(sql, "INDEX") - nNEnd := strings.Index(sql, "ON") - if nNStart == -1 || nNEnd == -1 { - continue - } - - indexName := strings.Trim(sql[nNStart+6:nNEnd], "` []") - var isRegular bool - if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { - index.Name = indexName[5+len(tableName):] - isRegular = true - } else { - index.Name = indexName - } - - if strings.HasPrefix(sql, "CREATE UNIQUE INDEX") { - index.Type = core.UniqueType - } else { - index.Type = core.IndexType - } - - nStart := strings.Index(sql, "(") - nEnd := strings.Index(sql, ")") - colIndexes := strings.Split(sql[nStart+1:nEnd], ",") - - index.Cols = make([]string, 0) - for _, col := range colIndexes { - index.Cols = append(index.Cols, strings.Trim(col, "` []")) - } - index.IsRegular = isRegular - indexes[index.Name] = index - } - - return indexes, nil -} - -func (db *sqlite3) Filters() []core.Filter { - return []core.Filter{&core.IdFilter{}} -} - -type sqlite3Driver struct { -} - -func (p *sqlite3Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) { - if strings.Contains(dataSourceName, "?") { - dataSourceName = dataSourceName[:strings.Index(dataSourceName, "?")] - } - - return &core.Uri{DbType: core.SQLITE, DbName: dataSourceName}, nil -} diff --git a/vendor/github.com/go-xorm/xorm/doc.go b/vendor/github.com/go-xorm/xorm/doc.go deleted file mode 100644 index a687e69476..0000000000 --- a/vendor/github.com/go-xorm/xorm/doc.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2013 - 2016 The XORM Authors. All rights reserved. -// Use of this source code is governed by a BSD -// license that can be found in the LICENSE file. - -/* - -Package xorm is a simple and powerful ORM for Go. - -Installation - -Make sure you have installed Go 1.6+ and then: - - go get github.com/go-xorm/xorm - -Create Engine - -Firstly, we should new an engine for a database - - engine, err := xorm.NewEngine(driverName, dataSourceName) - -Method NewEngine's parameters is the same as sql.Open. It depends -drivers' implementation. -Generally, one engine for an application is enough. You can set it as package variable. - -Raw Methods - -XORM also support raw SQL execution: - -1. query a SQL string, the returned results is []map[string][]byte - - results, err := engine.Query("select * from user") - -2. execute a SQL string, the returned results - - affected, err := engine.Exec("update user set .... where ...") - -ORM Methods - -There are 8 major ORM methods and many helpful methods to use to operate database. - -1. Insert one or multiple records to database - - affected, err := engine.Insert(&struct) - // INSERT INTO struct () values () - affected, err := engine.Insert(&struct1, &struct2) - // INSERT INTO struct1 () values () - // INSERT INTO struct2 () values () - affected, err := engine.Insert(&sliceOfStruct) - // INSERT INTO struct () values (),(),() - affected, err := engine.Insert(&struct1, &sliceOfStruct2) - // INSERT INTO struct1 () values () - // INSERT INTO struct2 () values (),(),() - -2. Query one record or one variable from database - - has, err := engine.Get(&user) - // SELECT * FROM user LIMIT 1 - - var id int64 - has, err := engine.Table("user").Where("name = ?", name).Get(&id) - // SELECT id FROM user WHERE name = ? LIMIT 1 - -3. Query multiple records from database - - var sliceOfStructs []Struct - err := engine.Find(&sliceOfStructs) - // SELECT * FROM user - - var mapOfStructs = make(map[int64]Struct) - err := engine.Find(&mapOfStructs) - // SELECT * FROM user - - var int64s []int64 - err := engine.Table("user").Cols("id").Find(&int64s) - // SELECT id FROM user - -4. Query multiple records and record by record handle, there two methods, one is Iterate, -another is Rows - - err := engine.Iterate(...) - // SELECT * FROM user - - rows, err := engine.Rows(...) - // SELECT * FROM user - defer rows.Close() - bean := new(Struct) - for rows.Next() { - err = rows.Scan(bean) - } - -5. Update one or more records - - affected, err := engine.ID(...).Update(&user) - // UPDATE user SET ... - -6. Delete one or more records, Delete MUST has condition - - affected, err := engine.Where(...).Delete(&user) - // DELETE FROM user Where ... - -7. Count records - - counts, err := engine.Count(&user) - // SELECT count(*) AS total FROM user - - counts, err := engine.SQL("select count(*) FROM user").Count() - // select count(*) FROM user - -8. Sum records - - sumFloat64, err := engine.Sum(&user, "id") - // SELECT sum(id) from user - - sumFloat64s, err := engine.Sums(&user, "id1", "id2") - // SELECT sum(id1), sum(id2) from user - - sumInt64s, err := engine.SumsInt(&user, "id1", "id2") - // SELECT sum(id1), sum(id2) from user - -Conditions - -The above 8 methods could use with condition methods chainable. -Attention: the above 8 methods should be the last chainable method. - -1. ID, In - - engine.ID(1).Get(&user) // for single primary key - // SELECT * FROM user WHERE id = 1 - engine.ID(core.PK{1, 2}).Get(&user) // for composite primary keys - // SELECT * FROM user WHERE id1 = 1 AND id2 = 2 - engine.In("id", 1, 2, 3).Find(&users) - // SELECT * FROM user WHERE id IN (1, 2, 3) - engine.In("id", []int{1, 2, 3}).Find(&users) - // SELECT * FROM user WHERE id IN (1, 2, 3) - -2. Where, And, Or - - engine.Where().And().Or().Find() - // SELECT * FROM user WHERE (.. AND ..) OR ... - -3. OrderBy, Asc, Desc - - engine.Asc().Desc().Find() - // SELECT * FROM user ORDER BY .. ASC, .. DESC - engine.OrderBy().Find() - // SELECT * FROM user ORDER BY .. - -4. Limit, Top - - engine.Limit().Find() - // SELECT * FROM user LIMIT .. OFFSET .. - engine.Top(5).Find() - // SELECT TOP 5 * FROM user // for mssql - // SELECT * FROM user LIMIT .. OFFSET 0 //for other databases - -5. SQL, let you custom SQL - - var users []User - engine.SQL("select * from user").Find(&users) - -6. Cols, Omit, Distinct - - var users []*User - engine.Cols("col1, col2").Find(&users) - // SELECT col1, col2 FROM user - engine.Cols("col1", "col2").Where().Update(user) - // UPDATE user set col1 = ?, col2 = ? Where ... - engine.Omit("col1").Find(&users) - // SELECT col2, col3 FROM user - engine.Omit("col1").Insert(&user) - // INSERT INTO table (non-col1) VALUES () - engine.Distinct("col1").Find(&users) - // SELECT DISTINCT col1 FROM user - -7. Join, GroupBy, Having - - engine.GroupBy("name").Having("name='xlw'").Find(&users) - //SELECT * FROM user GROUP BY name HAVING name='xlw' - engine.Join("LEFT", "userdetail", "user.id=userdetail.id").Find(&users) - //SELECT * FROM user LEFT JOIN userdetail ON user.id=userdetail.id - -More usage, please visit http://xorm.io/docs -*/ -package xorm diff --git a/vendor/github.com/go-xorm/xorm/engine.go b/vendor/github.com/go-xorm/xorm/engine.go deleted file mode 100644 index 4ed0f77a92..0000000000 --- a/vendor/github.com/go-xorm/xorm/engine.go +++ /dev/null @@ -1,1659 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "bufio" - "bytes" - "context" - "database/sql" - "encoding/gob" - "errors" - "fmt" - "io" - "os" - "reflect" - "strconv" - "strings" - "sync" - "time" - - "xorm.io/builder" - "xorm.io/core" -) - -// Engine is the major struct of xorm, it means a database manager. -// Commonly, an application only need one engine -type Engine struct { - db *core.DB - dialect core.Dialect - - ColumnMapper core.IMapper - TableMapper core.IMapper - TagIdentifier string - Tables map[reflect.Type]*core.Table - - mutex *sync.RWMutex - Cacher core.Cacher - - showSQL bool - showExecTime bool - - logger core.ILogger - TZLocation *time.Location // The timezone of the application - DatabaseTZ *time.Location // The timezone of the database - - disableGlobalCache bool - - tagHandlers map[string]tagHandler - - engineGroup *EngineGroup - - cachers map[string]core.Cacher - cacherLock sync.RWMutex - - defaultContext context.Context -} - -func (engine *Engine) setCacher(tableName string, cacher core.Cacher) { - engine.cacherLock.Lock() - engine.cachers[tableName] = cacher - engine.cacherLock.Unlock() -} - -func (engine *Engine) SetCacher(tableName string, cacher core.Cacher) { - engine.setCacher(tableName, cacher) -} - -func (engine *Engine) getCacher(tableName string) core.Cacher { - var cacher core.Cacher - var ok bool - engine.cacherLock.RLock() - cacher, ok = engine.cachers[tableName] - engine.cacherLock.RUnlock() - if !ok && !engine.disableGlobalCache { - cacher = engine.Cacher - } - return cacher -} - -func (engine *Engine) GetCacher(tableName string) core.Cacher { - return engine.getCacher(tableName) -} - -// BufferSize sets buffer size for iterate -func (engine *Engine) BufferSize(size int) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.BufferSize(size) -} - -// CondDeleted returns the conditions whether a record is soft deleted. -func (engine *Engine) CondDeleted(colName string) builder.Cond { - if engine.dialect.DBType() == core.MSSQL { - return builder.IsNull{colName} - } - return builder.IsNull{colName}.Or(builder.Eq{colName: zeroTime1}) -} - -// ShowSQL show SQL statement or not on logger if log level is great than INFO -func (engine *Engine) ShowSQL(show ...bool) { - engine.logger.ShowSQL(show...) - if len(show) == 0 { - engine.showSQL = true - } else { - engine.showSQL = show[0] - } -} - -// ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO -func (engine *Engine) ShowExecTime(show ...bool) { - if len(show) == 0 { - engine.showExecTime = true - } else { - engine.showExecTime = show[0] - } -} - -// Logger return the logger interface -func (engine *Engine) Logger() core.ILogger { - return engine.logger -} - -// SetLogger set the new logger -func (engine *Engine) SetLogger(logger core.ILogger) { - engine.logger = logger - engine.showSQL = logger.IsShowSQL() - engine.dialect.SetLogger(logger) -} - -// SetLogLevel sets the logger level -func (engine *Engine) SetLogLevel(level core.LogLevel) { - engine.logger.SetLevel(level) -} - -// SetDisableGlobalCache disable global cache or not -func (engine *Engine) SetDisableGlobalCache(disable bool) { - if engine.disableGlobalCache != disable { - engine.disableGlobalCache = disable - } -} - -// DriverName return the current sql driver's name -func (engine *Engine) DriverName() string { - return engine.dialect.DriverName() -} - -// DataSourceName return the current connection string -func (engine *Engine) DataSourceName() string { - return engine.dialect.DataSourceName() -} - -// SetMapper set the name mapping rules -func (engine *Engine) SetMapper(mapper core.IMapper) { - engine.SetTableMapper(mapper) - engine.SetColumnMapper(mapper) -} - -// SetTableMapper set the table name mapping rule -func (engine *Engine) SetTableMapper(mapper core.IMapper) { - engine.TableMapper = mapper -} - -// SetColumnMapper set the column name mapping rule -func (engine *Engine) SetColumnMapper(mapper core.IMapper) { - engine.ColumnMapper = mapper -} - -// SupportInsertMany If engine's database support batch insert records like -// "insert into user values (name, age), (name, age)". -// When the return is ture, then engine.Insert(&users) will -// generate batch sql and exeute. -func (engine *Engine) SupportInsertMany() bool { - return engine.dialect.SupportInsertMany() -} - -func (engine *Engine) quoteColumns(columnStr string) string { - columns := strings.Split(columnStr, ",") - for i := 0; i < len(columns); i++ { - columns[i] = engine.Quote(strings.TrimSpace(columns[i])) - } - return strings.Join(columns, ",") -} - -// Quote Use QuoteStr quote the string sql -func (engine *Engine) Quote(value string) string { - value = strings.TrimSpace(value) - if len(value) == 0 { - return value - } - - buf := strings.Builder{} - engine.QuoteTo(&buf, value) - - return buf.String() -} - -// QuoteTo quotes string and writes into the buffer -func (engine *Engine) QuoteTo(buf *strings.Builder, value string) { - if buf == nil { - return - } - - value = strings.TrimSpace(value) - if value == "" { - return - } - - quotePair := engine.dialect.Quote("") - - if value[0] == '`' || len(quotePair) < 2 || value[0] == quotePair[0] { // no quote - _, _ = buf.WriteString(value) - return - } else { - prefix, suffix := quotePair[0], quotePair[1] - - _ = buf.WriteByte(prefix) - for i := 0; i < len(value); i++ { - if value[i] == '.' { - _ = buf.WriteByte(suffix) - _ = buf.WriteByte('.') - _ = buf.WriteByte(prefix) - } else { - _ = buf.WriteByte(value[i]) - } - } - _ = buf.WriteByte(suffix) - } -} - -func (engine *Engine) quote(sql string) string { - return engine.dialect.Quote(sql) -} - -// SqlType will be deprecated, please use SQLType instead -// -// Deprecated: use SQLType instead -func (engine *Engine) SqlType(c *core.Column) string { - return engine.SQLType(c) -} - -// SQLType A simple wrapper to dialect's core.SqlType method -func (engine *Engine) SQLType(c *core.Column) string { - return engine.dialect.SqlType(c) -} - -// AutoIncrStr Database's autoincrement statement -func (engine *Engine) AutoIncrStr() string { - return engine.dialect.AutoIncrStr() -} - -// SetConnMaxLifetime sets the maximum amount of time a connection may be reused. -func (engine *Engine) SetConnMaxLifetime(d time.Duration) { - engine.db.SetConnMaxLifetime(d) -} - -// SetMaxOpenConns is only available for go 1.2+ -func (engine *Engine) SetMaxOpenConns(conns int) { - engine.db.SetMaxOpenConns(conns) -} - -// SetMaxIdleConns set the max idle connections on pool, default is 2 -func (engine *Engine) SetMaxIdleConns(conns int) { - engine.db.SetMaxIdleConns(conns) -} - -// SetDefaultCacher set the default cacher. Xorm's default not enable cacher. -func (engine *Engine) SetDefaultCacher(cacher core.Cacher) { - engine.Cacher = cacher -} - -// GetDefaultCacher returns the default cacher -func (engine *Engine) GetDefaultCacher() core.Cacher { - return engine.Cacher -} - -// NoCache If you has set default cacher, and you want temporilly stop use cache, -// you can use NoCache() -func (engine *Engine) NoCache() *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.NoCache() -} - -// NoCascade If you do not want to auto cascade load object -func (engine *Engine) NoCascade() *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.NoCascade() -} - -// MapCacher Set a table use a special cacher -func (engine *Engine) MapCacher(bean interface{}, cacher core.Cacher) error { - engine.setCacher(engine.TableName(bean, true), cacher) - return nil -} - -// NewDB provides an interface to operate database directly -func (engine *Engine) NewDB() (*core.DB, error) { - return core.OpenDialect(engine.dialect) -} - -// DB return the wrapper of sql.DB -func (engine *Engine) DB() *core.DB { - return engine.db -} - -// Dialect return database dialect -func (engine *Engine) Dialect() core.Dialect { - return engine.dialect -} - -// NewSession New a session -func (engine *Engine) NewSession() *Session { - session := &Session{engine: engine} - session.Init() - return session -} - -// Close the engine -func (engine *Engine) Close() error { - return engine.db.Close() -} - -// Ping tests if database is alive -func (engine *Engine) Ping() error { - session := engine.NewSession() - defer session.Close() - return session.Ping() -} - -// logging sql -func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) { - if engine.showSQL && !engine.showExecTime { - if len(sqlArgs) > 0 { - engine.logger.Infof("[SQL] %v %#v", sqlStr, sqlArgs) - } else { - engine.logger.Infof("[SQL] %v", sqlStr) - } - } -} - -// Sql provides raw sql input parameter. When you have a complex SQL statement -// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL. -// -// Deprecated: use SQL instead. -func (engine *Engine) Sql(querystring string, args ...interface{}) *Session { - return engine.SQL(querystring, args...) -} - -// SQL method let's you manually write raw SQL and operate -// For example: -// -// engine.SQL("select * from user").Find(&users) -// -// This code will execute "select * from user" and set the records to users -func (engine *Engine) SQL(query interface{}, args ...interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.SQL(query, args...) -} - -// NoAutoTime Default if your struct has "created" or "updated" filed tag, the fields -// will automatically be filled with current time when Insert or Update -// invoked. Call NoAutoTime if you dont' want to fill automatically. -func (engine *Engine) NoAutoTime() *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.NoAutoTime() -} - -// NoAutoCondition disable auto generate Where condition from bean or not -func (engine *Engine) NoAutoCondition(no ...bool) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.NoAutoCondition(no...) -} - -func (engine *Engine) loadTableInfo(table *core.Table) error { - colSeq, cols, err := engine.dialect.GetColumns(table.Name) - if err != nil { - return err - } - for _, name := range colSeq { - table.AddColumn(cols[name]) - } - indexes, err := engine.dialect.GetIndexes(table.Name) - if err != nil { - return err - } - table.Indexes = indexes - - for _, index := range indexes { - for _, name := range index.Cols { - if col := table.GetColumn(name); col != nil { - col.Indexes[index.Name] = index.Type - } else { - return fmt.Errorf("Unknown col %s in index %v of table %v, columns %v", name, index.Name, table.Name, table.ColumnsSeq()) - } - } - } - return nil -} - -// DBMetas Retrieve all tables, columns, indexes' informations from database. -func (engine *Engine) DBMetas() ([]*core.Table, error) { - tables, err := engine.dialect.GetTables() - if err != nil { - return nil, err - } - - for _, table := range tables { - if err = engine.loadTableInfo(table); err != nil { - return nil, err - } - } - return tables, nil -} - -// DumpAllToFile dump database all table structs and data to a file -func (engine *Engine) DumpAllToFile(fp string, tp ...core.DbType) error { - f, err := os.Create(fp) - if err != nil { - return err - } - defer f.Close() - return engine.DumpAll(f, tp...) -} - -// DumpAll dump database all table structs and data to w -func (engine *Engine) DumpAll(w io.Writer, tp ...core.DbType) error { - tables, err := engine.DBMetas() - if err != nil { - return err - } - return engine.DumpTables(tables, w, tp...) -} - -// DumpTablesToFile dump specified tables to SQL file. -func (engine *Engine) DumpTablesToFile(tables []*core.Table, fp string, tp ...core.DbType) error { - f, err := os.Create(fp) - if err != nil { - return err - } - defer f.Close() - return engine.DumpTables(tables, f, tp...) -} - -// DumpTables dump specify tables to io.Writer -func (engine *Engine) DumpTables(tables []*core.Table, w io.Writer, tp ...core.DbType) error { - return engine.dumpTables(tables, w, tp...) -} - -// dumpTables dump database all table structs and data to w with specify db type -func (engine *Engine) dumpTables(tables []*core.Table, w io.Writer, tp ...core.DbType) error { - var dialect core.Dialect - var distDBName string - if len(tp) == 0 { - dialect = engine.dialect - distDBName = string(engine.dialect.DBType()) - } else { - dialect = core.QueryDialect(tp[0]) - if dialect == nil { - return errors.New("Unsupported database type") - } - dialect.Init(nil, engine.dialect.URI(), "", "") - distDBName = string(tp[0]) - } - - _, err := io.WriteString(w, fmt.Sprintf("/*Generated by xorm v%s %s, from %s to %s*/\n\n", - Version, time.Now().In(engine.TZLocation).Format("2006-01-02 15:04:05"), engine.dialect.DBType(), strings.ToUpper(distDBName))) - if err != nil { - return err - } - - for i, table := range tables { - if i > 0 { - _, err = io.WriteString(w, "\n") - if err != nil { - return err - } - } - _, err = io.WriteString(w, dialect.CreateTableSql(table, "", table.StoreEngine, "")+";\n") - if err != nil { - return err - } - for _, index := range table.Indexes { - _, err = io.WriteString(w, dialect.CreateIndexSql(table.Name, index)+";\n") - if err != nil { - return err - } - } - - cols := table.ColumnsSeq() - colNames := engine.dialect.Quote(strings.Join(cols, engine.dialect.Quote(", "))) - destColNames := dialect.Quote(strings.Join(cols, dialect.Quote(", "))) - - rows, err := engine.DB().Query("SELECT " + colNames + " FROM " + engine.Quote(table.Name)) - if err != nil { - return err - } - defer rows.Close() - - for rows.Next() { - dest := make([]interface{}, len(cols)) - err = rows.ScanSlice(&dest) - if err != nil { - return err - } - - _, err = io.WriteString(w, "INSERT INTO "+dialect.Quote(table.Name)+" ("+destColNames+") VALUES (") - if err != nil { - return err - } - - var temp string - for i, d := range dest { - col := table.GetColumn(cols[i]) - if col == nil { - return errors.New("unknow column error") - } - - if d == nil { - temp += ", NULL" - } else if col.SQLType.IsText() || col.SQLType.IsTime() { - var v = fmt.Sprintf("%s", d) - if strings.HasSuffix(v, " +0000 UTC") { - temp += fmt.Sprintf(", '%s'", v[0:len(v)-len(" +0000 UTC")]) - } else { - temp += ", '" + strings.Replace(v, "'", "''", -1) + "'" - } - } else if col.SQLType.IsBlob() { - if reflect.TypeOf(d).Kind() == reflect.Slice { - temp += fmt.Sprintf(", %s", dialect.FormatBytes(d.([]byte))) - } else if reflect.TypeOf(d).Kind() == reflect.String { - temp += fmt.Sprintf(", '%s'", d.(string)) - } - } else if col.SQLType.IsNumeric() { - switch reflect.TypeOf(d).Kind() { - case reflect.Slice: - if col.SQLType.Name == core.Bool { - temp += fmt.Sprintf(", %v", strconv.FormatBool(d.([]byte)[0] != byte('0'))) - } else { - temp += fmt.Sprintf(", %s", string(d.([]byte))) - } - case reflect.Int16, reflect.Int8, reflect.Int32, reflect.Int64, reflect.Int: - if col.SQLType.Name == core.Bool { - temp += fmt.Sprintf(", %v", strconv.FormatBool(reflect.ValueOf(d).Int() > 0)) - } else { - temp += fmt.Sprintf(", %v", d) - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if col.SQLType.Name == core.Bool { - temp += fmt.Sprintf(", %v", strconv.FormatBool(reflect.ValueOf(d).Uint() > 0)) - } else { - temp += fmt.Sprintf(", %v", d) - } - default: - temp += fmt.Sprintf(", %v", d) - } - } else { - s := fmt.Sprintf("%v", d) - if strings.Contains(s, ":") || strings.Contains(s, "-") { - if strings.HasSuffix(s, " +0000 UTC") { - temp += fmt.Sprintf(", '%s'", s[0:len(s)-len(" +0000 UTC")]) - } else { - temp += fmt.Sprintf(", '%s'", s) - } - } else { - temp += fmt.Sprintf(", %s", s) - } - } - } - _, err = io.WriteString(w, temp[2:]+");\n") - if err != nil { - return err - } - } - - // FIXME: Hack for postgres - if string(dialect.DBType()) == core.POSTGRES && table.AutoIncrColumn() != nil { - _, err = io.WriteString(w, "SELECT setval('"+table.Name+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dialect.Quote(table.Name)+"), 1), false);\n") - if err != nil { - return err - } - } - } - return nil -} - -// Cascade use cascade or not -func (engine *Engine) Cascade(trueOrFalse ...bool) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Cascade(trueOrFalse...) -} - -// Where method provide a condition query -func (engine *Engine) Where(query interface{}, args ...interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Where(query, args...) -} - -// Id will be deprecated, please use ID instead -func (engine *Engine) Id(id interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Id(id) -} - -// ID method provoide a condition as (id) = ? -func (engine *Engine) ID(id interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.ID(id) -} - -// Before apply before Processor, affected bean is passed to closure arg -func (engine *Engine) Before(closures func(interface{})) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Before(closures) -} - -// After apply after insert Processor, affected bean is passed to closure arg -func (engine *Engine) After(closures func(interface{})) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.After(closures) -} - -// Charset set charset when create table, only support mysql now -func (engine *Engine) Charset(charset string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Charset(charset) -} - -// StoreEngine set store engine when create table, only support mysql now -func (engine *Engine) StoreEngine(storeEngine string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.StoreEngine(storeEngine) -} - -// Distinct use for distinct columns. Caution: when you are using cache, -// distinct will not be cached because cache system need id, -// but distinct will not provide id -func (engine *Engine) Distinct(columns ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Distinct(columns...) -} - -// Select customerize your select columns or contents -func (engine *Engine) Select(str string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Select(str) -} - -// Cols only use the parameters as select or update columns -func (engine *Engine) Cols(columns ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Cols(columns...) -} - -// AllCols indicates that all columns should be use -func (engine *Engine) AllCols() *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.AllCols() -} - -// MustCols specify some columns must use even if they are empty -func (engine *Engine) MustCols(columns ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.MustCols(columns...) -} - -// UseBool xorm automatically retrieve condition according struct, but -// if struct has bool field, it will ignore them. So use UseBool -// to tell system to do not ignore them. -// If no parameters, it will use all the bool field of struct, or -// it will use parameters's columns -func (engine *Engine) UseBool(columns ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.UseBool(columns...) -} - -// Omit only not use the parameters as select or update columns -func (engine *Engine) Omit(columns ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Omit(columns...) -} - -// Nullable set null when column is zero-value and nullable for update -func (engine *Engine) Nullable(columns ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Nullable(columns...) -} - -// In will generate "column IN (?, ?)" -func (engine *Engine) In(column string, args ...interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.In(column, args...) -} - -// NotIn will generate "column NOT IN (?, ?)" -func (engine *Engine) NotIn(column string, args ...interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.NotIn(column, args...) -} - -// Incr provides a update string like "column = column + ?" -func (engine *Engine) Incr(column string, arg ...interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Incr(column, arg...) -} - -// Decr provides a update string like "column = column - ?" -func (engine *Engine) Decr(column string, arg ...interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Decr(column, arg...) -} - -// SetExpr provides a update string like "column = {expression}" -func (engine *Engine) SetExpr(column string, expression interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.SetExpr(column, expression) -} - -// Table temporarily change the Get, Find, Update's table -func (engine *Engine) Table(tableNameOrBean interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Table(tableNameOrBean) -} - -// Alias set the table alias -func (engine *Engine) Alias(alias string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Alias(alias) -} - -// Limit will generate "LIMIT start, limit" -func (engine *Engine) Limit(limit int, start ...int) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Limit(limit, start...) -} - -// Desc will generate "ORDER BY column1 DESC, column2 DESC" -func (engine *Engine) Desc(colNames ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Desc(colNames...) -} - -// Asc will generate "ORDER BY column1,column2 Asc" -// This method can chainable use. -// -// engine.Desc("name").Asc("age").Find(&users) -// // SELECT * FROM user ORDER BY name DESC, age ASC -// -func (engine *Engine) Asc(colNames ...string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Asc(colNames...) -} - -// OrderBy will generate "ORDER BY order" -func (engine *Engine) OrderBy(order string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.OrderBy(order) -} - -// Prepare enables prepare statement -func (engine *Engine) Prepare() *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Prepare() -} - -// Join the join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN -func (engine *Engine) Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Join(joinOperator, tablename, condition, args...) -} - -// GroupBy generate group by statement -func (engine *Engine) GroupBy(keys string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.GroupBy(keys) -} - -// Having generate having statement -func (engine *Engine) Having(conditions string) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Having(conditions) -} - -// UnMapType removes the datbase mapper of a type -func (engine *Engine) UnMapType(t reflect.Type) { - engine.mutex.Lock() - defer engine.mutex.Unlock() - delete(engine.Tables, t) -} - -func (engine *Engine) autoMapType(v reflect.Value) (*core.Table, error) { - t := v.Type() - engine.mutex.Lock() - defer engine.mutex.Unlock() - table, ok := engine.Tables[t] - if !ok { - var err error - table, err = engine.mapType(v) - if err != nil { - return nil, err - } - - engine.Tables[t] = table - if engine.Cacher != nil { - if v.CanAddr() { - engine.GobRegister(v.Addr().Interface()) - } else { - engine.GobRegister(v.Interface()) - } - } - } - return table, nil -} - -// GobRegister register one struct to gob for cache use -func (engine *Engine) GobRegister(v interface{}) *Engine { - gob.Register(v) - return engine -} - -// Table table struct -type Table struct { - *core.Table - Name string -} - -// IsValid if table is valid -func (t *Table) IsValid() bool { - return t.Table != nil && len(t.Name) > 0 -} - -// TableInfo get table info according to bean's content -func (engine *Engine) TableInfo(bean interface{}) *Table { - v := rValue(bean) - tb, err := engine.autoMapType(v) - if err != nil { - engine.logger.Error(err) - } - return &Table{tb, engine.TableName(bean)} -} - -func addIndex(indexName string, table *core.Table, col *core.Column, indexType int) { - if index, ok := table.Indexes[indexName]; ok { - index.AddColumn(col.Name) - col.Indexes[index.Name] = indexType - } else { - index := core.NewIndex(indexName, indexType) - index.AddColumn(col.Name) - table.AddIndex(index) - col.Indexes[index.Name] = indexType - } -} - -// TableName table name interface to define customerize table name -type TableName interface { - TableName() string -} - -var ( - tpTableName = reflect.TypeOf((*TableName)(nil)).Elem() -) - -func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) { - t := v.Type() - table := core.NewEmptyTable() - table.Type = t - table.Name = engine.tbNameForMap(v) - - var idFieldColName string - var hasCacheTag, hasNoCacheTag bool - - for i := 0; i < t.NumField(); i++ { - tag := t.Field(i).Tag - - ormTagStr := tag.Get(engine.TagIdentifier) - var col *core.Column - fieldValue := v.Field(i) - fieldType := fieldValue.Type() - - if ormTagStr != "" { - col = &core.Column{ - FieldName: t.Field(i).Name, - Nullable: true, - IsPrimaryKey: false, - IsAutoIncrement: false, - MapType: core.TWOSIDES, - Indexes: make(map[string]int), - DefaultIsEmpty: true, - } - tags := splitTag(ormTagStr) - - if len(tags) > 0 { - if tags[0] == "-" { - continue - } - - var ctx = tagContext{ - table: table, - col: col, - fieldValue: fieldValue, - indexNames: make(map[string]int), - engine: engine, - } - - if strings.HasPrefix(strings.ToUpper(tags[0]), "EXTENDS") { - pStart := strings.Index(tags[0], "(") - if pStart > -1 && strings.HasSuffix(tags[0], ")") { - var tagPrefix = strings.TrimFunc(tags[0][pStart+1:len(tags[0])-1], func(r rune) bool { - return r == '\'' || r == '"' - }) - - ctx.params = []string{tagPrefix} - } - - if err := ExtendsTagHandler(&ctx); err != nil { - return nil, err - } - continue - } - - for j, key := range tags { - if ctx.ignoreNext { - ctx.ignoreNext = false - continue - } - - k := strings.ToUpper(key) - ctx.tagName = k - ctx.params = []string{} - - pStart := strings.Index(k, "(") - if pStart == 0 { - return nil, errors.New("( could not be the first charactor") - } - if pStart > -1 { - if !strings.HasSuffix(k, ")") { - return nil, fmt.Errorf("field %s tag %s cannot match ) charactor", col.FieldName, key) - } - - ctx.tagName = k[:pStart] - ctx.params = strings.Split(key[pStart+1:len(k)-1], ",") - } - - if j > 0 { - ctx.preTag = strings.ToUpper(tags[j-1]) - } - if j < len(tags)-1 { - ctx.nextTag = tags[j+1] - } else { - ctx.nextTag = "" - } - - if h, ok := engine.tagHandlers[ctx.tagName]; ok { - if err := h(&ctx); err != nil { - return nil, err - } - } else { - if strings.HasPrefix(key, "'") && strings.HasSuffix(key, "'") { - col.Name = key[1 : len(key)-1] - } else { - col.Name = key - } - } - - if ctx.hasCacheTag { - hasCacheTag = true - } - if ctx.hasNoCacheTag { - hasNoCacheTag = true - } - } - - if col.SQLType.Name == "" { - col.SQLType = core.Type2SQLType(fieldType) - } - engine.dialect.SqlType(col) - if col.Length == 0 { - col.Length = col.SQLType.DefaultLength - } - if col.Length2 == 0 { - col.Length2 = col.SQLType.DefaultLength2 - } - if col.Name == "" { - col.Name = engine.ColumnMapper.Obj2Table(t.Field(i).Name) - } - - if ctx.isUnique { - ctx.indexNames[col.Name] = core.UniqueType - } else if ctx.isIndex { - ctx.indexNames[col.Name] = core.IndexType - } - - for indexName, indexType := range ctx.indexNames { - addIndex(indexName, table, col, indexType) - } - } - } else { - var sqlType core.SQLType - if fieldValue.CanAddr() { - if _, ok := fieldValue.Addr().Interface().(core.Conversion); ok { - sqlType = core.SQLType{Name: core.Text} - } - } - if _, ok := fieldValue.Interface().(core.Conversion); ok { - sqlType = core.SQLType{Name: core.Text} - } else { - sqlType = core.Type2SQLType(fieldType) - } - col = core.NewColumn(engine.ColumnMapper.Obj2Table(t.Field(i).Name), - t.Field(i).Name, sqlType, sqlType.DefaultLength, - sqlType.DefaultLength2, true) - - if fieldType.Kind() == reflect.Int64 && (strings.ToUpper(col.FieldName) == "ID" || strings.HasSuffix(strings.ToUpper(col.FieldName), ".ID")) { - idFieldColName = col.Name - } - } - if col.IsAutoIncrement { - col.Nullable = false - } - - table.AddColumn(col) - - } // end for - - if idFieldColName != "" && len(table.PrimaryKeys) == 0 { - col := table.GetColumn(idFieldColName) - col.IsPrimaryKey = true - col.IsAutoIncrement = true - col.Nullable = false - table.PrimaryKeys = append(table.PrimaryKeys, col.Name) - table.AutoIncrement = col.Name - } - - if hasCacheTag { - if engine.Cacher != nil { // !nash! use engine's cacher if provided - engine.logger.Info("enable cache on table:", table.Name) - engine.setCacher(table.Name, engine.Cacher) - } else { - engine.logger.Info("enable LRU cache on table:", table.Name) - engine.setCacher(table.Name, NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)) - } - } - if hasNoCacheTag { - engine.logger.Info("disable cache on table:", table.Name) - engine.setCacher(table.Name, nil) - } - - return table, nil -} - -// IsTableEmpty if a table has any reocrd -func (engine *Engine) IsTableEmpty(bean interface{}) (bool, error) { - session := engine.NewSession() - defer session.Close() - return session.IsTableEmpty(bean) -} - -// IsTableExist if a table is exist -func (engine *Engine) IsTableExist(beanOrTableName interface{}) (bool, error) { - session := engine.NewSession() - defer session.Close() - return session.IsTableExist(beanOrTableName) -} - -// IdOf get id from one struct -// -// Deprecated: use IDOf instead. -func (engine *Engine) IdOf(bean interface{}) core.PK { - return engine.IDOf(bean) -} - -// IDOf get id from one struct -func (engine *Engine) IDOf(bean interface{}) core.PK { - return engine.IdOfV(reflect.ValueOf(bean)) -} - -// IdOfV get id from one value of struct -// -// Deprecated: use IDOfV instead. -func (engine *Engine) IdOfV(rv reflect.Value) core.PK { - return engine.IDOfV(rv) -} - -// IDOfV get id from one value of struct -func (engine *Engine) IDOfV(rv reflect.Value) core.PK { - pk, err := engine.idOfV(rv) - if err != nil { - engine.logger.Error(err) - return nil - } - return pk -} - -func (engine *Engine) idOfV(rv reflect.Value) (core.PK, error) { - v := reflect.Indirect(rv) - table, err := engine.autoMapType(v) - if err != nil { - return nil, err - } - - pk := make([]interface{}, len(table.PrimaryKeys)) - for i, col := range table.PKColumns() { - var err error - - fieldName := col.FieldName - for { - parts := strings.SplitN(fieldName, ".", 2) - if len(parts) == 1 { - break - } - - v = v.FieldByName(parts[0]) - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if v.Kind() != reflect.Struct { - return nil, ErrUnSupportedType - } - fieldName = parts[1] - } - - pkField := v.FieldByName(fieldName) - switch pkField.Kind() { - case reflect.String: - pk[i], err = engine.idTypeAssertion(col, pkField.String()) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - pk[i], err = engine.idTypeAssertion(col, strconv.FormatInt(pkField.Int(), 10)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - // id of uint will be converted to int64 - pk[i], err = engine.idTypeAssertion(col, strconv.FormatUint(pkField.Uint(), 10)) - } - - if err != nil { - return nil, err - } - } - return core.PK(pk), nil -} - -func (engine *Engine) idTypeAssertion(col *core.Column, sid string) (interface{}, error) { - if col.SQLType.IsNumeric() { - n, err := strconv.ParseInt(sid, 10, 64) - if err != nil { - return nil, err - } - return n, nil - } else if col.SQLType.IsText() { - return sid, nil - } else { - return nil, errors.New("not supported") - } -} - -// CreateIndexes create indexes -func (engine *Engine) CreateIndexes(bean interface{}) error { - session := engine.NewSession() - defer session.Close() - return session.CreateIndexes(bean) -} - -// CreateUniques create uniques -func (engine *Engine) CreateUniques(bean interface{}) error { - session := engine.NewSession() - defer session.Close() - return session.CreateUniques(bean) -} - -// ClearCacheBean if enabled cache, clear the cache bean -func (engine *Engine) ClearCacheBean(bean interface{}, id string) error { - tableName := engine.TableName(bean) - cacher := engine.getCacher(tableName) - if cacher != nil { - cacher.ClearIds(tableName) - cacher.DelBean(tableName, id) - } - return nil -} - -// ClearCache if enabled cache, clear some tables' cache -func (engine *Engine) ClearCache(beans ...interface{}) error { - for _, bean := range beans { - tableName := engine.TableName(bean) - cacher := engine.getCacher(tableName) - if cacher != nil { - cacher.ClearIds(tableName) - cacher.ClearBeans(tableName) - } - } - return nil -} - -// Sync the new struct changes to database, this method will automatically add -// table, column, index, unique. but will not delete or change anything. -// If you change some field, you should change the database manually. -func (engine *Engine) Sync(beans ...interface{}) error { - session := engine.NewSession() - defer session.Close() - - for _, bean := range beans { - v := rValue(bean) - tableNameNoSchema := engine.TableName(bean) - table, err := engine.autoMapType(v) - if err != nil { - return err - } - - isExist, err := session.Table(bean).isTableExist(tableNameNoSchema) - if err != nil { - return err - } - if !isExist { - err = session.createTable(bean) - if err != nil { - return err - } - } - /*isEmpty, err := engine.IsEmptyTable(bean) - if err != nil { - return err - }*/ - var isEmpty bool - if isEmpty { - err = session.dropTable(bean) - if err != nil { - return err - } - err = session.createTable(bean) - if err != nil { - return err - } - } else { - for _, col := range table.Columns() { - isExist, err := engine.dialect.IsColumnExist(tableNameNoSchema, col.Name) - if err != nil { - return err - } - if !isExist { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - err = session.addColumn(col.Name) - if err != nil { - return err - } - } - } - - for name, index := range table.Indexes { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - if index.Type == core.UniqueType { - isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, true) - if err != nil { - return err - } - if !isExist { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - - err = session.addUnique(tableNameNoSchema, name) - if err != nil { - return err - } - } - } else if index.Type == core.IndexType { - isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, false) - if err != nil { - return err - } - if !isExist { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - - err = session.addIndex(tableNameNoSchema, name) - if err != nil { - return err - } - } - } else { - return errors.New("unknow index type") - } - } - } - } - return nil -} - -// Sync2 synchronize structs to database tables -func (engine *Engine) Sync2(beans ...interface{}) error { - s := engine.NewSession() - defer s.Close() - return s.Sync2(beans...) -} - -// CreateTables create tabls according bean -func (engine *Engine) CreateTables(beans ...interface{}) error { - session := engine.NewSession() - defer session.Close() - - err := session.Begin() - if err != nil { - return err - } - - for _, bean := range beans { - err = session.createTable(bean) - if err != nil { - session.Rollback() - return err - } - } - return session.Commit() -} - -// DropTables drop specify tables -func (engine *Engine) DropTables(beans ...interface{}) error { - session := engine.NewSession() - defer session.Close() - - err := session.Begin() - if err != nil { - return err - } - - for _, bean := range beans { - err = session.dropTable(bean) - if err != nil { - session.Rollback() - return err - } - } - return session.Commit() -} - -// DropIndexes drop indexes of a table -func (engine *Engine) DropIndexes(bean interface{}) error { - session := engine.NewSession() - defer session.Close() - return session.DropIndexes(bean) -} - -// Exec raw sql -func (engine *Engine) Exec(sqlOrArgs ...interface{}) (sql.Result, error) { - session := engine.NewSession() - defer session.Close() - return session.Exec(sqlOrArgs...) -} - -// Query a raw sql and return records as []map[string][]byte -func (engine *Engine) Query(sqlOrArgs ...interface{}) (resultsSlice []map[string][]byte, err error) { - session := engine.NewSession() - defer session.Close() - return session.Query(sqlOrArgs...) -} - -// QueryString runs a raw sql and return records as []map[string]string -func (engine *Engine) QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) { - session := engine.NewSession() - defer session.Close() - return session.QueryString(sqlOrArgs...) -} - -// QueryInterface runs a raw sql and return records as []map[string]interface{} -func (engine *Engine) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) { - session := engine.NewSession() - defer session.Close() - return session.QueryInterface(sqlOrArgs...) -} - -// Insert one or more records -func (engine *Engine) Insert(beans ...interface{}) (int64, error) { - session := engine.NewSession() - defer session.Close() - return session.Insert(beans...) -} - -// InsertOne insert only one record -func (engine *Engine) InsertOne(bean interface{}) (int64, error) { - session := engine.NewSession() - defer session.Close() - return session.InsertOne(bean) -} - -// Update records, bean's non-empty fields are updated contents, -// condiBean' non-empty filds are conditions -// CAUTION: -// 1.bool will defaultly be updated content nor conditions -// You should call UseBool if you have bool to use. -// 2.float32 & float64 may be not inexact as conditions -func (engine *Engine) Update(bean interface{}, condiBeans ...interface{}) (int64, error) { - session := engine.NewSession() - defer session.Close() - return session.Update(bean, condiBeans...) -} - -// Delete records, bean's non-empty fields are conditions -func (engine *Engine) Delete(bean interface{}) (int64, error) { - session := engine.NewSession() - defer session.Close() - return session.Delete(bean) -} - -// Get retrieve one record from table, bean's non-empty fields -// are conditions -func (engine *Engine) Get(bean interface{}) (bool, error) { - session := engine.NewSession() - defer session.Close() - return session.Get(bean) -} - -// Exist returns true if the record exist otherwise return false -func (engine *Engine) Exist(bean ...interface{}) (bool, error) { - session := engine.NewSession() - defer session.Close() - return session.Exist(bean...) -} - -// Find retrieve records from table, condiBeans's non-empty fields -// are conditions. beans could be []Struct, []*Struct, map[int64]Struct -// map[int64]*Struct -func (engine *Engine) Find(beans interface{}, condiBeans ...interface{}) error { - session := engine.NewSession() - defer session.Close() - return session.Find(beans, condiBeans...) -} - -// FindAndCount find the results and also return the counts -func (engine *Engine) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { - session := engine.NewSession() - defer session.Close() - return session.FindAndCount(rowsSlicePtr, condiBean...) -} - -// Iterate record by record handle records from table, bean's non-empty fields -// are conditions. -func (engine *Engine) Iterate(bean interface{}, fun IterFunc) error { - session := engine.NewSession() - defer session.Close() - return session.Iterate(bean, fun) -} - -// Rows return sql.Rows compatible Rows obj, as a forward Iterator object for iterating record by record, bean's non-empty fields -// are conditions. -func (engine *Engine) Rows(bean interface{}) (*Rows, error) { - session := engine.NewSession() - return session.Rows(bean) -} - -// Count counts the records. bean's non-empty fields are conditions. -func (engine *Engine) Count(bean ...interface{}) (int64, error) { - session := engine.NewSession() - defer session.Close() - return session.Count(bean...) -} - -// Sum sum the records by some column. bean's non-empty fields are conditions. -func (engine *Engine) Sum(bean interface{}, colName string) (float64, error) { - session := engine.NewSession() - defer session.Close() - return session.Sum(bean, colName) -} - -// SumInt sum the records by some column. bean's non-empty fields are conditions. -func (engine *Engine) SumInt(bean interface{}, colName string) (int64, error) { - session := engine.NewSession() - defer session.Close() - return session.SumInt(bean, colName) -} - -// Sums sum the records by some columns. bean's non-empty fields are conditions. -func (engine *Engine) Sums(bean interface{}, colNames ...string) ([]float64, error) { - session := engine.NewSession() - defer session.Close() - return session.Sums(bean, colNames...) -} - -// SumsInt like Sums but return slice of int64 instead of float64. -func (engine *Engine) SumsInt(bean interface{}, colNames ...string) ([]int64, error) { - session := engine.NewSession() - defer session.Close() - return session.SumsInt(bean, colNames...) -} - -// ImportFile SQL DDL file -func (engine *Engine) ImportFile(ddlPath string) ([]sql.Result, error) { - file, err := os.Open(ddlPath) - if err != nil { - return nil, err - } - defer file.Close() - return engine.Import(file) -} - -// Import SQL DDL from io.Reader -func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) { - var results []sql.Result - var lastError error - scanner := bufio.NewScanner(r) - - semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) { - if atEOF && len(data) == 0 { - return 0, nil, nil - } - if i := bytes.IndexByte(data, ';'); i >= 0 { - return i + 1, data[0:i], nil - } - // If we're at EOF, we have a final, non-terminated line. Return it. - if atEOF { - return len(data), data, nil - } - // Request more data. - return 0, nil, nil - } - - scanner.Split(semiColSpliter) - - for scanner.Scan() { - query := strings.Trim(scanner.Text(), " \t\n\r") - if len(query) > 0 { - engine.logSQL(query) - result, err := engine.DB().Exec(query) - results = append(results, result) - if err != nil { - return nil, err - } - } - } - - return results, lastError -} - -// nowTime return current time -func (engine *Engine) nowTime(col *core.Column) (interface{}, time.Time) { - t := time.Now() - var tz = engine.DatabaseTZ - if !col.DisableTimeZone && col.TimeZone != nil { - tz = col.TimeZone - } - return engine.formatTime(col.SQLType.Name, t.In(tz)), t.In(engine.TZLocation) -} - -func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{}) { - if t.IsZero() { - if col.Nullable { - return nil - } - return "" - } - - if col.TimeZone != nil { - return engine.formatTime(col.SQLType.Name, t.In(col.TimeZone)) - } - return engine.formatTime(col.SQLType.Name, t.In(engine.DatabaseTZ)) -} - -// formatTime format time as column type -func (engine *Engine) formatTime(sqlTypeName string, t time.Time) (v interface{}) { - switch sqlTypeName { - case core.Time: - s := t.Format("2006-01-02 15:04:05") // time.RFC3339 - v = s[11:19] - case core.Date: - v = t.Format("2006-01-02") - case core.DateTime, core.TimeStamp: - v = t.Format("2006-01-02 15:04:05") - case core.TimeStampz: - if engine.dialect.DBType() == core.MSSQL { - v = t.Format("2006-01-02T15:04:05.9999999Z07:00") - } else { - v = t.Format(time.RFC3339Nano) - } - case core.BigInt, core.Int: - v = t.Unix() - default: - v = t - } - return -} - -// GetColumnMapper returns the column name mapper -func (engine *Engine) GetColumnMapper() core.IMapper { - return engine.ColumnMapper -} - -// GetTableMapper returns the table name mapper -func (engine *Engine) GetTableMapper() core.IMapper { - return engine.TableMapper -} - -// GetTZLocation returns time zone of the application -func (engine *Engine) GetTZLocation() *time.Location { - return engine.TZLocation -} - -// SetTZLocation sets time zone of the application -func (engine *Engine) SetTZLocation(tz *time.Location) { - engine.TZLocation = tz -} - -// GetTZDatabase returns time zone of the database -func (engine *Engine) GetTZDatabase() *time.Location { - return engine.DatabaseTZ -} - -// SetTZDatabase sets time zone of the database -func (engine *Engine) SetTZDatabase(tz *time.Location) { - engine.DatabaseTZ = tz -} - -// SetSchema sets the schema of database -func (engine *Engine) SetSchema(schema string) { - engine.dialect.URI().Schema = schema -} - -// Unscoped always disable struct tag "deleted" -func (engine *Engine) Unscoped() *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Unscoped() -} diff --git a/vendor/github.com/go-xorm/xorm/engine_cond.go b/vendor/github.com/go-xorm/xorm/engine_cond.go deleted file mode 100644 index 702ac80434..0000000000 --- a/vendor/github.com/go-xorm/xorm/engine_cond.go +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql/driver" - "fmt" - "reflect" - "strings" - "time" - - "xorm.io/builder" - "xorm.io/core" -) - -func (engine *Engine) buildConds(table *core.Table, bean interface{}, - includeVersion bool, includeUpdated bool, includeNil bool, - includeAutoIncr bool, allUseBool bool, useAllCols bool, unscoped bool, - mustColumnMap map[string]bool, tableName, aliasName string, addedTableName bool) (builder.Cond, error) { - var conds []builder.Cond - for _, col := range table.Columns() { - if !includeVersion && col.IsVersion { - continue - } - if !includeUpdated && col.IsUpdated { - continue - } - if !includeAutoIncr && col.IsAutoIncrement { - continue - } - - if engine.dialect.DBType() == core.MSSQL && (col.SQLType.Name == core.Text || col.SQLType.IsBlob() || col.SQLType.Name == core.TimeStampz) { - continue - } - if col.SQLType.IsJson() { - continue - } - - var colName string - if addedTableName { - var nm = tableName - if len(aliasName) > 0 { - nm = aliasName - } - colName = engine.Quote(nm) + "." + engine.Quote(col.Name) - } else { - colName = engine.Quote(col.Name) - } - - fieldValuePtr, err := col.ValueOf(bean) - if err != nil { - if !strings.Contains(err.Error(), "is not valid") { - engine.logger.Warn(err) - } - continue - } - - if col.IsDeleted && !unscoped { // tag "deleted" is enabled - conds = append(conds, engine.CondDeleted(colName)) - } - - fieldValue := *fieldValuePtr - if fieldValue.Interface() == nil { - continue - } - - fieldType := reflect.TypeOf(fieldValue.Interface()) - requiredField := useAllCols - - if b, ok := getFlagForColumn(mustColumnMap, col); ok { - if b { - requiredField = true - } else { - continue - } - } - - if fieldType.Kind() == reflect.Ptr { - if fieldValue.IsNil() { - if includeNil { - conds = append(conds, builder.Eq{colName: nil}) - } - continue - } else if !fieldValue.IsValid() { - continue - } else { - // dereference ptr type to instance type - fieldValue = fieldValue.Elem() - fieldType = reflect.TypeOf(fieldValue.Interface()) - requiredField = true - } - } - - var val interface{} - switch fieldType.Kind() { - case reflect.Bool: - if allUseBool || requiredField { - val = fieldValue.Interface() - } else { - // if a bool in a struct, it will not be as a condition because it default is false, - // please use Where() instead - continue - } - case reflect.String: - if !requiredField && fieldValue.String() == "" { - continue - } - // for MyString, should convert to string or panic - if fieldType.String() != reflect.String.String() { - val = fieldValue.String() - } else { - val = fieldValue.Interface() - } - case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64: - if !requiredField && fieldValue.Int() == 0 { - continue - } - val = fieldValue.Interface() - case reflect.Float32, reflect.Float64: - if !requiredField && fieldValue.Float() == 0.0 { - continue - } - val = fieldValue.Interface() - case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64: - if !requiredField && fieldValue.Uint() == 0 { - continue - } - t := int64(fieldValue.Uint()) - val = reflect.ValueOf(&t).Interface() - case reflect.Struct: - if fieldType.ConvertibleTo(core.TimeType) { - t := fieldValue.Convert(core.TimeType).Interface().(time.Time) - if !requiredField && (t.IsZero() || !fieldValue.IsValid()) { - continue - } - val = engine.formatColTime(col, t) - } else if _, ok := reflect.New(fieldType).Interface().(core.Conversion); ok { - continue - } else if valNul, ok := fieldValue.Interface().(driver.Valuer); ok { - val, _ = valNul.Value() - if val == nil { - continue - } - } else { - if col.SQLType.IsJson() { - if col.SQLType.IsText() { - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - engine.logger.Error(err) - continue - } - val = string(bytes) - } else if col.SQLType.IsBlob() { - var bytes []byte - var err error - bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - engine.logger.Error(err) - continue - } - val = bytes - } - } else { - engine.autoMapType(fieldValue) - if table, ok := engine.Tables[fieldValue.Type()]; ok { - if len(table.PrimaryKeys) == 1 { - pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName) - // fix non-int pk issues - //if pkField.Int() != 0 { - if pkField.IsValid() && !isZero(pkField.Interface()) { - val = pkField.Interface() - } else { - continue - } - } else { - //TODO: how to handler? - return nil, fmt.Errorf("not supported %v as %v", fieldValue.Interface(), table.PrimaryKeys) - } - } else { - val = fieldValue.Interface() - } - } - } - case reflect.Array: - continue - case reflect.Slice, reflect.Map: - if fieldValue == reflect.Zero(fieldType) { - continue - } - if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 { - continue - } - - if col.SQLType.IsText() { - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - engine.logger.Error(err) - continue - } - val = string(bytes) - } else if col.SQLType.IsBlob() { - var bytes []byte - var err error - if (fieldType.Kind() == reflect.Array || fieldType.Kind() == reflect.Slice) && - fieldType.Elem().Kind() == reflect.Uint8 { - if fieldValue.Len() > 0 { - val = fieldValue.Bytes() - } else { - continue - } - } else { - bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - engine.logger.Error(err) - continue - } - val = bytes - } - } else { - continue - } - default: - val = fieldValue.Interface() - } - - conds = append(conds, builder.Eq{colName: val}) - } - - return builder.And(conds...), nil -} diff --git a/vendor/github.com/go-xorm/xorm/engine_context.go b/vendor/github.com/go-xorm/xorm/engine_context.go deleted file mode 100644 index c6cbb76c1d..0000000000 --- a/vendor/github.com/go-xorm/xorm/engine_context.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package xorm - -import "context" - -// Context creates a session with the context -func (engine *Engine) Context(ctx context.Context) *Session { - session := engine.NewSession() - session.isAutoClose = true - return session.Context(ctx) -} - -// SetDefaultContext set the default context -func (engine *Engine) SetDefaultContext(ctx context.Context) { - engine.defaultContext = ctx -} - -// PingContext tests if database is alive -func (engine *Engine) PingContext(ctx context.Context) error { - session := engine.NewSession() - defer session.Close() - return session.PingContext(ctx) -} diff --git a/vendor/github.com/go-xorm/xorm/engine_group.go b/vendor/github.com/go-xorm/xorm/engine_group.go deleted file mode 100644 index 42d49eca93..0000000000 --- a/vendor/github.com/go-xorm/xorm/engine_group.go +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "context" - "time" - - "xorm.io/core" -) - -// EngineGroup defines an engine group -type EngineGroup struct { - *Engine - slaves []*Engine - policy GroupPolicy -} - -// NewEngineGroup creates a new engine group -func NewEngineGroup(args1 interface{}, args2 interface{}, policies ...GroupPolicy) (*EngineGroup, error) { - var eg EngineGroup - if len(policies) > 0 { - eg.policy = policies[0] - } else { - eg.policy = RoundRobinPolicy() - } - - driverName, ok1 := args1.(string) - conns, ok2 := args2.([]string) - if ok1 && ok2 { - engines := make([]*Engine, len(conns)) - for i, conn := range conns { - engine, err := NewEngine(driverName, conn) - if err != nil { - return nil, err - } - engine.engineGroup = &eg - engines[i] = engine - } - - eg.Engine = engines[0] - eg.slaves = engines[1:] - return &eg, nil - } - - master, ok3 := args1.(*Engine) - slaves, ok4 := args2.([]*Engine) - if ok3 && ok4 { - master.engineGroup = &eg - for i := 0; i < len(slaves); i++ { - slaves[i].engineGroup = &eg - } - eg.Engine = master - eg.slaves = slaves - return &eg, nil - } - return nil, ErrParamsType -} - -// Close the engine -func (eg *EngineGroup) Close() error { - err := eg.Engine.Close() - if err != nil { - return err - } - - for i := 0; i < len(eg.slaves); i++ { - err := eg.slaves[i].Close() - if err != nil { - return err - } - } - return nil -} - -// Context returned a group session -func (eg *EngineGroup) Context(ctx context.Context) *Session { - sess := eg.NewSession() - sess.isAutoClose = true - return sess.Context(ctx) -} - -// NewSession returned a group session -func (eg *EngineGroup) NewSession() *Session { - sess := eg.Engine.NewSession() - sess.sessionType = groupSession - return sess -} - -// Master returns the master engine -func (eg *EngineGroup) Master() *Engine { - return eg.Engine -} - -// Ping tests if database is alive -func (eg *EngineGroup) Ping() error { - if err := eg.Engine.Ping(); err != nil { - return err - } - - for _, slave := range eg.slaves { - if err := slave.Ping(); err != nil { - return err - } - } - return nil -} - -// SetColumnMapper set the column name mapping rule -func (eg *EngineGroup) SetColumnMapper(mapper core.IMapper) { - eg.Engine.ColumnMapper = mapper - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].ColumnMapper = mapper - } -} - -// SetConnMaxLifetime sets the maximum amount of time a connection may be reused. -func (eg *EngineGroup) SetConnMaxLifetime(d time.Duration) { - eg.Engine.SetConnMaxLifetime(d) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].SetConnMaxLifetime(d) - } -} - -// SetDefaultCacher set the default cacher -func (eg *EngineGroup) SetDefaultCacher(cacher core.Cacher) { - eg.Engine.SetDefaultCacher(cacher) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].SetDefaultCacher(cacher) - } -} - -// SetLogger set the new logger -func (eg *EngineGroup) SetLogger(logger core.ILogger) { - eg.Engine.SetLogger(logger) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].SetLogger(logger) - } -} - -// SetLogLevel sets the logger level -func (eg *EngineGroup) SetLogLevel(level core.LogLevel) { - eg.Engine.SetLogLevel(level) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].SetLogLevel(level) - } -} - -// SetMapper set the name mapping rules -func (eg *EngineGroup) SetMapper(mapper core.IMapper) { - eg.Engine.SetMapper(mapper) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].SetMapper(mapper) - } -} - -// SetMaxIdleConns set the max idle connections on pool, default is 2 -func (eg *EngineGroup) SetMaxIdleConns(conns int) { - eg.Engine.db.SetMaxIdleConns(conns) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].db.SetMaxIdleConns(conns) - } -} - -// SetMaxOpenConns is only available for go 1.2+ -func (eg *EngineGroup) SetMaxOpenConns(conns int) { - eg.Engine.db.SetMaxOpenConns(conns) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].db.SetMaxOpenConns(conns) - } -} - -// SetPolicy set the group policy -func (eg *EngineGroup) SetPolicy(policy GroupPolicy) *EngineGroup { - eg.policy = policy - return eg -} - -// SetTableMapper set the table name mapping rule -func (eg *EngineGroup) SetTableMapper(mapper core.IMapper) { - eg.Engine.TableMapper = mapper - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].TableMapper = mapper - } -} - -// ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO -func (eg *EngineGroup) ShowExecTime(show ...bool) { - eg.Engine.ShowExecTime(show...) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].ShowExecTime(show...) - } -} - -// ShowSQL show SQL statement or not on logger if log level is great than INFO -func (eg *EngineGroup) ShowSQL(show ...bool) { - eg.Engine.ShowSQL(show...) - for i := 0; i < len(eg.slaves); i++ { - eg.slaves[i].ShowSQL(show...) - } -} - -// Slave returns one of the physical databases which is a slave according the policy -func (eg *EngineGroup) Slave() *Engine { - switch len(eg.slaves) { - case 0: - return eg.Engine - case 1: - return eg.slaves[0] - } - return eg.policy.Slave(eg) -} - -// Slaves returns all the slaves -func (eg *EngineGroup) Slaves() []*Engine { - return eg.slaves -} diff --git a/vendor/github.com/go-xorm/xorm/engine_group_policy.go b/vendor/github.com/go-xorm/xorm/engine_group_policy.go deleted file mode 100644 index 5b56e8995f..0000000000 --- a/vendor/github.com/go-xorm/xorm/engine_group_policy.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "math/rand" - "sync" - "time" -) - -// GroupPolicy is be used by chosing the current slave from slaves -type GroupPolicy interface { - Slave(*EngineGroup) *Engine -} - -// GroupPolicyHandler should be used when a function is a GroupPolicy -type GroupPolicyHandler func(*EngineGroup) *Engine - -// Slave implements the chosen of slaves -func (h GroupPolicyHandler) Slave(eg *EngineGroup) *Engine { - return h(eg) -} - -// RandomPolicy implmentes randomly chose the slave of slaves -func RandomPolicy() GroupPolicyHandler { - var r = rand.New(rand.NewSource(time.Now().UnixNano())) - return func(g *EngineGroup) *Engine { - return g.Slaves()[r.Intn(len(g.Slaves()))] - } -} - -// WeightRandomPolicy implmentes randomly chose the slave of slaves -func WeightRandomPolicy(weights []int) GroupPolicyHandler { - var rands = make([]int, 0, len(weights)) - for i := 0; i < len(weights); i++ { - for n := 0; n < weights[i]; n++ { - rands = append(rands, i) - } - } - var r = rand.New(rand.NewSource(time.Now().UnixNano())) - - return func(g *EngineGroup) *Engine { - var slaves = g.Slaves() - idx := rands[r.Intn(len(rands))] - if idx >= len(slaves) { - idx = len(slaves) - 1 - } - return slaves[idx] - } -} - -func RoundRobinPolicy() GroupPolicyHandler { - var pos = -1 - var lock sync.Mutex - return func(g *EngineGroup) *Engine { - var slaves = g.Slaves() - - lock.Lock() - defer lock.Unlock() - pos++ - if pos >= len(slaves) { - pos = 0 - } - - return slaves[pos] - } -} - -func WeightRoundRobinPolicy(weights []int) GroupPolicyHandler { - var rands = make([]int, 0, len(weights)) - for i := 0; i < len(weights); i++ { - for n := 0; n < weights[i]; n++ { - rands = append(rands, i) - } - } - var pos = -1 - var lock sync.Mutex - - return func(g *EngineGroup) *Engine { - var slaves = g.Slaves() - lock.Lock() - defer lock.Unlock() - pos++ - if pos >= len(rands) { - pos = 0 - } - - idx := rands[pos] - if idx >= len(slaves) { - idx = len(slaves) - 1 - } - return slaves[idx] - } -} - -// LeastConnPolicy implements GroupPolicy, every time will get the least connections slave -func LeastConnPolicy() GroupPolicyHandler { - return func(g *EngineGroup) *Engine { - var slaves = g.Slaves() - connections := 0 - idx := 0 - for i := 0; i < len(slaves); i++ { - openConnections := slaves[i].DB().Stats().OpenConnections - if i == 0 { - connections = openConnections - idx = i - } else if openConnections <= connections { - connections = openConnections - idx = i - } - } - return slaves[idx] - } -} diff --git a/vendor/github.com/go-xorm/xorm/engine_table.go b/vendor/github.com/go-xorm/xorm/engine_table.go deleted file mode 100644 index eb5aa850af..0000000000 --- a/vendor/github.com/go-xorm/xorm/engine_table.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2018 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "fmt" - "reflect" - "strings" - - "xorm.io/core" -) - -// tbNameWithSchema will automatically add schema prefix on table name -func (engine *Engine) tbNameWithSchema(v string) string { - // Add schema name as prefix of table name. - // Only for postgres database. - if engine.dialect.DBType() == core.POSTGRES && - engine.dialect.URI().Schema != "" && - engine.dialect.URI().Schema != postgresPublicSchema && - strings.Index(v, ".") == -1 { - return engine.dialect.URI().Schema + "." + v - } - return v -} - -// TableName returns table name with schema prefix if has -func (engine *Engine) TableName(bean interface{}, includeSchema ...bool) string { - tbName := engine.tbNameNoSchema(bean) - if len(includeSchema) > 0 && includeSchema[0] { - tbName = engine.tbNameWithSchema(tbName) - } - - return tbName -} - -// tbName get some table's table name -func (session *Session) tbNameNoSchema(table *core.Table) string { - if len(session.statement.AltTableName) > 0 { - return session.statement.AltTableName - } - - return table.Name -} - -func (engine *Engine) tbNameForMap(v reflect.Value) string { - if v.Type().Implements(tpTableName) { - return v.Interface().(TableName).TableName() - } - if v.Kind() == reflect.Ptr { - v = v.Elem() - if v.Type().Implements(tpTableName) { - return v.Interface().(TableName).TableName() - } - } - - return engine.TableMapper.Obj2Table(v.Type().Name()) -} - -func (engine *Engine) tbNameNoSchema(tablename interface{}) string { - switch tablename.(type) { - case []string: - t := tablename.([]string) - if len(t) > 1 { - return fmt.Sprintf("%v AS %v", engine.Quote(t[0]), engine.Quote(t[1])) - } else if len(t) == 1 { - return engine.Quote(t[0]) - } - case []interface{}: - t := tablename.([]interface{}) - l := len(t) - var table string - if l > 0 { - f := t[0] - switch f.(type) { - case string: - table = f.(string) - case TableName: - table = f.(TableName).TableName() - default: - v := rValue(f) - t := v.Type() - if t.Kind() == reflect.Struct { - table = engine.tbNameForMap(v) - } else { - table = engine.Quote(fmt.Sprintf("%v", f)) - } - } - } - if l > 1 { - return fmt.Sprintf("%v AS %v", engine.Quote(table), - engine.Quote(fmt.Sprintf("%v", t[1]))) - } else if l == 1 { - return engine.Quote(table) - } - case TableName: - return tablename.(TableName).TableName() - case string: - return tablename.(string) - case reflect.Value: - v := tablename.(reflect.Value) - return engine.tbNameForMap(v) - default: - v := rValue(tablename) - t := v.Type() - if t.Kind() == reflect.Struct { - return engine.tbNameForMap(v) - } - return engine.Quote(fmt.Sprintf("%v", tablename)) - } - return "" -} diff --git a/vendor/github.com/go-xorm/xorm/error.go b/vendor/github.com/go-xorm/xorm/error.go deleted file mode 100644 index a67527acda..0000000000 --- a/vendor/github.com/go-xorm/xorm/error.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" -) - -var ( - // ErrParamsType params error - ErrParamsType = errors.New("Params type error") - // ErrTableNotFound table not found error - ErrTableNotFound = errors.New("Table not found") - // ErrUnSupportedType unsupported error - ErrUnSupportedType = errors.New("Unsupported type error") - // ErrNotExist record does not exist error - ErrNotExist = errors.New("Record does not exist") - // ErrCacheFailed cache failed error - ErrCacheFailed = errors.New("Cache failed") - // ErrNeedDeletedCond delete needs less one condition error - ErrNeedDeletedCond = errors.New("Delete action needs at least one condition") - // ErrNotImplemented not implemented - ErrNotImplemented = errors.New("Not implemented") - // ErrConditionType condition type unsupported - ErrConditionType = errors.New("Unsupported condition type") - // ErrUnSupportedSQLType parameter of SQL is not supported - ErrUnSupportedSQLType = errors.New("unsupported sql type") -) - -// ErrFieldIsNotExist columns does not exist -type ErrFieldIsNotExist struct { - FieldName string - TableName string -} - -func (e ErrFieldIsNotExist) Error() string { - return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName) -} - -// ErrFieldIsNotValid is not valid -type ErrFieldIsNotValid struct { - FieldName string - TableName string -} - -func (e ErrFieldIsNotValid) Error() string { - return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName) -} diff --git a/vendor/github.com/go-xorm/xorm/gen_reserved.sh b/vendor/github.com/go-xorm/xorm/gen_reserved.sh deleted file mode 100644 index 434a1bfcb0..0000000000 --- a/vendor/github.com/go-xorm/xorm/gen_reserved.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -if [ -f $1 ];then - cat $1| awk '{printf("\""$1"\":true,\n")}' -else - echo "argument $1 if not a file!" -fi diff --git a/vendor/github.com/go-xorm/xorm/go.mod b/vendor/github.com/go-xorm/xorm/go.mod deleted file mode 100644 index 1ab39831a8..0000000000 --- a/vendor/github.com/go-xorm/xorm/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module github.com/go-xorm/xorm - -go 1.11 - -require ( - github.com/cockroachdb/apd v1.1.0 // indirect - github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 - github.com/go-sql-driver/mysql v1.4.1 - github.com/gofrs/uuid v3.2.0+incompatible // indirect - github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect - github.com/jackc/pgx v3.6.0+incompatible - github.com/lib/pq v1.0.0 - github.com/mattn/go-sqlite3 v1.10.0 - github.com/pkg/errors v0.8.1 // indirect - github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect - github.com/stretchr/testify v1.4.0 - github.com/ziutek/mymysql v1.5.4 - xorm.io/builder v0.3.6 - xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb -) diff --git a/vendor/github.com/go-xorm/xorm/go.sum b/vendor/github.com/go-xorm/xorm/go.sum deleted file mode 100644 index cf637a8e06..0000000000 --- a/vendor/github.com/go-xorm/xorm/go.sum +++ /dev/null @@ -1,172 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= -cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o= -github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= -github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.6.0+incompatible h1:bJeo4JdVbDAW8KB2m8XkFeo8CPipREoG37BwEoKGz+Q= -github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= -github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= -github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw= -google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= -xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= -xorm.io/core v0.7.0 h1:hKxuOKWZNeiFQsSuGet/KV8HZ788hclvAl+7azx3tkM= -xorm.io/core v0.7.0/go.mod h1:TuOJjIVa7e3w/rN8tDcAvuLBMtwzdHPbyOzE6Gk1EUI= -xorm.io/core v0.7.1 h1:I6x6Q6dYb67aDEoYFWr2t8UcKIYjJPyCHS+aXuj5V0Y= -xorm.io/core v0.7.1/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= -xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb h1:msX3zG3BPl8Ti+LDzP33/9K7BzO/WqFXk610K1kYKfo= -xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= diff --git a/vendor/github.com/go-xorm/xorm/helpers.go b/vendor/github.com/go-xorm/xorm/helpers.go deleted file mode 100644 index a31e922c0b..0000000000 --- a/vendor/github.com/go-xorm/xorm/helpers.go +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "reflect" - "sort" - "strconv" - "strings" - - "xorm.io/core" -) - -// str2PK convert string value to primary key value according to tp -func str2PKValue(s string, tp reflect.Type) (reflect.Value, error) { - var err error - var result interface{} - var defReturn = reflect.Zero(tp) - - switch tp.Kind() { - case reflect.Int: - result, err = strconv.Atoi(s) - if err != nil { - return defReturn, fmt.Errorf("convert %s as int: %s", s, err.Error()) - } - case reflect.Int8: - x, err := strconv.Atoi(s) - if err != nil { - return defReturn, fmt.Errorf("convert %s as int8: %s", s, err.Error()) - } - result = int8(x) - case reflect.Int16: - x, err := strconv.Atoi(s) - if err != nil { - return defReturn, fmt.Errorf("convert %s as int16: %s", s, err.Error()) - } - result = int16(x) - case reflect.Int32: - x, err := strconv.Atoi(s) - if err != nil { - return defReturn, fmt.Errorf("convert %s as int32: %s", s, err.Error()) - } - result = int32(x) - case reflect.Int64: - result, err = strconv.ParseInt(s, 10, 64) - if err != nil { - return defReturn, fmt.Errorf("convert %s as int64: %s", s, err.Error()) - } - case reflect.Uint: - x, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return defReturn, fmt.Errorf("convert %s as uint: %s", s, err.Error()) - } - result = uint(x) - case reflect.Uint8: - x, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return defReturn, fmt.Errorf("convert %s as uint8: %s", s, err.Error()) - } - result = uint8(x) - case reflect.Uint16: - x, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return defReturn, fmt.Errorf("convert %s as uint16: %s", s, err.Error()) - } - result = uint16(x) - case reflect.Uint32: - x, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return defReturn, fmt.Errorf("convert %s as uint32: %s", s, err.Error()) - } - result = uint32(x) - case reflect.Uint64: - result, err = strconv.ParseUint(s, 10, 64) - if err != nil { - return defReturn, fmt.Errorf("convert %s as uint64: %s", s, err.Error()) - } - case reflect.String: - result = s - default: - return defReturn, errors.New("unsupported convert type") - } - return reflect.ValueOf(result).Convert(tp), nil -} - -func str2PK(s string, tp reflect.Type) (interface{}, error) { - v, err := str2PKValue(s, tp) - if err != nil { - return nil, err - } - return v.Interface(), nil -} - -func splitTag(tag string) (tags []string) { - tag = strings.TrimSpace(tag) - var hasQuote = false - var lastIdx = 0 - for i, t := range tag { - if t == '\'' { - hasQuote = !hasQuote - } else if t == ' ' { - if lastIdx < i && !hasQuote { - tags = append(tags, strings.TrimSpace(tag[lastIdx:i])) - lastIdx = i + 1 - } - } - } - if lastIdx < len(tag) { - tags = append(tags, strings.TrimSpace(tag[lastIdx:])) - } - return -} - -type zeroable interface { - IsZero() bool -} - -func isZero(k interface{}) bool { - switch k.(type) { - case int: - return k.(int) == 0 - case int8: - return k.(int8) == 0 - case int16: - return k.(int16) == 0 - case int32: - return k.(int32) == 0 - case int64: - return k.(int64) == 0 - case uint: - return k.(uint) == 0 - case uint8: - return k.(uint8) == 0 - case uint16: - return k.(uint16) == 0 - case uint32: - return k.(uint32) == 0 - case uint64: - return k.(uint64) == 0 - case float32: - return k.(float32) == 0 - case float64: - return k.(float64) == 0 - case bool: - return k.(bool) == false - case string: - return k.(string) == "" - case zeroable: - return k.(zeroable).IsZero() - } - return false -} - -func isStructZero(v reflect.Value) bool { - if !v.IsValid() { - return true - } - - for i := 0; i < v.NumField(); i++ { - field := v.Field(i) - switch field.Kind() { - case reflect.Ptr: - field = field.Elem() - fallthrough - case reflect.Struct: - if !isStructZero(field) { - return false - } - default: - if field.CanInterface() && !isZero(field.Interface()) { - return false - } - } - } - return true -} - -func isArrayValueZero(v reflect.Value) bool { - if !v.IsValid() || v.Len() == 0 { - return true - } - - for i := 0; i < v.Len(); i++ { - if !isZero(v.Index(i).Interface()) { - return false - } - } - - return true -} - -func int64ToIntValue(id int64, tp reflect.Type) reflect.Value { - var v interface{} - kind := tp.Kind() - - if kind == reflect.Ptr { - kind = tp.Elem().Kind() - } - - switch kind { - case reflect.Int16: - temp := int16(id) - v = &temp - case reflect.Int32: - temp := int32(id) - v = &temp - case reflect.Int: - temp := int(id) - v = &temp - case reflect.Int64: - temp := id - v = &temp - case reflect.Uint16: - temp := uint16(id) - v = &temp - case reflect.Uint32: - temp := uint32(id) - v = &temp - case reflect.Uint64: - temp := uint64(id) - v = &temp - case reflect.Uint: - temp := uint(id) - v = &temp - } - - if tp.Kind() == reflect.Ptr { - return reflect.ValueOf(v).Convert(tp) - } - return reflect.ValueOf(v).Elem().Convert(tp) -} - -func int64ToInt(id int64, tp reflect.Type) interface{} { - return int64ToIntValue(id, tp).Interface() -} - -func isPKZero(pk core.PK) bool { - for _, k := range pk { - if isZero(k) { - return true - } - } - return false -} - -func indexNoCase(s, sep string) int { - return strings.Index(strings.ToLower(s), strings.ToLower(sep)) -} - -func splitNoCase(s, sep string) []string { - idx := indexNoCase(s, sep) - if idx < 0 { - return []string{s} - } - return strings.Split(s, s[idx:idx+len(sep)]) -} - -func splitNNoCase(s, sep string, n int) []string { - idx := indexNoCase(s, sep) - if idx < 0 { - return []string{s} - } - return strings.SplitN(s, s[idx:idx+len(sep)], n) -} - -func makeArray(elem string, count int) []string { - res := make([]string, count) - for i := 0; i < count; i++ { - res[i] = elem - } - return res -} - -func rValue(bean interface{}) reflect.Value { - return reflect.Indirect(reflect.ValueOf(bean)) -} - -func rType(bean interface{}) reflect.Type { - sliceValue := reflect.Indirect(reflect.ValueOf(bean)) - // return reflect.TypeOf(sliceValue.Interface()) - return sliceValue.Type() -} - -func structName(v reflect.Type) string { - for v.Kind() == reflect.Ptr { - v = v.Elem() - } - return v.Name() -} - -func sliceEq(left, right []string) bool { - if len(left) != len(right) { - return false - } - sort.Sort(sort.StringSlice(left)) - sort.Sort(sort.StringSlice(right)) - for i := 0; i < len(left); i++ { - if left[i] != right[i] { - return false - } - } - return true -} - -func indexName(tableName, idxName string) string { - return fmt.Sprintf("IDX_%v_%v", tableName, idxName) -} - -func eraseAny(value string, strToErase ...string) string { - if len(strToErase) == 0 { - return value - } - var replaceSeq []string - for _, s := range strToErase { - replaceSeq = append(replaceSeq, s, "") - } - - replacer := strings.NewReplacer(replaceSeq...) - - return replacer.Replace(value) -} - -func quoteColumns(cols []string, quoteFunc func(string) string, sep string) string { - for i := range cols { - cols[i] = quoteFunc(cols[i]) - } - return strings.Join(cols, sep+" ") -} diff --git a/vendor/github.com/go-xorm/xorm/helpler_time.go b/vendor/github.com/go-xorm/xorm/helpler_time.go deleted file mode 100644 index f4013e27e1..0000000000 --- a/vendor/github.com/go-xorm/xorm/helpler_time.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import "time" - -const ( - zeroTime0 = "0000-00-00 00:00:00" - zeroTime1 = "0001-01-01 00:00:00" -) - -func formatTime(t time.Time) string { - return t.Format("2006-01-02 15:04:05") -} - -func isTimeZero(t time.Time) bool { - return t.IsZero() || formatTime(t) == zeroTime0 || - formatTime(t) == zeroTime1 -} diff --git a/vendor/github.com/go-xorm/xorm/interface.go b/vendor/github.com/go-xorm/xorm/interface.go deleted file mode 100644 index a564db1260..0000000000 --- a/vendor/github.com/go-xorm/xorm/interface.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "context" - "database/sql" - "reflect" - "time" - - "xorm.io/core" -) - -// Interface defines the interface which Engine, EngineGroup and Session will implementate. -type Interface interface { - AllCols() *Session - Alias(alias string) *Session - Asc(colNames ...string) *Session - BufferSize(size int) *Session - Cols(columns ...string) *Session - Count(...interface{}) (int64, error) - CreateIndexes(bean interface{}) error - CreateUniques(bean interface{}) error - Decr(column string, arg ...interface{}) *Session - Desc(...string) *Session - Delete(interface{}) (int64, error) - Distinct(columns ...string) *Session - DropIndexes(bean interface{}) error - Exec(sqlOrArgs ...interface{}) (sql.Result, error) - Exist(bean ...interface{}) (bool, error) - Find(interface{}, ...interface{}) error - FindAndCount(interface{}, ...interface{}) (int64, error) - Get(interface{}) (bool, error) - GroupBy(keys string) *Session - ID(interface{}) *Session - In(string, ...interface{}) *Session - Incr(column string, arg ...interface{}) *Session - Insert(...interface{}) (int64, error) - InsertOne(interface{}) (int64, error) - IsTableEmpty(bean interface{}) (bool, error) - IsTableExist(beanOrTableName interface{}) (bool, error) - Iterate(interface{}, IterFunc) error - Limit(int, ...int) *Session - MustCols(columns ...string) *Session - NoAutoCondition(...bool) *Session - NotIn(string, ...interface{}) *Session - Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session - Omit(columns ...string) *Session - OrderBy(order string) *Session - Ping() error - Query(sqlOrArgs ...interface{}) (resultsSlice []map[string][]byte, err error) - QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) - QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) - Rows(bean interface{}) (*Rows, error) - SetExpr(string, interface{}) *Session - SQL(interface{}, ...interface{}) *Session - Sum(bean interface{}, colName string) (float64, error) - SumInt(bean interface{}, colName string) (int64, error) - Sums(bean interface{}, colNames ...string) ([]float64, error) - SumsInt(bean interface{}, colNames ...string) ([]int64, error) - Table(tableNameOrBean interface{}) *Session - Unscoped() *Session - Update(bean interface{}, condiBeans ...interface{}) (int64, error) - UseBool(...string) *Session - Where(interface{}, ...interface{}) *Session -} - -// EngineInterface defines the interface which Engine, EngineGroup will implementate. -type EngineInterface interface { - Interface - - Before(func(interface{})) *Session - Charset(charset string) *Session - ClearCache(...interface{}) error - Context(context.Context) *Session - CreateTables(...interface{}) error - DBMetas() ([]*core.Table, error) - Dialect() core.Dialect - DropTables(...interface{}) error - DumpAllToFile(fp string, tp ...core.DbType) error - GetCacher(string) core.Cacher - GetColumnMapper() core.IMapper - GetDefaultCacher() core.Cacher - GetTableMapper() core.IMapper - GetTZDatabase() *time.Location - GetTZLocation() *time.Location - MapCacher(interface{}, core.Cacher) error - NewSession() *Session - NoAutoTime() *Session - Quote(string) string - SetCacher(string, core.Cacher) - SetConnMaxLifetime(time.Duration) - SetDefaultCacher(core.Cacher) - SetLogger(logger core.ILogger) - SetLogLevel(core.LogLevel) - SetMapper(core.IMapper) - SetMaxOpenConns(int) - SetMaxIdleConns(int) - SetSchema(string) - SetTZDatabase(tz *time.Location) - SetTZLocation(tz *time.Location) - ShowExecTime(...bool) - ShowSQL(show ...bool) - Sync(...interface{}) error - Sync2(...interface{}) error - StoreEngine(storeEngine string) *Session - TableInfo(bean interface{}) *Table - TableName(interface{}, ...bool) string - UnMapType(reflect.Type) -} - -var ( - _ Interface = &Session{} - _ EngineInterface = &Engine{} - _ EngineInterface = &EngineGroup{} -) diff --git a/vendor/github.com/go-xorm/xorm/json.go b/vendor/github.com/go-xorm/xorm/json.go deleted file mode 100644 index fdb6ce5654..0000000000 --- a/vendor/github.com/go-xorm/xorm/json.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2019 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import "encoding/json" - -// JSONInterface represents an interface to handle json data -type JSONInterface interface { - Marshal(v interface{}) ([]byte, error) - Unmarshal(data []byte, v interface{}) error -} - -var ( - // DefaultJSONHandler default json handler - DefaultJSONHandler JSONInterface = StdJSON{} -) - -// StdJSON implements JSONInterface via encoding/json -type StdJSON struct{} - -// Marshal implements JSONInterface -func (StdJSON) Marshal(v interface{}) ([]byte, error) { - return json.Marshal(v) -} - -// Unmarshal implements JSONInterface -func (StdJSON) Unmarshal(data []byte, v interface{}) error { - return json.Unmarshal(data, v) -} diff --git a/vendor/github.com/go-xorm/xorm/logger.go b/vendor/github.com/go-xorm/xorm/logger.go deleted file mode 100644 index 7b26e77f3b..0000000000 --- a/vendor/github.com/go-xorm/xorm/logger.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "fmt" - "io" - "log" - - "xorm.io/core" -) - -// default log options -const ( - DEFAULT_LOG_PREFIX = "[xorm]" - DEFAULT_LOG_FLAG = log.Ldate | log.Lmicroseconds - DEFAULT_LOG_LEVEL = core.LOG_DEBUG -) - -var _ core.ILogger = DiscardLogger{} - -// DiscardLogger don't log implementation for core.ILogger -type DiscardLogger struct{} - -// Debug empty implementation -func (DiscardLogger) Debug(v ...interface{}) {} - -// Debugf empty implementation -func (DiscardLogger) Debugf(format string, v ...interface{}) {} - -// Error empty implementation -func (DiscardLogger) Error(v ...interface{}) {} - -// Errorf empty implementation -func (DiscardLogger) Errorf(format string, v ...interface{}) {} - -// Info empty implementation -func (DiscardLogger) Info(v ...interface{}) {} - -// Infof empty implementation -func (DiscardLogger) Infof(format string, v ...interface{}) {} - -// Warn empty implementation -func (DiscardLogger) Warn(v ...interface{}) {} - -// Warnf empty implementation -func (DiscardLogger) Warnf(format string, v ...interface{}) {} - -// Level empty implementation -func (DiscardLogger) Level() core.LogLevel { - return core.LOG_UNKNOWN -} - -// SetLevel empty implementation -func (DiscardLogger) SetLevel(l core.LogLevel) {} - -// ShowSQL empty implementation -func (DiscardLogger) ShowSQL(show ...bool) {} - -// IsShowSQL empty implementation -func (DiscardLogger) IsShowSQL() bool { - return false -} - -// SimpleLogger is the default implment of core.ILogger -type SimpleLogger struct { - DEBUG *log.Logger - ERR *log.Logger - INFO *log.Logger - WARN *log.Logger - level core.LogLevel - showSQL bool -} - -var _ core.ILogger = &SimpleLogger{} - -// NewSimpleLogger use a special io.Writer as logger output -func NewSimpleLogger(out io.Writer) *SimpleLogger { - return NewSimpleLogger2(out, DEFAULT_LOG_PREFIX, DEFAULT_LOG_FLAG) -} - -// NewSimpleLogger2 let you customrize your logger prefix and flag -func NewSimpleLogger2(out io.Writer, prefix string, flag int) *SimpleLogger { - return NewSimpleLogger3(out, prefix, flag, DEFAULT_LOG_LEVEL) -} - -// NewSimpleLogger3 let you customrize your logger prefix and flag and logLevel -func NewSimpleLogger3(out io.Writer, prefix string, flag int, l core.LogLevel) *SimpleLogger { - return &SimpleLogger{ - DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), flag), - ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag), - INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag), - WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag), - level: l, - } -} - -// Error implement core.ILogger -func (s *SimpleLogger) Error(v ...interface{}) { - if s.level <= core.LOG_ERR { - s.ERR.Output(2, fmt.Sprint(v...)) - } - return -} - -// Errorf implement core.ILogger -func (s *SimpleLogger) Errorf(format string, v ...interface{}) { - if s.level <= core.LOG_ERR { - s.ERR.Output(2, fmt.Sprintf(format, v...)) - } - return -} - -// Debug implement core.ILogger -func (s *SimpleLogger) Debug(v ...interface{}) { - if s.level <= core.LOG_DEBUG { - s.DEBUG.Output(2, fmt.Sprint(v...)) - } - return -} - -// Debugf implement core.ILogger -func (s *SimpleLogger) Debugf(format string, v ...interface{}) { - if s.level <= core.LOG_DEBUG { - s.DEBUG.Output(2, fmt.Sprintf(format, v...)) - } - return -} - -// Info implement core.ILogger -func (s *SimpleLogger) Info(v ...interface{}) { - if s.level <= core.LOG_INFO { - s.INFO.Output(2, fmt.Sprint(v...)) - } - return -} - -// Infof implement core.ILogger -func (s *SimpleLogger) Infof(format string, v ...interface{}) { - if s.level <= core.LOG_INFO { - s.INFO.Output(2, fmt.Sprintf(format, v...)) - } - return -} - -// Warn implement core.ILogger -func (s *SimpleLogger) Warn(v ...interface{}) { - if s.level <= core.LOG_WARNING { - s.WARN.Output(2, fmt.Sprint(v...)) - } - return -} - -// Warnf implement core.ILogger -func (s *SimpleLogger) Warnf(format string, v ...interface{}) { - if s.level <= core.LOG_WARNING { - s.WARN.Output(2, fmt.Sprintf(format, v...)) - } - return -} - -// Level implement core.ILogger -func (s *SimpleLogger) Level() core.LogLevel { - return s.level -} - -// SetLevel implement core.ILogger -func (s *SimpleLogger) SetLevel(l core.LogLevel) { - s.level = l - return -} - -// ShowSQL implement core.ILogger -func (s *SimpleLogger) ShowSQL(show ...bool) { - if len(show) == 0 { - s.showSQL = true - return - } - s.showSQL = show[0] -} - -// IsShowSQL implement core.ILogger -func (s *SimpleLogger) IsShowSQL() bool { - return s.showSQL -} diff --git a/vendor/github.com/go-xorm/xorm/pg_reserved.txt b/vendor/github.com/go-xorm/xorm/pg_reserved.txt deleted file mode 100644 index 720ed377ba..0000000000 --- a/vendor/github.com/go-xorm/xorm/pg_reserved.txt +++ /dev/null @@ -1,746 +0,0 @@ -A non-reserved non-reserved -ABORT non-reserved -ABS reserved reserved -ABSENT non-reserved non-reserved -ABSOLUTE non-reserved non-reserved non-reserved reserved -ACCESS non-reserved -ACCORDING non-reserved non-reserved -ACTION non-reserved non-reserved non-reserved reserved -ADA non-reserved non-reserved non-reserved -ADD non-reserved non-reserved non-reserved reserved -ADMIN non-reserved non-reserved non-reserved -AFTER non-reserved non-reserved non-reserved -AGGREGATE non-reserved -ALL reserved reserved reserved reserved -ALLOCATE reserved reserved reserved -ALSO non-reserved -ALTER non-reserved reserved reserved reserved -ALWAYS non-reserved non-reserved non-reserved -ANALYSE reserved -ANALYZE reserved -AND reserved reserved reserved reserved -ANY reserved reserved reserved reserved -ARE reserved reserved reserved -ARRAY reserved reserved reserved -ARRAY_AGG reserved reserved -ARRAY_MAX_CARDINALITY reserved -AS reserved reserved reserved reserved -ASC reserved non-reserved non-reserved reserved -ASENSITIVE reserved reserved -ASSERTION non-reserved non-reserved non-reserved reserved -ASSIGNMENT non-reserved non-reserved non-reserved -ASYMMETRIC reserved reserved reserved -AT non-reserved reserved reserved reserved -ATOMIC reserved reserved -ATTRIBUTE non-reserved non-reserved non-reserved -ATTRIBUTES non-reserved non-reserved -AUTHORIZATION reserved (can be function or type) reserved reserved reserved -AVG reserved reserved reserved -BACKWARD non-reserved -BASE64 non-reserved non-reserved -BEFORE non-reserved non-reserved non-reserved -BEGIN non-reserved reserved reserved reserved -BEGIN_FRAME reserved -BEGIN_PARTITION reserved -BERNOULLI non-reserved non-reserved -BETWEEN non-reserved (cannot be function or type) reserved reserved reserved -BIGINT non-reserved (cannot be function or type) reserved reserved -BINARY reserved (can be function or type) reserved reserved -BIT non-reserved (cannot be function or type) reserved -BIT_LENGTH reserved -BLOB reserved reserved -BLOCKED non-reserved non-reserved -BOM non-reserved non-reserved -BOOLEAN non-reserved (cannot be function or type) reserved reserved -BOTH reserved reserved reserved reserved -BREADTH non-reserved non-reserved -BY non-reserved reserved reserved reserved -C non-reserved non-reserved non-reserved -CACHE non-reserved -CALL reserved reserved -CALLED non-reserved reserved reserved -CARDINALITY reserved reserved -CASCADE non-reserved non-reserved non-reserved reserved -CASCADED non-reserved reserved reserved reserved -CASE reserved reserved reserved reserved -CAST reserved reserved reserved reserved -CATALOG non-reserved non-reserved non-reserved reserved -CATALOG_NAME non-reserved non-reserved non-reserved -CEIL reserved reserved -CEILING reserved reserved -CHAIN non-reserved non-reserved non-reserved -CHAR non-reserved (cannot be function or type) reserved reserved reserved -CHARACTER non-reserved (cannot be function or type) reserved reserved reserved -CHARACTERISTICS non-reserved non-reserved non-reserved -CHARACTERS non-reserved non-reserved -CHARACTER_LENGTH reserved reserved reserved -CHARACTER_SET_CATALOG non-reserved non-reserved non-reserved -CHARACTER_SET_NAME non-reserved non-reserved non-reserved -CHARACTER_SET_SCHEMA non-reserved non-reserved non-reserved -CHAR_LENGTH reserved reserved reserved -CHECK reserved reserved reserved reserved -CHECKPOINT non-reserved -CLASS non-reserved -CLASS_ORIGIN non-reserved non-reserved non-reserved -CLOB reserved reserved -CLOSE non-reserved reserved reserved reserved -CLUSTER non-reserved -COALESCE non-reserved (cannot be function or type) reserved reserved reserved -COBOL non-reserved non-reserved non-reserved -COLLATE reserved reserved reserved reserved -COLLATION reserved (can be function or type) non-reserved non-reserved reserved -COLLATION_CATALOG non-reserved non-reserved non-reserved -COLLATION_NAME non-reserved non-reserved non-reserved -COLLATION_SCHEMA non-reserved non-reserved non-reserved -COLLECT reserved reserved -COLUMN reserved reserved reserved reserved -COLUMNS non-reserved non-reserved -COLUMN_NAME non-reserved non-reserved non-reserved -COMMAND_FUNCTION non-reserved non-reserved non-reserved -COMMAND_FUNCTION_CODE non-reserved non-reserved -COMMENT non-reserved -COMMENTS non-reserved -COMMIT non-reserved reserved reserved reserved -COMMITTED non-reserved non-reserved non-reserved non-reserved -CONCURRENTLY reserved (can be function or type) -CONDITION reserved reserved -CONDITION_NUMBER non-reserved non-reserved non-reserved -CONFIGURATION non-reserved -CONNECT reserved reserved reserved -CONNECTION non-reserved non-reserved non-reserved reserved -CONNECTION_NAME non-reserved non-reserved non-reserved -CONSTRAINT reserved reserved reserved reserved -CONSTRAINTS non-reserved non-reserved non-reserved reserved -CONSTRAINT_CATALOG non-reserved non-reserved non-reserved -CONSTRAINT_NAME non-reserved non-reserved non-reserved -CONSTRAINT_SCHEMA non-reserved non-reserved non-reserved -CONSTRUCTOR non-reserved non-reserved -CONTAINS reserved non-reserved -CONTENT non-reserved non-reserved non-reserved -CONTINUE non-reserved non-reserved non-reserved reserved -CONTROL non-reserved non-reserved -CONVERSION non-reserved -CONVERT reserved reserved reserved -COPY non-reserved -CORR reserved reserved -CORRESPONDING reserved reserved reserved -COST non-reserved -COUNT reserved reserved reserved -COVAR_POP reserved reserved -COVAR_SAMP reserved reserved -CREATE reserved reserved reserved reserved -CROSS reserved (can be function or type) reserved reserved reserved -CSV non-reserved -CUBE reserved reserved -CUME_DIST reserved reserved -CURRENT non-reserved reserved reserved reserved -CURRENT_CATALOG reserved reserved reserved -CURRENT_DATE reserved reserved reserved reserved -CURRENT_DEFAULT_TRANSFORM_GROUP reserved reserved -CURRENT_PATH reserved reserved -CURRENT_ROLE reserved reserved reserved -CURRENT_ROW reserved -CURRENT_SCHEMA reserved (can be function or type) reserved reserved -CURRENT_TIME reserved reserved reserved reserved -CURRENT_TIMESTAMP reserved reserved reserved reserved -CURRENT_TRANSFORM_GROUP_FOR_TYPE reserved reserved -CURRENT_USER reserved reserved reserved reserved -CURSOR non-reserved reserved reserved reserved -CURSOR_NAME non-reserved non-reserved non-reserved -CYCLE non-reserved reserved reserved -DATA non-reserved non-reserved non-reserved non-reserved -DATABASE non-reserved -DATALINK reserved reserved -DATE reserved reserved reserved -DATETIME_INTERVAL_CODE non-reserved non-reserved non-reserved -DATETIME_INTERVAL_PRECISION non-reserved non-reserved non-reserved -DAY non-reserved reserved reserved reserved -DB non-reserved non-reserved -DEALLOCATE non-reserved reserved reserved reserved -DEC non-reserved (cannot be function or type) reserved reserved reserved -DECIMAL non-reserved (cannot be function or type) reserved reserved reserved -DECLARE non-reserved reserved reserved reserved -DEFAULT reserved reserved reserved reserved -DEFAULTS non-reserved non-reserved non-reserved -DEFERRABLE reserved non-reserved non-reserved reserved -DEFERRED non-reserved non-reserved non-reserved reserved -DEFINED non-reserved non-reserved -DEFINER non-reserved non-reserved non-reserved -DEGREE non-reserved non-reserved -DELETE non-reserved reserved reserved reserved -DELIMITER non-reserved -DELIMITERS non-reserved -DENSE_RANK reserved reserved -DEPTH non-reserved non-reserved -DEREF reserved reserved -DERIVED non-reserved non-reserved -DESC reserved non-reserved non-reserved reserved -DESCRIBE reserved reserved reserved -DESCRIPTOR non-reserved non-reserved reserved -DETERMINISTIC reserved reserved -DIAGNOSTICS non-reserved non-reserved reserved -DICTIONARY non-reserved -DISABLE non-reserved -DISCARD non-reserved -DISCONNECT reserved reserved reserved -DISPATCH non-reserved non-reserved -DISTINCT reserved reserved reserved reserved -DLNEWCOPY reserved reserved -DLPREVIOUSCOPY reserved reserved -DLURLCOMPLETE reserved reserved -DLURLCOMPLETEONLY reserved reserved -DLURLCOMPLETEWRITE reserved reserved -DLURLPATH reserved reserved -DLURLPATHONLY reserved reserved -DLURLPATHWRITE reserved reserved -DLURLSCHEME reserved reserved -DLURLSERVER reserved reserved -DLVALUE reserved reserved -DO reserved -DOCUMENT non-reserved non-reserved non-reserved -DOMAIN non-reserved non-reserved non-reserved reserved -DOUBLE non-reserved reserved reserved reserved -DROP non-reserved reserved reserved reserved -DYNAMIC reserved reserved -DYNAMIC_FUNCTION non-reserved non-reserved non-reserved -DYNAMIC_FUNCTION_CODE non-reserved non-reserved -EACH non-reserved reserved reserved -ELEMENT reserved reserved -ELSE reserved reserved reserved reserved -EMPTY non-reserved non-reserved -ENABLE non-reserved -ENCODING non-reserved non-reserved non-reserved -ENCRYPTED non-reserved -END reserved reserved reserved reserved -END-EXEC reserved reserved reserved -END_FRAME reserved -END_PARTITION reserved -ENFORCED non-reserved -ENUM non-reserved -EQUALS reserved non-reserved -ESCAPE non-reserved reserved reserved reserved -EVENT non-reserved -EVERY reserved reserved -EXCEPT reserved reserved reserved reserved -EXCEPTION reserved -EXCLUDE non-reserved non-reserved non-reserved -EXCLUDING non-reserved non-reserved non-reserved -EXCLUSIVE non-reserved -EXEC reserved reserved reserved -EXECUTE non-reserved reserved reserved reserved -EXISTS non-reserved (cannot be function or type) reserved reserved reserved -EXP reserved reserved -EXPLAIN non-reserved -EXPRESSION non-reserved -EXTENSION non-reserved -EXTERNAL non-reserved reserved reserved reserved -EXTRACT non-reserved (cannot be function or type) reserved reserved reserved -FALSE reserved reserved reserved reserved -FAMILY non-reserved -FETCH reserved reserved reserved reserved -FILE non-reserved non-reserved -FILTER reserved reserved -FINAL non-reserved non-reserved -FIRST non-reserved non-reserved non-reserved reserved -FIRST_VALUE reserved reserved -FLAG non-reserved non-reserved -FLOAT non-reserved (cannot be function or type) reserved reserved reserved -FLOOR reserved reserved -FOLLOWING non-reserved non-reserved non-reserved -FOR reserved reserved reserved reserved -FORCE non-reserved -FOREIGN reserved reserved reserved reserved -FORTRAN non-reserved non-reserved non-reserved -FORWARD non-reserved -FOUND non-reserved non-reserved reserved -FRAME_ROW reserved -FREE reserved reserved -FREEZE reserved (can be function or type) -FROM reserved reserved reserved reserved -FS non-reserved non-reserved -FULL reserved (can be function or type) reserved reserved reserved -FUNCTION non-reserved reserved reserved -FUNCTIONS non-reserved -FUSION reserved reserved -G non-reserved non-reserved -GENERAL non-reserved non-reserved -GENERATED non-reserved non-reserved -GET reserved reserved reserved -GLOBAL non-reserved reserved reserved reserved -GO non-reserved non-reserved reserved -GOTO non-reserved non-reserved reserved -GRANT reserved reserved reserved reserved -GRANTED non-reserved non-reserved non-reserved -GREATEST non-reserved (cannot be function or type) -GROUP reserved reserved reserved reserved -GROUPING reserved reserved -GROUPS reserved -HANDLER non-reserved -HAVING reserved reserved reserved reserved -HEADER non-reserved -HEX non-reserved non-reserved -HIERARCHY non-reserved non-reserved -HOLD non-reserved reserved reserved -HOUR non-reserved reserved reserved reserved -ID non-reserved non-reserved -IDENTITY non-reserved reserved reserved reserved -IF non-reserved -IGNORE non-reserved non-reserved -ILIKE reserved (can be function or type) -IMMEDIATE non-reserved non-reserved non-reserved reserved -IMMEDIATELY non-reserved -IMMUTABLE non-reserved -IMPLEMENTATION non-reserved non-reserved -IMPLICIT non-reserved -IMPORT reserved reserved -IN reserved reserved reserved reserved -INCLUDING non-reserved non-reserved non-reserved -INCREMENT non-reserved non-reserved non-reserved -INDENT non-reserved non-reserved -INDEX non-reserved -INDEXES non-reserved -INDICATOR reserved reserved reserved -INHERIT non-reserved -INHERITS non-reserved -INITIALLY reserved non-reserved non-reserved reserved -INLINE non-reserved -INNER reserved (can be function or type) reserved reserved reserved -INOUT non-reserved (cannot be function or type) reserved reserved -INPUT non-reserved non-reserved non-reserved reserved -INSENSITIVE non-reserved reserved reserved reserved -INSERT non-reserved reserved reserved reserved -INSTANCE non-reserved non-reserved -INSTANTIABLE non-reserved non-reserved -INSTEAD non-reserved non-reserved non-reserved -INT non-reserved (cannot be function or type) reserved reserved reserved -INTEGER non-reserved (cannot be function or type) reserved reserved reserved -INTEGRITY non-reserved non-reserved -INTERSECT reserved reserved reserved reserved -INTERSECTION reserved reserved -INTERVAL non-reserved (cannot be function or type) reserved reserved reserved -INTO reserved reserved reserved reserved -INVOKER non-reserved non-reserved non-reserved -IS reserved (can be function or type) reserved reserved reserved -ISNULL reserved (can be function or type) -ISOLATION non-reserved non-reserved non-reserved reserved -JOIN reserved (can be function or type) reserved reserved reserved -K non-reserved non-reserved -KEY non-reserved non-reserved non-reserved reserved -KEY_MEMBER non-reserved non-reserved -KEY_TYPE non-reserved non-reserved -LABEL non-reserved -LAG reserved reserved -LANGUAGE non-reserved reserved reserved reserved -LARGE non-reserved reserved reserved -LAST non-reserved non-reserved non-reserved reserved -LAST_VALUE reserved reserved -LATERAL reserved reserved reserved -LC_COLLATE non-reserved -LC_CTYPE non-reserved -LEAD reserved reserved -LEADING reserved reserved reserved reserved -LEAKPROOF non-reserved -LEAST non-reserved (cannot be function or type) -LEFT reserved (can be function or type) reserved reserved reserved -LENGTH non-reserved non-reserved non-reserved -LEVEL non-reserved non-reserved non-reserved reserved -LIBRARY non-reserved non-reserved -LIKE reserved (can be function or type) reserved reserved reserved -LIKE_REGEX reserved reserved -LIMIT reserved non-reserved non-reserved -LINK non-reserved non-reserved -LISTEN non-reserved -LN reserved reserved -LOAD non-reserved -LOCAL non-reserved reserved reserved reserved -LOCALTIME reserved reserved reserved -LOCALTIMESTAMP reserved reserved reserved -LOCATION non-reserved non-reserved non-reserved -LOCATOR non-reserved non-reserved -LOCK non-reserved -LOWER reserved reserved reserved -M non-reserved non-reserved -MAP non-reserved non-reserved -MAPPING non-reserved non-reserved non-reserved -MATCH non-reserved reserved reserved reserved -MATCHED non-reserved non-reserved -MATERIALIZED non-reserved -MAX reserved reserved reserved -MAXVALUE non-reserved non-reserved non-reserved -MAX_CARDINALITY reserved -MEMBER reserved reserved -MERGE reserved reserved -MESSAGE_LENGTH non-reserved non-reserved non-reserved -MESSAGE_OCTET_LENGTH non-reserved non-reserved non-reserved -MESSAGE_TEXT non-reserved non-reserved non-reserved -METHOD reserved reserved -MIN reserved reserved reserved -MINUTE non-reserved reserved reserved reserved -MINVALUE non-reserved non-reserved non-reserved -MOD reserved reserved -MODE non-reserved -MODIFIES reserved reserved -MODULE reserved reserved reserved -MONTH non-reserved reserved reserved reserved -MORE non-reserved non-reserved non-reserved -MOVE non-reserved -MULTISET reserved reserved -MUMPS non-reserved non-reserved non-reserved -NAME non-reserved non-reserved non-reserved non-reserved -NAMES non-reserved non-reserved non-reserved reserved -NAMESPACE non-reserved non-reserved -NATIONAL non-reserved (cannot be function or type) reserved reserved reserved -NATURAL reserved (can be function or type) reserved reserved reserved -NCHAR non-reserved (cannot be function or type) reserved reserved reserved -NCLOB reserved reserved -NESTING non-reserved non-reserved -NEW reserved reserved -NEXT non-reserved non-reserved non-reserved reserved -NFC non-reserved non-reserved -NFD non-reserved non-reserved -NFKC non-reserved non-reserved -NFKD non-reserved non-reserved -NIL non-reserved non-reserved -NO non-reserved reserved reserved reserved -NONE non-reserved (cannot be function or type) reserved reserved -NORMALIZE reserved reserved -NORMALIZED non-reserved non-reserved -NOT reserved reserved reserved reserved -NOTHING non-reserved -NOTIFY non-reserved -NOTNULL reserved (can be function or type) -NOWAIT non-reserved -NTH_VALUE reserved reserved -NTILE reserved reserved -NULL reserved reserved reserved reserved -NULLABLE non-reserved non-reserved non-reserved -NULLIF non-reserved (cannot be function or type) reserved reserved reserved -NULLS non-reserved non-reserved non-reserved -NUMBER non-reserved non-reserved non-reserved -NUMERIC non-reserved (cannot be function or type) reserved reserved reserved -OBJECT non-reserved non-reserved non-reserved -OCCURRENCES_REGEX reserved reserved -OCTETS non-reserved non-reserved -OCTET_LENGTH reserved reserved reserved -OF non-reserved reserved reserved reserved -OFF non-reserved non-reserved non-reserved -OFFSET reserved reserved reserved -OIDS non-reserved -OLD reserved reserved -ON reserved reserved reserved reserved -ONLY reserved reserved reserved reserved -OPEN reserved reserved reserved -OPERATOR non-reserved -OPTION non-reserved non-reserved non-reserved reserved -OPTIONS non-reserved non-reserved non-reserved -OR reserved reserved reserved reserved -ORDER reserved reserved reserved reserved -ORDERING non-reserved non-reserved -ORDINALITY non-reserved non-reserved -OTHERS non-reserved non-reserved -OUT non-reserved (cannot be function or type) reserved reserved -OUTER reserved (can be function or type) reserved reserved reserved -OUTPUT non-reserved non-reserved reserved -OVER reserved (can be function or type) reserved reserved -OVERLAPS reserved (can be function or type) reserved reserved reserved -OVERLAY non-reserved (cannot be function or type) reserved reserved -OVERRIDING non-reserved non-reserved -OWNED non-reserved -OWNER non-reserved -P non-reserved non-reserved -PAD non-reserved non-reserved reserved -PARAMETER reserved reserved -PARAMETER_MODE non-reserved non-reserved -PARAMETER_NAME non-reserved non-reserved -PARAMETER_ORDINAL_POSITION non-reserved non-reserved -PARAMETER_SPECIFIC_CATALOG non-reserved non-reserved -PARAMETER_SPECIFIC_NAME non-reserved non-reserved -PARAMETER_SPECIFIC_SCHEMA non-reserved non-reserved -PARSER non-reserved -PARTIAL non-reserved non-reserved non-reserved reserved -PARTITION non-reserved reserved reserved -PASCAL non-reserved non-reserved non-reserved -PASSING non-reserved non-reserved non-reserved -PASSTHROUGH non-reserved non-reserved -PASSWORD non-reserved -PATH non-reserved non-reserved -PERCENT reserved -PERCENTILE_CONT reserved reserved -PERCENTILE_DISC reserved reserved -PERCENT_RANK reserved reserved -PERIOD reserved -PERMISSION non-reserved non-reserved -PLACING reserved non-reserved non-reserved -PLANS non-reserved -PLI non-reserved non-reserved non-reserved -PORTION reserved -POSITION non-reserved (cannot be function or type) reserved reserved reserved -POSITION_REGEX reserved reserved -POWER reserved reserved -PRECEDES reserved -PRECEDING non-reserved non-reserved non-reserved -PRECISION non-reserved (cannot be function or type) reserved reserved reserved -PREPARE non-reserved reserved reserved reserved -PREPARED non-reserved -PRESERVE non-reserved non-reserved non-reserved reserved -PRIMARY reserved reserved reserved reserved -PRIOR non-reserved non-reserved non-reserved reserved -PRIVILEGES non-reserved non-reserved non-reserved reserved -PROCEDURAL non-reserved -PROCEDURE non-reserved reserved reserved reserved -PROGRAM non-reserved -PUBLIC non-reserved non-reserved reserved -QUOTE non-reserved -RANGE non-reserved reserved reserved -RANK reserved reserved -READ non-reserved non-reserved non-reserved reserved -READS reserved reserved -REAL non-reserved (cannot be function or type) reserved reserved reserved -REASSIGN non-reserved -RECHECK non-reserved -RECOVERY non-reserved non-reserved -RECURSIVE non-reserved reserved reserved -REF non-reserved reserved reserved -REFERENCES reserved reserved reserved reserved -REFERENCING reserved reserved -REFRESH non-reserved -REGR_AVGX reserved reserved -REGR_AVGY reserved reserved -REGR_COUNT reserved reserved -REGR_INTERCEPT reserved reserved -REGR_R2 reserved reserved -REGR_SLOPE reserved reserved -REGR_SXX reserved reserved -REGR_SXY reserved reserved -REGR_SYY reserved reserved -REINDEX non-reserved -RELATIVE non-reserved non-reserved non-reserved reserved -RELEASE non-reserved reserved reserved -RENAME non-reserved -REPEATABLE non-reserved non-reserved non-reserved non-reserved -REPLACE non-reserved -REPLICA non-reserved -REQUIRING non-reserved non-reserved -RESET non-reserved -RESPECT non-reserved non-reserved -RESTART non-reserved non-reserved non-reserved -RESTORE non-reserved non-reserved -RESTRICT non-reserved non-reserved non-reserved reserved -RESULT reserved reserved -RETURN reserved reserved -RETURNED_CARDINALITY non-reserved non-reserved -RETURNED_LENGTH non-reserved non-reserved non-reserved -RETURNED_OCTET_LENGTH non-reserved non-reserved non-reserved -RETURNED_SQLSTATE non-reserved non-reserved non-reserved -RETURNING reserved non-reserved non-reserved -RETURNS non-reserved reserved reserved -REVOKE non-reserved reserved reserved reserved -RIGHT reserved (can be function or type) reserved reserved reserved -ROLE non-reserved non-reserved non-reserved -ROLLBACK non-reserved reserved reserved reserved -ROLLUP reserved reserved -ROUTINE non-reserved non-reserved -ROUTINE_CATALOG non-reserved non-reserved -ROUTINE_NAME non-reserved non-reserved -ROUTINE_SCHEMA non-reserved non-reserved -ROW non-reserved (cannot be function or type) reserved reserved -ROWS non-reserved reserved reserved reserved -ROW_COUNT non-reserved non-reserved non-reserved -ROW_NUMBER reserved reserved -RULE non-reserved -SAVEPOINT non-reserved reserved reserved -SCALE non-reserved non-reserved non-reserved -SCHEMA non-reserved non-reserved non-reserved reserved -SCHEMA_NAME non-reserved non-reserved non-reserved -SCOPE reserved reserved -SCOPE_CATALOG non-reserved non-reserved -SCOPE_NAME non-reserved non-reserved -SCOPE_SCHEMA non-reserved non-reserved -SCROLL non-reserved reserved reserved reserved -SEARCH non-reserved reserved reserved -SECOND non-reserved reserved reserved reserved -SECTION non-reserved non-reserved reserved -SECURITY non-reserved non-reserved non-reserved -SELECT reserved reserved reserved reserved -SELECTIVE non-reserved non-reserved -SELF non-reserved non-reserved -SENSITIVE reserved reserved -SEQUENCE non-reserved non-reserved non-reserved -SEQUENCES non-reserved -SERIALIZABLE non-reserved non-reserved non-reserved non-reserved -SERVER non-reserved non-reserved non-reserved -SERVER_NAME non-reserved non-reserved non-reserved -SESSION non-reserved non-reserved non-reserved reserved -SESSION_USER reserved reserved reserved reserved -SET non-reserved reserved reserved reserved -SETOF non-reserved (cannot be function or type) -SETS non-reserved non-reserved -SHARE non-reserved -SHOW non-reserved -SIMILAR reserved (can be function or type) reserved reserved -SIMPLE non-reserved non-reserved non-reserved -SIZE non-reserved non-reserved reserved -SMALLINT non-reserved (cannot be function or type) reserved reserved reserved -SNAPSHOT non-reserved -SOME reserved reserved reserved reserved -SOURCE non-reserved non-reserved -SPACE non-reserved non-reserved reserved -SPECIFIC reserved reserved -SPECIFICTYPE reserved reserved -SPECIFIC_NAME non-reserved non-reserved -SQL reserved reserved reserved -SQLCODE reserved -SQLERROR reserved -SQLEXCEPTION reserved reserved -SQLSTATE reserved reserved reserved -SQLWARNING reserved reserved -SQRT reserved reserved -STABLE non-reserved -STANDALONE non-reserved non-reserved non-reserved -START non-reserved reserved reserved -STATE non-reserved non-reserved -STATEMENT non-reserved non-reserved non-reserved -STATIC reserved reserved -STATISTICS non-reserved -STDDEV_POP reserved reserved -STDDEV_SAMP reserved reserved -STDIN non-reserved -STDOUT non-reserved -STORAGE non-reserved -STRICT non-reserved -STRIP non-reserved non-reserved non-reserved -STRUCTURE non-reserved non-reserved -STYLE non-reserved non-reserved -SUBCLASS_ORIGIN non-reserved non-reserved non-reserved -SUBMULTISET reserved reserved -SUBSTRING non-reserved (cannot be function or type) reserved reserved reserved -SUBSTRING_REGEX reserved reserved -SUCCEEDS reserved -SUM reserved reserved reserved -SYMMETRIC reserved reserved reserved -SYSID non-reserved -SYSTEM non-reserved reserved reserved -SYSTEM_TIME reserved -SYSTEM_USER reserved reserved reserved -T non-reserved non-reserved -TABLE reserved reserved reserved reserved -TABLES non-reserved -TABLESAMPLE reserved reserved -TABLESPACE non-reserved -TABLE_NAME non-reserved non-reserved non-reserved -TEMP non-reserved -TEMPLATE non-reserved -TEMPORARY non-reserved non-reserved non-reserved reserved -TEXT non-reserved -THEN reserved reserved reserved reserved -TIES non-reserved non-reserved -TIME non-reserved (cannot be function or type) reserved reserved reserved -TIMESTAMP non-reserved (cannot be function or type) reserved reserved reserved -TIMEZONE_HOUR reserved reserved reserved -TIMEZONE_MINUTE reserved reserved reserved -TO reserved reserved reserved reserved -TOKEN non-reserved non-reserved -TOP_LEVEL_COUNT non-reserved non-reserved -TRAILING reserved reserved reserved reserved -TRANSACTION non-reserved non-reserved non-reserved reserved -TRANSACTIONS_COMMITTED non-reserved non-reserved -TRANSACTIONS_ROLLED_BACK non-reserved non-reserved -TRANSACTION_ACTIVE non-reserved non-reserved -TRANSFORM non-reserved non-reserved -TRANSFORMS non-reserved non-reserved -TRANSLATE reserved reserved reserved -TRANSLATE_REGEX reserved reserved -TRANSLATION reserved reserved reserved -TREAT non-reserved (cannot be function or type) reserved reserved -TRIGGER non-reserved reserved reserved -TRIGGER_CATALOG non-reserved non-reserved -TRIGGER_NAME non-reserved non-reserved -TRIGGER_SCHEMA non-reserved non-reserved -TRIM non-reserved (cannot be function or type) reserved reserved reserved -TRIM_ARRAY reserved reserved -TRUE reserved reserved reserved reserved -TRUNCATE non-reserved reserved reserved -TRUSTED non-reserved -TYPE non-reserved non-reserved non-reserved non-reserved -TYPES non-reserved -UESCAPE reserved reserved -UNBOUNDED non-reserved non-reserved non-reserved -UNCOMMITTED non-reserved non-reserved non-reserved non-reserved -UNDER non-reserved non-reserved -UNENCRYPTED non-reserved -UNION reserved reserved reserved reserved -UNIQUE reserved reserved reserved reserved -UNKNOWN non-reserved reserved reserved reserved -UNLINK non-reserved non-reserved -UNLISTEN non-reserved -UNLOGGED non-reserved -UNNAMED non-reserved non-reserved non-reserved -UNNEST reserved reserved -UNTIL non-reserved -UNTYPED non-reserved non-reserved -UPDATE non-reserved reserved reserved reserved -UPPER reserved reserved reserved -URI non-reserved non-reserved -USAGE non-reserved non-reserved reserved -USER reserved reserved reserved reserved -USER_DEFINED_TYPE_CATALOG non-reserved non-reserved -USER_DEFINED_TYPE_CODE non-reserved non-reserved -USER_DEFINED_TYPE_NAME non-reserved non-reserved -USER_DEFINED_TYPE_SCHEMA non-reserved non-reserved -USING reserved reserved reserved reserved -VACUUM non-reserved -VALID non-reserved non-reserved non-reserved -VALIDATE non-reserved -VALIDATOR non-reserved -VALUE non-reserved reserved reserved reserved -VALUES non-reserved (cannot be function or type) reserved reserved reserved -VALUE_OF reserved -VARBINARY reserved reserved -VARCHAR non-reserved (cannot be function or type) reserved reserved reserved -VARIADIC reserved -VARYING non-reserved reserved reserved reserved -VAR_POP reserved reserved -VAR_SAMP reserved reserved -VERBOSE reserved (can be function or type) -VERSION non-reserved non-reserved non-reserved -VERSIONING reserved -VIEW non-reserved non-reserved non-reserved reserved -VOLATILE non-reserved -WHEN reserved reserved reserved reserved -WHENEVER reserved reserved reserved -WHERE reserved reserved reserved reserved -WHITESPACE non-reserved non-reserved non-reserved -WIDTH_BUCKET reserved reserved -WINDOW reserved reserved reserved -WITH reserved reserved reserved reserved -WITHIN reserved reserved -WITHOUT non-reserved reserved reserved -WORK non-reserved non-reserved non-reserved reserved -WRAPPER non-reserved non-reserved non-reserved -WRITE non-reserved non-reserved non-reserved reserved -XML non-reserved reserved reserved -XMLAGG reserved reserved -XMLATTRIBUTES non-reserved (cannot be function or type) reserved reserved -XMLBINARY reserved reserved -XMLCAST reserved reserved -XMLCOMMENT reserved reserved -XMLCONCAT non-reserved (cannot be function or type) reserved reserved -XMLDECLARATION non-reserved non-reserved -XMLDOCUMENT reserved reserved -XMLELEMENT non-reserved (cannot be function or type) reserved reserved -XMLEXISTS non-reserved (cannot be function or type) reserved reserved -XMLFOREST non-reserved (cannot be function or type) reserved reserved -XMLITERATE reserved reserved -XMLNAMESPACES reserved reserved -XMLPARSE non-reserved (cannot be function or type) reserved reserved -XMLPI non-reserved (cannot be function or type) reserved reserved -XMLQUERY reserved reserved -XMLROOT non-reserved (cannot be function or type) -XMLSCHEMA non-reserved non-reserved -XMLSERIALIZE non-reserved (cannot be function or type) reserved reserved -XMLTABLE reserved reserved -XMLTEXT reserved reserved -XMLVALIDATE reserved reserved -YEAR non-reserved reserved reserved reserved -YES non-reserved non-reserved non-reserved -ZONE non-reserved non-reserved non-reserved reserved \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/processors.go b/vendor/github.com/go-xorm/xorm/processors.go deleted file mode 100644 index dcd9c6ac0b..0000000000 --- a/vendor/github.com/go-xorm/xorm/processors.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -// BeforeInsertProcessor executed before an object is initially persisted to the database -type BeforeInsertProcessor interface { - BeforeInsert() -} - -// BeforeUpdateProcessor executed before an object is updated -type BeforeUpdateProcessor interface { - BeforeUpdate() -} - -// BeforeDeleteProcessor executed before an object is deleted -type BeforeDeleteProcessor interface { - BeforeDelete() -} - -// BeforeSetProcessor executed before data set to the struct fields -type BeforeSetProcessor interface { - BeforeSet(string, Cell) -} - -// AfterSetProcessor executed after data set to the struct fields -type AfterSetProcessor interface { - AfterSet(string, Cell) -} - -// AfterInsertProcessor executed after an object is persisted to the database -type AfterInsertProcessor interface { - AfterInsert() -} - -// AfterUpdateProcessor executed after an object has been updated -type AfterUpdateProcessor interface { - AfterUpdate() -} - -// AfterDeleteProcessor executed after an object has been deleted -type AfterDeleteProcessor interface { - AfterDelete() -} - -// AfterLoadProcessor executed after an ojbect has been loaded from database -type AfterLoadProcessor interface { - AfterLoad() -} - -// AfterLoadSessionProcessor executed after an ojbect has been loaded from database with session parameter -type AfterLoadSessionProcessor interface { - AfterLoad(*Session) -} - -type executedProcessorFunc func(*Session, interface{}) error - -type executedProcessor struct { - fun executedProcessorFunc - session *Session - bean interface{} -} - -func (executor *executedProcessor) execute() error { - return executor.fun(executor.session, executor.bean) -} - -func (session *Session) executeProcessors() error { - processors := session.afterProcessors - session.afterProcessors = make([]executedProcessor, 0) - for _, processor := range processors { - if err := processor.execute(); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/rows.go b/vendor/github.com/go-xorm/xorm/rows.go deleted file mode 100644 index bdd44589f8..0000000000 --- a/vendor/github.com/go-xorm/xorm/rows.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql" - "fmt" - "reflect" - - "xorm.io/core" -) - -// Rows rows wrapper a rows to -type Rows struct { - session *Session - rows *core.Rows - beanType reflect.Type - lastError error -} - -func newRows(session *Session, bean interface{}) (*Rows, error) { - rows := new(Rows) - rows.session = session - rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type() - - var sqlStr string - var args []interface{} - var err error - - if err = rows.session.statement.setRefBean(bean); err != nil { - return nil, err - } - - if len(session.statement.TableName()) <= 0 { - return nil, ErrTableNotFound - } - - if rows.session.statement.RawSQL == "" { - sqlStr, args, err = rows.session.statement.genGetSQL(bean) - if err != nil { - return nil, err - } - } else { - sqlStr = rows.session.statement.RawSQL - args = rows.session.statement.RawParams - } - - rows.rows, err = rows.session.queryRows(sqlStr, args...) - if err != nil { - rows.lastError = err - rows.Close() - return nil, err - } - - return rows, nil -} - -// Next move cursor to next record, return false if end has reached -func (rows *Rows) Next() bool { - if rows.lastError == nil && rows.rows != nil { - hasNext := rows.rows.Next() - if !hasNext { - rows.lastError = sql.ErrNoRows - } - return hasNext - } - return false -} - -// Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close. -func (rows *Rows) Err() error { - return rows.lastError -} - -// Scan row record to bean properties -func (rows *Rows) Scan(bean interface{}) error { - if rows.lastError != nil { - return rows.lastError - } - - if reflect.Indirect(reflect.ValueOf(bean)).Type() != rows.beanType { - return fmt.Errorf("scan arg is incompatible type to [%v]", rows.beanType) - } - - if err := rows.session.statement.setRefBean(bean); err != nil { - return err - } - - fields, err := rows.rows.Columns() - if err != nil { - return err - } - - scanResults, err := rows.session.row2Slice(rows.rows, fields, bean) - if err != nil { - return err - } - - dataStruct := rValue(bean) - _, err = rows.session.slice2Bean(scanResults, fields, bean, &dataStruct, rows.session.statement.RefTable) - if err != nil { - return err - } - - return rows.session.executeProcessors() -} - -// Close session if session.IsAutoClose is true, and claimed any opened resources -func (rows *Rows) Close() error { - if rows.session.isAutoClose { - defer rows.session.Close() - } - - if rows.rows != nil { - return rows.rows.Close() - } - - return rows.lastError -} diff --git a/vendor/github.com/go-xorm/xorm/session.go b/vendor/github.com/go-xorm/xorm/session.go deleted file mode 100644 index b33955fdce..0000000000 --- a/vendor/github.com/go-xorm/xorm/session.go +++ /dev/null @@ -1,866 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "context" - "database/sql" - "errors" - "fmt" - "hash/crc32" - "reflect" - "strings" - "time" - - "xorm.io/core" -) - -type sessionType int - -const ( - engineSession sessionType = iota - groupSession -) - -// Session keep a pointer to sql.DB and provides all execution of all -// kind of database operations. -type Session struct { - db *core.DB - engine *Engine - tx *core.Tx - statement Statement - isAutoCommit bool - isCommitedOrRollbacked bool - isAutoClose bool - - // Automatically reset the statement after operations that execute a SQL - // query such as Count(), Find(), Get(), ... - autoResetStatement bool - - // !nashtsai! storing these beans due to yet committed tx - afterInsertBeans map[interface{}]*[]func(interface{}) - afterUpdateBeans map[interface{}]*[]func(interface{}) - afterDeleteBeans map[interface{}]*[]func(interface{}) - // -- - - beforeClosures []func(interface{}) - afterClosures []func(interface{}) - - afterProcessors []executedProcessor - - prepareStmt bool - stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr)) - - // !evalphobia! stored the last executed query on this session - //beforeSQLExec func(string, ...interface{}) - lastSQL string - lastSQLArgs []interface{} - - ctx context.Context - sessionType sessionType -} - -// Clone copy all the session's content and return a new session -func (session *Session) Clone() *Session { - var sess = *session - return &sess -} - -// Init reset the session as the init status. -func (session *Session) Init() { - session.statement.Init() - session.statement.Engine = session.engine - session.isAutoCommit = true - session.isCommitedOrRollbacked = false - session.isAutoClose = false - session.autoResetStatement = true - session.prepareStmt = false - - // !nashtsai! is lazy init better? - session.afterInsertBeans = make(map[interface{}]*[]func(interface{}), 0) - session.afterUpdateBeans = make(map[interface{}]*[]func(interface{}), 0) - session.afterDeleteBeans = make(map[interface{}]*[]func(interface{}), 0) - session.beforeClosures = make([]func(interface{}), 0) - session.afterClosures = make([]func(interface{}), 0) - session.stmtCache = make(map[uint32]*core.Stmt) - - session.afterProcessors = make([]executedProcessor, 0) - - session.lastSQL = "" - session.lastSQLArgs = []interface{}{} - - session.ctx = session.engine.defaultContext -} - -// Close release the connection from pool -func (session *Session) Close() { - for _, v := range session.stmtCache { - v.Close() - } - - if session.db != nil { - // When Close be called, if session is a transaction and do not call - // Commit or Rollback, then call Rollback. - if session.tx != nil && !session.isCommitedOrRollbacked { - session.Rollback() - } - session.tx = nil - session.stmtCache = nil - session.db = nil - } -} - -// ContextCache enable context cache or not -func (session *Session) ContextCache(context ContextCache) *Session { - session.statement.context = context - return session -} - -// IsClosed returns if session is closed -func (session *Session) IsClosed() bool { - return session.db == nil -} - -func (session *Session) resetStatement() { - if session.autoResetStatement { - session.statement.Init() - } -} - -// Prepare set a flag to session that should be prepare statement before execute query -func (session *Session) Prepare() *Session { - session.prepareStmt = true - return session -} - -// Before Apply before Processor, affected bean is passed to closure arg -func (session *Session) Before(closures func(interface{})) *Session { - if closures != nil { - session.beforeClosures = append(session.beforeClosures, closures) - } - return session -} - -// After Apply after Processor, affected bean is passed to closure arg -func (session *Session) After(closures func(interface{})) *Session { - if closures != nil { - session.afterClosures = append(session.afterClosures, closures) - } - return session -} - -// Table can input a string or pointer to struct for special a table to operate. -func (session *Session) Table(tableNameOrBean interface{}) *Session { - session.statement.Table(tableNameOrBean) - return session -} - -// Alias set the table alias -func (session *Session) Alias(alias string) *Session { - session.statement.Alias(alias) - return session -} - -// NoCascade indicate that no cascade load child object -func (session *Session) NoCascade() *Session { - session.statement.UseCascade = false - return session -} - -// ForUpdate Set Read/Write locking for UPDATE -func (session *Session) ForUpdate() *Session { - session.statement.IsForUpdate = true - return session -} - -// NoAutoCondition disable generate SQL condition from beans -func (session *Session) NoAutoCondition(no ...bool) *Session { - session.statement.NoAutoCondition(no...) - return session -} - -// Limit provide limit and offset query condition -func (session *Session) Limit(limit int, start ...int) *Session { - session.statement.Limit(limit, start...) - return session -} - -// OrderBy provide order by query condition, the input parameter is the content -// after order by on a sql statement. -func (session *Session) OrderBy(order string) *Session { - session.statement.OrderBy(order) - return session -} - -// Desc provide desc order by query condition, the input parameters are columns. -func (session *Session) Desc(colNames ...string) *Session { - session.statement.Desc(colNames...) - return session -} - -// Asc provide asc order by query condition, the input parameters are columns. -func (session *Session) Asc(colNames ...string) *Session { - session.statement.Asc(colNames...) - return session -} - -// StoreEngine is only avialble mysql dialect currently -func (session *Session) StoreEngine(storeEngine string) *Session { - session.statement.StoreEngine = storeEngine - return session -} - -// Charset is only avialble mysql dialect currently -func (session *Session) Charset(charset string) *Session { - session.statement.Charset = charset - return session -} - -// Cascade indicates if loading sub Struct -func (session *Session) Cascade(trueOrFalse ...bool) *Session { - if len(trueOrFalse) >= 1 { - session.statement.UseCascade = trueOrFalse[0] - } - return session -} - -// NoCache ask this session do not retrieve data from cache system and -// get data from database directly. -func (session *Session) NoCache() *Session { - session.statement.UseCache = false - return session -} - -// Join join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN -func (session *Session) Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session { - session.statement.Join(joinOperator, tablename, condition, args...) - return session -} - -// GroupBy Generate Group By statement -func (session *Session) GroupBy(keys string) *Session { - session.statement.GroupBy(keys) - return session -} - -// Having Generate Having statement -func (session *Session) Having(conditions string) *Session { - session.statement.Having(conditions) - return session -} - -// DB db return the wrapper of sql.DB -func (session *Session) DB() *core.DB { - if session.db == nil { - session.db = session.engine.db - session.stmtCache = make(map[uint32]*core.Stmt, 0) - } - return session.db -} - -func cleanupProcessorsClosures(slices *[]func(interface{})) { - if len(*slices) > 0 { - *slices = make([]func(interface{}), 0) - } -} - -func (session *Session) canCache() bool { - if session.statement.RefTable == nil || - session.statement.JoinStr != "" || - session.statement.RawSQL != "" || - !session.statement.UseCache || - session.statement.IsForUpdate || - session.tx != nil || - len(session.statement.selectStr) > 0 { - return false - } - return true -} - -func (session *Session) doPrepare(db *core.DB, sqlStr string) (stmt *core.Stmt, err error) { - crc := crc32.ChecksumIEEE([]byte(sqlStr)) - // TODO try hash(sqlStr+len(sqlStr)) - var has bool - stmt, has = session.stmtCache[crc] - if !has { - stmt, err = db.PrepareContext(session.ctx, sqlStr) - if err != nil { - return nil, err - } - session.stmtCache[crc] = stmt - } - return -} - -func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) (*reflect.Value, error) { - var col *core.Column - if col = table.GetColumnIdx(key, idx); col == nil { - return nil, ErrFieldIsNotExist{key, table.Name} - } - - fieldValue, err := col.ValueOfV(dataStruct) - if err != nil { - return nil, err - } - - if !fieldValue.IsValid() || !fieldValue.CanSet() { - return nil, ErrFieldIsNotValid{key, table.Name} - } - - return fieldValue, nil -} - -// Cell cell is a result of one column field -type Cell *interface{} - -func (session *Session) rows2Beans(rows *core.Rows, fields []string, - table *core.Table, newElemFunc func([]string) reflect.Value, - sliceValueSetFunc func(*reflect.Value, core.PK) error) error { - for rows.Next() { - var newValue = newElemFunc(fields) - bean := newValue.Interface() - dataStruct := newValue.Elem() - - // handle beforeClosures - scanResults, err := session.row2Slice(rows, fields, bean) - if err != nil { - return err - } - pk, err := session.slice2Bean(scanResults, fields, bean, &dataStruct, table) - if err != nil { - return err - } - session.afterProcessors = append(session.afterProcessors, executedProcessor{ - fun: func(*Session, interface{}) error { - return sliceValueSetFunc(&newValue, pk) - }, - session: session, - bean: bean, - }) - } - return nil -} - -func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interface{}) ([]interface{}, error) { - for _, closure := range session.beforeClosures { - closure(bean) - } - - scanResults := make([]interface{}, len(fields)) - for i := 0; i < len(fields); i++ { - var cell interface{} - scanResults[i] = &cell - } - if err := rows.Scan(scanResults...); err != nil { - return nil, err - } - - if b, hasBeforeSet := bean.(BeforeSetProcessor); hasBeforeSet { - for ii, key := range fields { - b.BeforeSet(key, Cell(scanResults[ii].(*interface{}))) - } - } - return scanResults, nil -} - -func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) { - defer func() { - if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet { - for ii, key := range fields { - b.AfterSet(key, Cell(scanResults[ii].(*interface{}))) - } - } - }() - - // handle afterClosures - for _, closure := range session.afterClosures { - session.afterProcessors = append(session.afterProcessors, executedProcessor{ - fun: func(sess *Session, bean interface{}) error { - closure(bean) - return nil - }, - session: session, - bean: bean, - }) - } - - if a, has := bean.(AfterLoadProcessor); has { - session.afterProcessors = append(session.afterProcessors, executedProcessor{ - fun: func(sess *Session, bean interface{}) error { - a.AfterLoad() - return nil - }, - session: session, - bean: bean, - }) - } - - if a, has := bean.(AfterLoadSessionProcessor); has { - session.afterProcessors = append(session.afterProcessors, executedProcessor{ - fun: func(sess *Session, bean interface{}) error { - a.AfterLoad(sess) - return nil - }, - session: session, - bean: bean, - }) - } - - var tempMap = make(map[string]int) - var pk core.PK - for ii, key := range fields { - var idx int - var ok bool - var lKey = strings.ToLower(key) - if idx, ok = tempMap[lKey]; !ok { - idx = 0 - } else { - idx = idx + 1 - } - tempMap[lKey] = idx - - fieldValue, err := session.getField(dataStruct, key, table, idx) - if err != nil { - if !strings.Contains(err.Error(), "is not valid") { - session.engine.logger.Warn(err) - } - continue - } - if fieldValue == nil { - continue - } - rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii])) - - // if row is null then ignore - if rawValue.Interface() == nil { - continue - } - - if fieldValue.CanAddr() { - if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { - if data, err := value2Bytes(&rawValue); err == nil { - if err := structConvert.FromDB(data); err != nil { - return nil, err - } - } else { - return nil, err - } - continue - } - } - - if _, ok := fieldValue.Interface().(core.Conversion); ok { - if data, err := value2Bytes(&rawValue); err == nil { - if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() { - fieldValue.Set(reflect.New(fieldValue.Type().Elem())) - } - fieldValue.Interface().(core.Conversion).FromDB(data) - } else { - return nil, err - } - continue - } - - rawValueType := reflect.TypeOf(rawValue.Interface()) - vv := reflect.ValueOf(rawValue.Interface()) - col := table.GetColumnIdx(key, idx) - if col.IsPrimaryKey { - pk = append(pk, rawValue.Interface()) - } - fieldType := fieldValue.Type() - hasAssigned := false - - if col.SQLType.IsJson() { - var bs []byte - if rawValueType.Kind() == reflect.String { - bs = []byte(vv.String()) - } else if rawValueType.ConvertibleTo(core.BytesType) { - bs = vv.Bytes() - } else { - return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind()) - } - - hasAssigned = true - - if len(bs) > 0 { - if fieldType.Kind() == reflect.String { - fieldValue.SetString(string(bs)) - continue - } - if fieldValue.CanAddr() { - err := DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface()) - if err != nil { - return nil, err - } - } else { - x := reflect.New(fieldType) - err := DefaultJSONHandler.Unmarshal(bs, x.Interface()) - if err != nil { - return nil, err - } - fieldValue.Set(x.Elem()) - } - } - - continue - } - - switch fieldType.Kind() { - case reflect.Complex64, reflect.Complex128: - // TODO: reimplement this - var bs []byte - if rawValueType.Kind() == reflect.String { - bs = []byte(vv.String()) - } else if rawValueType.ConvertibleTo(core.BytesType) { - bs = vv.Bytes() - } - - hasAssigned = true - if len(bs) > 0 { - if fieldValue.CanAddr() { - err := DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface()) - if err != nil { - return nil, err - } - } else { - x := reflect.New(fieldType) - err := DefaultJSONHandler.Unmarshal(bs, x.Interface()) - if err != nil { - return nil, err - } - fieldValue.Set(x.Elem()) - } - } - case reflect.Slice, reflect.Array: - switch rawValueType.Kind() { - case reflect.Slice, reflect.Array: - switch rawValueType.Elem().Kind() { - case reflect.Uint8: - if fieldType.Elem().Kind() == reflect.Uint8 { - hasAssigned = true - if col.SQLType.IsText() { - x := reflect.New(fieldType) - err := DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface()) - if err != nil { - return nil, err - } - fieldValue.Set(x.Elem()) - } else { - if fieldValue.Len() > 0 { - for i := 0; i < fieldValue.Len(); i++ { - if i < vv.Len() { - fieldValue.Index(i).Set(vv.Index(i)) - } - } - } else { - for i := 0; i < vv.Len(); i++ { - fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i))) - } - } - } - } - } - } - case reflect.String: - if rawValueType.Kind() == reflect.String { - hasAssigned = true - fieldValue.SetString(vv.String()) - } - case reflect.Bool: - if rawValueType.Kind() == reflect.Bool { - hasAssigned = true - fieldValue.SetBool(vv.Bool()) - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - switch rawValueType.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - hasAssigned = true - fieldValue.SetInt(vv.Int()) - } - case reflect.Float32, reflect.Float64: - switch rawValueType.Kind() { - case reflect.Float32, reflect.Float64: - hasAssigned = true - fieldValue.SetFloat(vv.Float()) - } - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - switch rawValueType.Kind() { - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - hasAssigned = true - fieldValue.SetUint(vv.Uint()) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - hasAssigned = true - fieldValue.SetUint(uint64(vv.Int())) - } - case reflect.Struct: - if fieldType.ConvertibleTo(core.TimeType) { - dbTZ := session.engine.DatabaseTZ - if col.TimeZone != nil { - dbTZ = col.TimeZone - } - - if rawValueType == core.TimeType { - hasAssigned = true - - t := vv.Convert(core.TimeType).Interface().(time.Time) - - z, _ := t.Zone() - // set new location if database don't save timezone or give an incorrect timezone - if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location - session.engine.logger.Debugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location()) - t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), - t.Minute(), t.Second(), t.Nanosecond(), dbTZ) - } - - t = t.In(session.engine.TZLocation) - fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) - } else if rawValueType == core.IntType || rawValueType == core.Int64Type || - rawValueType == core.Int32Type { - hasAssigned = true - - t := time.Unix(vv.Int(), 0).In(session.engine.TZLocation) - fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) - } else { - if d, ok := vv.Interface().([]uint8); ok { - hasAssigned = true - t, err := session.byte2Time(col, d) - if err != nil { - session.engine.logger.Error("byte2Time error:", err.Error()) - hasAssigned = false - } else { - fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) - } - } else if d, ok := vv.Interface().(string); ok { - hasAssigned = true - t, err := session.str2Time(col, d) - if err != nil { - session.engine.logger.Error("byte2Time error:", err.Error()) - hasAssigned = false - } else { - fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) - } - } else { - return nil, fmt.Errorf("rawValueType is %v, value is %v", rawValueType, vv.Interface()) - } - } - } else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok { - // !! 增加支持sql.Scanner接口的结构,如sql.NullString - hasAssigned = true - if err := nulVal.Scan(vv.Interface()); err != nil { - session.engine.logger.Error("sql.Sanner error:", err.Error()) - hasAssigned = false - } - } else if col.SQLType.IsJson() { - if rawValueType.Kind() == reflect.String { - hasAssigned = true - x := reflect.New(fieldType) - if len([]byte(vv.String())) > 0 { - err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), x.Interface()) - if err != nil { - return nil, err - } - fieldValue.Set(x.Elem()) - } - } else if rawValueType.Kind() == reflect.Slice { - hasAssigned = true - x := reflect.New(fieldType) - if len(vv.Bytes()) > 0 { - err := DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface()) - if err != nil { - return nil, err - } - fieldValue.Set(x.Elem()) - } - } - } else if session.statement.UseCascade { - table, err := session.engine.autoMapType(*fieldValue) - if err != nil { - return nil, err - } - - hasAssigned = true - if len(table.PrimaryKeys) != 1 { - return nil, errors.New("unsupported non or composited primary key cascade") - } - var pk = make(core.PK, len(table.PrimaryKeys)) - pk[0], err = asKind(vv, rawValueType) - if err != nil { - return nil, err - } - - if !isPKZero(pk) { - // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch - // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne - // property to be fetched lazily - structInter := reflect.New(fieldValue.Type()) - has, err := session.ID(pk).NoCascade().get(structInter.Interface()) - if err != nil { - return nil, err - } - if has { - fieldValue.Set(structInter.Elem()) - } else { - return nil, errors.New("cascade obj is not exist") - } - } - } - case reflect.Ptr: - // !nashtsai! TODO merge duplicated codes above - switch fieldType { - // following types case matching ptr's native type, therefore assign ptr directly - case core.PtrStringType: - if rawValueType.Kind() == reflect.String { - x := vv.String() - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrBoolType: - if rawValueType.Kind() == reflect.Bool { - x := vv.Bool() - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrTimeType: - if rawValueType == core.PtrTimeType { - hasAssigned = true - var x = rawValue.Interface().(time.Time) - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrFloat64Type: - if rawValueType.Kind() == reflect.Float64 { - x := vv.Float() - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrUint64Type: - if rawValueType.Kind() == reflect.Int64 { - var x = uint64(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrInt64Type: - if rawValueType.Kind() == reflect.Int64 { - x := vv.Int() - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrFloat32Type: - if rawValueType.Kind() == reflect.Float64 { - var x = float32(vv.Float()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrIntType: - if rawValueType.Kind() == reflect.Int64 { - var x = int(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrInt32Type: - if rawValueType.Kind() == reflect.Int64 { - var x = int32(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrInt8Type: - if rawValueType.Kind() == reflect.Int64 { - var x = int8(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrInt16Type: - if rawValueType.Kind() == reflect.Int64 { - var x = int16(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrUintType: - if rawValueType.Kind() == reflect.Int64 { - var x = uint(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.PtrUint32Type: - if rawValueType.Kind() == reflect.Int64 { - var x = uint32(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.Uint8Type: - if rawValueType.Kind() == reflect.Int64 { - var x = uint8(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.Uint16Type: - if rawValueType.Kind() == reflect.Int64 { - var x = uint16(vv.Int()) - hasAssigned = true - fieldValue.Set(reflect.ValueOf(&x)) - } - case core.Complex64Type: - var x complex64 - if len([]byte(vv.String())) > 0 { - err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x) - if err != nil { - return nil, err - } - fieldValue.Set(reflect.ValueOf(&x)) - } - hasAssigned = true - case core.Complex128Type: - var x complex128 - if len([]byte(vv.String())) > 0 { - err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x) - if err != nil { - return nil, err - } - fieldValue.Set(reflect.ValueOf(&x)) - } - hasAssigned = true - } // switch fieldType - } // switch fieldType.Kind() - - // !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value - if !hasAssigned { - data, err := value2Bytes(&rawValue) - if err != nil { - return nil, err - } - - if err = session.bytes2Value(col, fieldValue, data); err != nil { - return nil, err - } - } - } - return pk, nil -} - -// saveLastSQL stores executed query information -func (session *Session) saveLastSQL(sql string, args ...interface{}) { - session.lastSQL = sql - session.lastSQLArgs = args - session.engine.logSQL(sql, args...) -} - -// LastSQL returns last query information -func (session *Session) LastSQL() (string, []interface{}) { - return session.lastSQL, session.lastSQLArgs -} - -// Unscoped always disable struct tag "deleted" -func (session *Session) Unscoped() *Session { - session.statement.Unscoped() - return session -} - -func (session *Session) incrVersionFieldValue(fieldValue *reflect.Value) { - switch fieldValue.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - fieldValue.SetInt(fieldValue.Int() + 1) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - fieldValue.SetUint(fieldValue.Uint() + 1) - } -} diff --git a/vendor/github.com/go-xorm/xorm/session_cols.go b/vendor/github.com/go-xorm/xorm/session_cols.go deleted file mode 100644 index 1558074f3d..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_cols.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "reflect" - "strings" - "time" - - "xorm.io/core" -) - -func setColumnInt(bean interface{}, col *core.Column, t int64) { - v, err := col.ValueOf(bean) - if err != nil { - return - } - if v.CanSet() { - switch v.Type().Kind() { - case reflect.Int, reflect.Int64, reflect.Int32: - v.SetInt(t) - case reflect.Uint, reflect.Uint64, reflect.Uint32: - v.SetUint(uint64(t)) - } - } -} - -func setColumnTime(bean interface{}, col *core.Column, t time.Time) { - v, err := col.ValueOf(bean) - if err != nil { - return - } - if v.CanSet() { - switch v.Type().Kind() { - case reflect.Struct: - v.Set(reflect.ValueOf(t).Convert(v.Type())) - case reflect.Int, reflect.Int64, reflect.Int32: - v.SetInt(t.Unix()) - case reflect.Uint, reflect.Uint64, reflect.Uint32: - v.SetUint(uint64(t.Unix())) - } - } -} - -func getFlagForColumn(m map[string]bool, col *core.Column) (val bool, has bool) { - if len(m) == 0 { - return false, false - } - - n := len(col.Name) - - for mk := range m { - if len(mk) != n { - continue - } - if strings.EqualFold(mk, col.Name) { - return m[mk], true - } - } - - return false, false -} - -func col2NewCols(columns ...string) []string { - newColumns := make([]string, 0, len(columns)) - for _, col := range columns { - col = strings.Replace(col, "`", "", -1) - col = strings.Replace(col, `"`, "", -1) - ccols := strings.Split(col, ",") - for _, c := range ccols { - newColumns = append(newColumns, strings.TrimSpace(c)) - } - } - return newColumns -} - -// Incr provides a query string like "count = count + 1" -func (session *Session) Incr(column string, arg ...interface{}) *Session { - session.statement.Incr(column, arg...) - return session -} - -// Decr provides a query string like "count = count - 1" -func (session *Session) Decr(column string, arg ...interface{}) *Session { - session.statement.Decr(column, arg...) - return session -} - -// SetExpr provides a query string like "column = {expression}" -func (session *Session) SetExpr(column string, expression interface{}) *Session { - session.statement.SetExpr(column, expression) - return session -} - -// Select provides some columns to special -func (session *Session) Select(str string) *Session { - session.statement.Select(str) - return session -} - -// Cols provides some columns to special -func (session *Session) Cols(columns ...string) *Session { - session.statement.Cols(columns...) - return session -} - -// AllCols ask all columns -func (session *Session) AllCols() *Session { - session.statement.AllCols() - return session -} - -// MustCols specify some columns must use even if they are empty -func (session *Session) MustCols(columns ...string) *Session { - session.statement.MustCols(columns...) - return session -} - -// UseBool automatically retrieve condition according struct, but -// if struct has bool field, it will ignore them. So use UseBool -// to tell system to do not ignore them. -// If no parameters, it will use all the bool field of struct, or -// it will use parameters's columns -func (session *Session) UseBool(columns ...string) *Session { - session.statement.UseBool(columns...) - return session -} - -// Distinct use for distinct columns. Caution: when you are using cache, -// distinct will not be cached because cache system need id, -// but distinct will not provide id -func (session *Session) Distinct(columns ...string) *Session { - session.statement.Distinct(columns...) - return session -} - -// Omit Only not use the parameters as select or update columns -func (session *Session) Omit(columns ...string) *Session { - session.statement.Omit(columns...) - return session -} - -// Nullable Set null when column is zero-value and nullable for update -func (session *Session) Nullable(columns ...string) *Session { - session.statement.Nullable(columns...) - return session -} - -// NoAutoTime means do not automatically give created field and updated field -// the current time on the current session temporarily -func (session *Session) NoAutoTime() *Session { - session.statement.UseAutoTime = false - return session -} diff --git a/vendor/github.com/go-xorm/xorm/session_cond.go b/vendor/github.com/go-xorm/xorm/session_cond.go deleted file mode 100644 index b16bdea8e0..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_cond.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import "xorm.io/builder" - -// Sql provides raw sql input parameter. When you have a complex SQL statement -// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL. -// -// Deprecated: use SQL instead. -func (session *Session) Sql(query string, args ...interface{}) *Session { - return session.SQL(query, args...) -} - -// SQL provides raw sql input parameter. When you have a complex SQL statement -// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL. -func (session *Session) SQL(query interface{}, args ...interface{}) *Session { - session.statement.SQL(query, args...) - return session -} - -// Where provides custom query condition. -func (session *Session) Where(query interface{}, args ...interface{}) *Session { - session.statement.Where(query, args...) - return session -} - -// And provides custom query condition. -func (session *Session) And(query interface{}, args ...interface{}) *Session { - session.statement.And(query, args...) - return session -} - -// Or provides custom query condition. -func (session *Session) Or(query interface{}, args ...interface{}) *Session { - session.statement.Or(query, args...) - return session -} - -// Id provides converting id as a query condition -// -// Deprecated: use ID instead -func (session *Session) Id(id interface{}) *Session { - return session.ID(id) -} - -// ID provides converting id as a query condition -func (session *Session) ID(id interface{}) *Session { - session.statement.ID(id) - return session -} - -// In provides a query string like "id in (1, 2, 3)" -func (session *Session) In(column string, args ...interface{}) *Session { - session.statement.In(column, args...) - return session -} - -// NotIn provides a query string like "id in (1, 2, 3)" -func (session *Session) NotIn(column string, args ...interface{}) *Session { - session.statement.NotIn(column, args...) - return session -} - -// Conds returns session query conditions except auto bean conditions -func (session *Session) Conds() builder.Cond { - return session.statement.cond -} diff --git a/vendor/github.com/go-xorm/xorm/session_context.go b/vendor/github.com/go-xorm/xorm/session_context.go deleted file mode 100644 index 915f056858..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_context.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2019 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import "context" - -// Context sets the context on this session -func (session *Session) Context(ctx context.Context) *Session { - session.ctx = ctx - return session -} - -// PingContext test if database is ok -func (session *Session) PingContext(ctx context.Context) error { - if session.isAutoClose { - defer session.Close() - } - - session.engine.logger.Infof("PING DATABASE %v", session.engine.DriverName()) - return session.DB().PingContext(ctx) -} diff --git a/vendor/github.com/go-xorm/xorm/session_convert.go b/vendor/github.com/go-xorm/xorm/session_convert.go deleted file mode 100644 index caff5d2624..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_convert.go +++ /dev/null @@ -1,661 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql" - "database/sql/driver" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "time" - - "xorm.io/core" -) - -func (session *Session) str2Time(col *core.Column, data string) (outTime time.Time, outErr error) { - sdata := strings.TrimSpace(data) - var x time.Time - var err error - - var parseLoc = session.engine.DatabaseTZ - if col.TimeZone != nil { - parseLoc = col.TimeZone - } - - if sdata == zeroTime0 || sdata == zeroTime1 { - } else if !strings.ContainsAny(sdata, "- :") { // !nashtsai! has only found that mymysql driver is using this for time type column - // time stamp - sd, err := strconv.ParseInt(sdata, 10, 64) - if err == nil { - x = time.Unix(sd, 0) - //session.engine.logger.Debugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - } else { - //session.engine.logger.Debugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - } - } else if len(sdata) > 19 && strings.Contains(sdata, "-") { - x, err = time.ParseInLocation(time.RFC3339Nano, sdata, parseLoc) - session.engine.logger.Debugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - if err != nil { - x, err = time.ParseInLocation("2006-01-02 15:04:05.999999999", sdata, parseLoc) - //session.engine.logger.Debugf("time(2) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - } - if err != nil { - x, err = time.ParseInLocation("2006-01-02 15:04:05.9999999 Z07:00", sdata, parseLoc) - //session.engine.logger.Debugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - } - } else if len(sdata) == 19 && strings.Contains(sdata, "-") { - x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, parseLoc) - //session.engine.logger.Debugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - } else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' { - x, err = time.ParseInLocation("2006-01-02", sdata, parseLoc) - //session.engine.logger.Debugf("time(5) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - } else if col.SQLType.Name == core.Time { - if strings.Contains(sdata, " ") { - ssd := strings.Split(sdata, " ") - sdata = ssd[1] - } - - sdata = strings.TrimSpace(sdata) - if session.engine.dialect.DBType() == core.MYSQL && len(sdata) > 8 { - sdata = sdata[len(sdata)-8:] - } - - st := fmt.Sprintf("2006-01-02 %v", sdata) - x, err = time.ParseInLocation("2006-01-02 15:04:05", st, parseLoc) - //session.engine.logger.Debugf("time(6) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) - } else { - outErr = fmt.Errorf("unsupported time format %v", sdata) - return - } - if err != nil { - outErr = fmt.Errorf("unsupported time format %v: %v", sdata, err) - return - } - outTime = x.In(session.engine.TZLocation) - return -} - -func (session *Session) byte2Time(col *core.Column, data []byte) (outTime time.Time, outErr error) { - return session.str2Time(col, string(data)) -} - -// convert a db data([]byte) to a field value -func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, data []byte) error { - if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { - return structConvert.FromDB(data) - } - - if structConvert, ok := fieldValue.Interface().(core.Conversion); ok { - return structConvert.FromDB(data) - } - - var v interface{} - key := col.Name - fieldType := fieldValue.Type() - - switch fieldType.Kind() { - case reflect.Complex64, reflect.Complex128: - x := reflect.New(fieldType) - if len(data) > 0 { - err := DefaultJSONHandler.Unmarshal(data, x.Interface()) - if err != nil { - session.engine.logger.Error(err) - return err - } - fieldValue.Set(x.Elem()) - } - case reflect.Slice, reflect.Array, reflect.Map: - v = data - t := fieldType.Elem() - k := t.Kind() - if col.SQLType.IsText() { - x := reflect.New(fieldType) - if len(data) > 0 { - err := DefaultJSONHandler.Unmarshal(data, x.Interface()) - if err != nil { - session.engine.logger.Error(err) - return err - } - fieldValue.Set(x.Elem()) - } - } else if col.SQLType.IsBlob() { - if k == reflect.Uint8 { - fieldValue.Set(reflect.ValueOf(v)) - } else { - x := reflect.New(fieldType) - if len(data) > 0 { - err := DefaultJSONHandler.Unmarshal(data, x.Interface()) - if err != nil { - session.engine.logger.Error(err) - return err - } - fieldValue.Set(x.Elem()) - } - } - } else { - return ErrUnSupportedType - } - case reflect.String: - fieldValue.SetString(string(data)) - case reflect.Bool: - v, err := asBool(data) - if err != nil { - return fmt.Errorf("arg %v as bool: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(v)) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - sdata := string(data) - var x int64 - var err error - // for mysql, when use bit, it returned \x01 - if col.SQLType.Name == core.Bit && - session.engine.dialect.DBType() == core.MYSQL { // !nashtsai! TODO dialect needs to provide conversion interface API - if len(data) == 1 { - x = int64(data[0]) - } else { - x = 0 - } - } else if strings.HasPrefix(sdata, "0x") { - x, err = strconv.ParseInt(sdata, 16, 64) - } else if strings.HasPrefix(sdata, "0") { - x, err = strconv.ParseInt(sdata, 8, 64) - } else if strings.EqualFold(sdata, "true") { - x = 1 - } else if strings.EqualFold(sdata, "false") { - x = 0 - } else { - x, err = strconv.ParseInt(sdata, 10, 64) - } - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.SetInt(x) - case reflect.Float32, reflect.Float64: - x, err := strconv.ParseFloat(string(data), 64) - if err != nil { - return fmt.Errorf("arg %v as float64: %s", key, err.Error()) - } - fieldValue.SetFloat(x) - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - x, err := strconv.ParseUint(string(data), 10, 64) - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.SetUint(x) - //Currently only support Time type - case reflect.Struct: - // !! 增加支持sql.Scanner接口的结构,如sql.NullString - if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok { - if err := nulVal.Scan(data); err != nil { - return fmt.Errorf("sql.Scan(%v) failed: %s ", data, err.Error()) - } - } else { - if fieldType.ConvertibleTo(core.TimeType) { - x, err := session.byte2Time(col, data) - if err != nil { - return err - } - v = x - fieldValue.Set(reflect.ValueOf(v).Convert(fieldType)) - } else if session.statement.UseCascade { - table, err := session.engine.autoMapType(*fieldValue) - if err != nil { - return err - } - - // TODO: current only support 1 primary key - if len(table.PrimaryKeys) > 1 { - return errors.New("unsupported composited primary key cascade") - } - - var pk = make(core.PK, len(table.PrimaryKeys)) - rawValueType := table.ColumnType(table.PKColumns()[0].FieldName) - pk[0], err = str2PK(string(data), rawValueType) - if err != nil { - return err - } - - if !isPKZero(pk) { - // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch - // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne - // property to be fetched lazily - structInter := reflect.New(fieldValue.Type()) - has, err := session.ID(pk).NoCascade().get(structInter.Interface()) - if err != nil { - return err - } - if has { - v = structInter.Elem().Interface() - fieldValue.Set(reflect.ValueOf(v)) - } else { - return errors.New("cascade obj is not exist") - } - } - } - } - case reflect.Ptr: - // !nashtsai! TODO merge duplicated codes above - //typeStr := fieldType.String() - switch fieldType.Elem().Kind() { - // case "*string": - case core.StringType.Kind(): - x := string(data) - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*bool": - case core.BoolType.Kind(): - d := string(data) - v, err := strconv.ParseBool(d) - if err != nil { - return fmt.Errorf("arg %v as bool: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&v).Convert(fieldType)) - // case "*complex64": - case core.Complex64Type.Kind(): - var x complex64 - if len(data) > 0 { - err := DefaultJSONHandler.Unmarshal(data, &x) - if err != nil { - session.engine.logger.Error(err) - return err - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - } - // case "*complex128": - case core.Complex128Type.Kind(): - var x complex128 - if len(data) > 0 { - err := DefaultJSONHandler.Unmarshal(data, &x) - if err != nil { - session.engine.logger.Error(err) - return err - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - } - // case "*float64": - case core.Float64Type.Kind(): - x, err := strconv.ParseFloat(string(data), 64) - if err != nil { - return fmt.Errorf("arg %v as float64: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*float32": - case core.Float32Type.Kind(): - var x float32 - x1, err := strconv.ParseFloat(string(data), 32) - if err != nil { - return fmt.Errorf("arg %v as float32: %s", key, err.Error()) - } - x = float32(x1) - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*uint64": - case core.Uint64Type.Kind(): - var x uint64 - x, err := strconv.ParseUint(string(data), 10, 64) - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*uint": - case core.UintType.Kind(): - var x uint - x1, err := strconv.ParseUint(string(data), 10, 64) - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - x = uint(x1) - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*uint32": - case core.Uint32Type.Kind(): - var x uint32 - x1, err := strconv.ParseUint(string(data), 10, 64) - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - x = uint32(x1) - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*uint8": - case core.Uint8Type.Kind(): - var x uint8 - x1, err := strconv.ParseUint(string(data), 10, 64) - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - x = uint8(x1) - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*uint16": - case core.Uint16Type.Kind(): - var x uint16 - x1, err := strconv.ParseUint(string(data), 10, 64) - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - x = uint16(x1) - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*int64": - case core.Int64Type.Kind(): - sdata := string(data) - var x int64 - var err error - // for mysql, when use bit, it returned \x01 - if col.SQLType.Name == core.Bit && - strings.Contains(session.engine.DriverName(), "mysql") { - if len(data) == 1 { - x = int64(data[0]) - } else { - x = 0 - } - } else if strings.HasPrefix(sdata, "0x") { - x, err = strconv.ParseInt(sdata, 16, 64) - } else if strings.HasPrefix(sdata, "0") { - x, err = strconv.ParseInt(sdata, 8, 64) - } else { - x, err = strconv.ParseInt(sdata, 10, 64) - } - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*int": - case core.IntType.Kind(): - sdata := string(data) - var x int - var x1 int64 - var err error - // for mysql, when use bit, it returned \x01 - if col.SQLType.Name == core.Bit && - strings.Contains(session.engine.DriverName(), "mysql") { - if len(data) == 1 { - x = int(data[0]) - } else { - x = 0 - } - } else if strings.HasPrefix(sdata, "0x") { - x1, err = strconv.ParseInt(sdata, 16, 64) - x = int(x1) - } else if strings.HasPrefix(sdata, "0") { - x1, err = strconv.ParseInt(sdata, 8, 64) - x = int(x1) - } else { - x1, err = strconv.ParseInt(sdata, 10, 64) - x = int(x1) - } - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*int32": - case core.Int32Type.Kind(): - sdata := string(data) - var x int32 - var x1 int64 - var err error - // for mysql, when use bit, it returned \x01 - if col.SQLType.Name == core.Bit && - session.engine.dialect.DBType() == core.MYSQL { - if len(data) == 1 { - x = int32(data[0]) - } else { - x = 0 - } - } else if strings.HasPrefix(sdata, "0x") { - x1, err = strconv.ParseInt(sdata, 16, 64) - x = int32(x1) - } else if strings.HasPrefix(sdata, "0") { - x1, err = strconv.ParseInt(sdata, 8, 64) - x = int32(x1) - } else { - x1, err = strconv.ParseInt(sdata, 10, 64) - x = int32(x1) - } - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*int8": - case core.Int8Type.Kind(): - sdata := string(data) - var x int8 - var x1 int64 - var err error - // for mysql, when use bit, it returned \x01 - if col.SQLType.Name == core.Bit && - strings.Contains(session.engine.DriverName(), "mysql") { - if len(data) == 1 { - x = int8(data[0]) - } else { - x = 0 - } - } else if strings.HasPrefix(sdata, "0x") { - x1, err = strconv.ParseInt(sdata, 16, 64) - x = int8(x1) - } else if strings.HasPrefix(sdata, "0") { - x1, err = strconv.ParseInt(sdata, 8, 64) - x = int8(x1) - } else { - x1, err = strconv.ParseInt(sdata, 10, 64) - x = int8(x1) - } - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*int16": - case core.Int16Type.Kind(): - sdata := string(data) - var x int16 - var x1 int64 - var err error - // for mysql, when use bit, it returned \x01 - if col.SQLType.Name == core.Bit && - strings.Contains(session.engine.DriverName(), "mysql") { - if len(data) == 1 { - x = int16(data[0]) - } else { - x = 0 - } - } else if strings.HasPrefix(sdata, "0x") { - x1, err = strconv.ParseInt(sdata, 16, 64) - x = int16(x1) - } else if strings.HasPrefix(sdata, "0") { - x1, err = strconv.ParseInt(sdata, 8, 64) - x = int16(x1) - } else { - x1, err = strconv.ParseInt(sdata, 10, 64) - x = int16(x1) - } - if err != nil { - return fmt.Errorf("arg %v as int: %s", key, err.Error()) - } - fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) - // case "*SomeStruct": - case reflect.Struct: - switch fieldType { - // case "*.time.Time": - case core.PtrTimeType: - x, err := session.byte2Time(col, data) - if err != nil { - return err - } - v = x - fieldValue.Set(reflect.ValueOf(&x)) - default: - if session.statement.UseCascade { - structInter := reflect.New(fieldType.Elem()) - table, err := session.engine.autoMapType(structInter.Elem()) - if err != nil { - return err - } - - if len(table.PrimaryKeys) > 1 { - return errors.New("unsupported composited primary key cascade") - } - - var pk = make(core.PK, len(table.PrimaryKeys)) - rawValueType := table.ColumnType(table.PKColumns()[0].FieldName) - pk[0], err = str2PK(string(data), rawValueType) - if err != nil { - return err - } - - if !isPKZero(pk) { - // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch - // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne - // property to be fetched lazily - has, err := session.ID(pk).NoCascade().get(structInter.Interface()) - if err != nil { - return err - } - if has { - v = structInter.Interface() - fieldValue.Set(reflect.ValueOf(v)) - } else { - return errors.New("cascade obj is not exist") - } - } - } else { - return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String()) - } - } - default: - return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String()) - } - default: - return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String()) - } - - return nil -} - -// convert a field value of a struct to interface for put into db -func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Value) (interface{}, error) { - if fieldValue.CanAddr() { - if fieldConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { - data, err := fieldConvert.ToDB() - if err != nil { - return 0, err - } - if col.SQLType.IsBlob() { - return data, nil - } - return string(data), nil - } - } - - if fieldConvert, ok := fieldValue.Interface().(core.Conversion); ok { - data, err := fieldConvert.ToDB() - if err != nil { - return 0, err - } - if col.SQLType.IsBlob() { - return data, nil - } - return string(data), nil - } - - fieldType := fieldValue.Type() - k := fieldType.Kind() - if k == reflect.Ptr { - if fieldValue.IsNil() { - return nil, nil - } else if !fieldValue.IsValid() { - session.engine.logger.Warn("the field[", col.FieldName, "] is invalid") - return nil, nil - } else { - // !nashtsai! deference pointer type to instance type - fieldValue = fieldValue.Elem() - fieldType = fieldValue.Type() - k = fieldType.Kind() - } - } - - switch k { - case reflect.Bool: - return fieldValue.Bool(), nil - case reflect.String: - return fieldValue.String(), nil - case reflect.Struct: - if fieldType.ConvertibleTo(core.TimeType) { - t := fieldValue.Convert(core.TimeType).Interface().(time.Time) - tf := session.engine.formatColTime(col, t) - return tf, nil - } - - if !col.SQLType.IsJson() { - // !! 增加支持driver.Valuer接口的结构,如sql.NullString - if v, ok := fieldValue.Interface().(driver.Valuer); ok { - return v.Value() - } - - fieldTable, err := session.engine.autoMapType(fieldValue) - if err != nil { - return nil, err - } - if len(fieldTable.PrimaryKeys) == 1 { - pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName) - return pkField.Interface(), nil - } - return 0, fmt.Errorf("no primary key for col %v", col.Name) - } - - if col.SQLType.IsText() { - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - session.engine.logger.Error(err) - return 0, err - } - return string(bytes), nil - } else if col.SQLType.IsBlob() { - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - session.engine.logger.Error(err) - return 0, err - } - return bytes, nil - } - return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type()) - case reflect.Complex64, reflect.Complex128: - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - session.engine.logger.Error(err) - return 0, err - } - return string(bytes), nil - case reflect.Array, reflect.Slice, reflect.Map: - if !fieldValue.IsValid() { - return fieldValue.Interface(), nil - } - - if col.SQLType.IsText() { - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - session.engine.logger.Error(err) - return 0, err - } - return string(bytes), nil - } else if col.SQLType.IsBlob() { - var bytes []byte - var err error - if (k == reflect.Slice) && - (fieldValue.Type().Elem().Kind() == reflect.Uint8) { - bytes = fieldValue.Bytes() - } else { - bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - session.engine.logger.Error(err) - return 0, err - } - } - return bytes, nil - } - return nil, ErrUnSupportedType - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return int64(fieldValue.Uint()), nil - default: - return fieldValue.Interface(), nil - } -} diff --git a/vendor/github.com/go-xorm/xorm/session_delete.go b/vendor/github.com/go-xorm/xorm/session_delete.go deleted file mode 100644 index 675d4d8c7d..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_delete.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "strconv" - - "xorm.io/core" -) - -func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string, args ...interface{}) error { - if table == nil || - session.tx != nil { - return ErrCacheFailed - } - - for _, filter := range session.engine.dialect.Filters() { - sqlStr = filter.Do(sqlStr, session.engine.dialect, table) - } - - newsql := session.statement.convertIDSQL(sqlStr) - if newsql == "" { - return ErrCacheFailed - } - - cacher := session.engine.getCacher(tableName) - pkColumns := table.PKColumns() - ids, err := core.GetCacheSql(cacher, tableName, newsql, args) - if err != nil { - resultsSlice, err := session.queryBytes(newsql, args...) - if err != nil { - return err - } - ids = make([]core.PK, 0) - if len(resultsSlice) > 0 { - for _, data := range resultsSlice { - var id int64 - var pk core.PK = make([]interface{}, 0) - for _, col := range pkColumns { - if v, ok := data[col.Name]; !ok { - return errors.New("no id") - } else if col.SQLType.IsText() { - pk = append(pk, string(v)) - } else if col.SQLType.IsNumeric() { - id, err = strconv.ParseInt(string(v), 10, 64) - if err != nil { - return err - } - pk = append(pk, id) - } else { - return errors.New("not supported primary key type") - } - } - ids = append(ids, pk) - } - } - } - - for _, id := range ids { - session.engine.logger.Debug("[cacheDelete] delete cache obj:", tableName, id) - sid, err := id.ToString() - if err != nil { - return err - } - cacher.DelBean(tableName, sid) - } - session.engine.logger.Debug("[cacheDelete] clear cache table:", tableName) - cacher.ClearIds(tableName) - return nil -} - -// Delete records, bean's non-empty fields are conditions -func (session *Session) Delete(bean interface{}) (int64, error) { - if session.isAutoClose { - defer session.Close() - } - - if session.statement.lastError != nil { - return 0, session.statement.lastError - } - - if err := session.statement.setRefBean(bean); err != nil { - return 0, err - } - - // handle before delete processors - for _, closure := range session.beforeClosures { - closure(bean) - } - cleanupProcessorsClosures(&session.beforeClosures) - - if processor, ok := interface{}(bean).(BeforeDeleteProcessor); ok { - processor.BeforeDelete() - } - - condSQL, condArgs, err := session.statement.genConds(bean) - if err != nil { - return 0, err - } - if len(condSQL) == 0 && session.statement.LimitN == 0 { - return 0, ErrNeedDeletedCond - } - - var tableNameNoQuote = session.statement.TableName() - var tableName = session.engine.Quote(tableNameNoQuote) - var table = session.statement.RefTable - var deleteSQL string - if len(condSQL) > 0 { - deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condSQL) - } else { - deleteSQL = fmt.Sprintf("DELETE FROM %v", tableName) - } - - var orderSQL string - if len(session.statement.OrderStr) > 0 { - orderSQL += fmt.Sprintf(" ORDER BY %s", session.statement.OrderStr) - } - if session.statement.LimitN > 0 { - orderSQL += fmt.Sprintf(" LIMIT %d", session.statement.LimitN) - } - - if len(orderSQL) > 0 { - switch session.engine.dialect.DBType() { - case core.POSTGRES: - inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL) - if len(condSQL) > 0 { - deleteSQL += " AND " + inSQL - } else { - deleteSQL += " WHERE " + inSQL - } - case core.SQLITE: - inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL) - if len(condSQL) > 0 { - deleteSQL += " AND " + inSQL - } else { - deleteSQL += " WHERE " + inSQL - } - // TODO: how to handle delete limit on mssql? - case core.MSSQL: - return 0, ErrNotImplemented - default: - deleteSQL += orderSQL - } - } - - var realSQL string - argsForCache := make([]interface{}, 0, len(condArgs)*2) - if session.statement.unscoped || table.DeletedColumn() == nil { // tag "deleted" is disabled - realSQL = deleteSQL - copy(argsForCache, condArgs) - argsForCache = append(condArgs, argsForCache...) - } else { - // !oinume! sqlStrForCache and argsForCache is needed to behave as executing "DELETE FROM ..." for cache. - copy(argsForCache, condArgs) - argsForCache = append(condArgs, argsForCache...) - - deletedColumn := table.DeletedColumn() - realSQL = fmt.Sprintf("UPDATE %v SET %v = ? WHERE %v", - session.engine.Quote(session.statement.TableName()), - session.engine.Quote(deletedColumn.Name), - condSQL) - - if len(orderSQL) > 0 { - switch session.engine.dialect.DBType() { - case core.POSTGRES: - inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL) - if len(condSQL) > 0 { - realSQL += " AND " + inSQL - } else { - realSQL += " WHERE " + inSQL - } - case core.SQLITE: - inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL) - if len(condSQL) > 0 { - realSQL += " AND " + inSQL - } else { - realSQL += " WHERE " + inSQL - } - // TODO: how to handle delete limit on mssql? - case core.MSSQL: - return 0, ErrNotImplemented - default: - realSQL += orderSQL - } - } - - // !oinume! Insert nowTime to the head of session.statement.Params - condArgs = append(condArgs, "") - paramsLen := len(condArgs) - copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1]) - - val, t := session.engine.nowTime(deletedColumn) - condArgs[0] = val - - var colName = deletedColumn.Name - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnTime(bean, col, t) - }) - } - - if cacher := session.engine.getCacher(tableNameNoQuote); cacher != nil && session.statement.UseCache { - session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...) - } - - session.statement.RefTable = table - res, err := session.exec(realSQL, condArgs...) - if err != nil { - return 0, err - } - - // handle after delete processors - if session.isAutoCommit { - for _, closure := range session.afterClosures { - closure(bean) - } - if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok { - processor.AfterDelete() - } - } else { - lenAfterClosures := len(session.afterClosures) - if lenAfterClosures > 0 { - if value, has := session.afterDeleteBeans[bean]; has && value != nil { - *value = append(*value, session.afterClosures...) - } else { - afterClosures := make([]func(interface{}), lenAfterClosures) - copy(afterClosures, session.afterClosures) - session.afterDeleteBeans[bean] = &afterClosures - } - } else { - if _, ok := interface{}(bean).(AfterDeleteProcessor); ok { - session.afterDeleteBeans[bean] = nil - } - } - } - cleanupProcessorsClosures(&session.afterClosures) - // -- - - return res.RowsAffected() -} diff --git a/vendor/github.com/go-xorm/xorm/session_exist.go b/vendor/github.com/go-xorm/xorm/session_exist.go deleted file mode 100644 index 660cc47e42..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_exist.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "reflect" - - "xorm.io/builder" - "xorm.io/core" -) - -// Exist returns true if the record exist otherwise return false -func (session *Session) Exist(bean ...interface{}) (bool, error) { - if session.isAutoClose { - defer session.Close() - } - - if session.statement.lastError != nil { - return false, session.statement.lastError - } - - var sqlStr string - var args []interface{} - var err error - - if session.statement.RawSQL == "" { - if len(bean) == 0 { - tableName := session.statement.TableName() - if len(tableName) <= 0 { - return false, ErrTableNotFound - } - - tableName = session.statement.Engine.Quote(tableName) - - if session.statement.cond.IsValid() { - condSQL, condArgs, err := builder.ToSQL(session.statement.cond) - if err != nil { - return false, err - } - - if session.engine.dialect.DBType() == core.MSSQL { - sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s WHERE %s", tableName, condSQL) - } else if session.engine.dialect.DBType() == core.ORACLE { - sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE (%s) AND ROWNUM=1", tableName, condSQL) - } else { - sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL) - } - args = condArgs - } else { - if session.engine.dialect.DBType() == core.MSSQL { - sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s", tableName) - } else if session.engine.dialect.DBType() == core.ORACLE { - sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE ROWNUM=1", tableName) - } else { - sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName) - } - args = []interface{}{} - } - } else { - beanValue := reflect.ValueOf(bean[0]) - if beanValue.Kind() != reflect.Ptr { - return false, errors.New("needs a pointer") - } - - if beanValue.Elem().Kind() == reflect.Struct { - if err := session.statement.setRefBean(bean[0]); err != nil { - return false, err - } - } - - if len(session.statement.TableName()) <= 0 { - return false, ErrTableNotFound - } - session.statement.Limit(1) - sqlStr, args, err = session.statement.genGetSQL(bean[0]) - if err != nil { - return false, err - } - } - } else { - sqlStr = session.statement.RawSQL - args = session.statement.RawParams - } - - rows, err := session.queryRows(sqlStr, args...) - if err != nil { - return false, err - } - defer rows.Close() - - return rows.Next(), nil -} diff --git a/vendor/github.com/go-xorm/xorm/session_find.go b/vendor/github.com/go-xorm/xorm/session_find.go deleted file mode 100644 index 6b8aa469db..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_find.go +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "reflect" - "strings" - - "xorm.io/builder" - "xorm.io/core" -) - -const ( - tpStruct = iota - tpNonStruct -) - -// Find retrieve records from table, condiBeans's non-empty fields -// are conditions. beans could be []Struct, []*Struct, map[int64]Struct -// map[int64]*Struct -func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) error { - if session.isAutoClose { - defer session.Close() - } - return session.find(rowsSlicePtr, condiBean...) -} - -// FindAndCount find the results and also return the counts -func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { - if session.isAutoClose { - defer session.Close() - } - - session.autoResetStatement = false - err := session.find(rowsSlicePtr, condiBean...) - if err != nil { - return 0, err - } - - sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) - if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { - return 0, errors.New("needs a pointer to a slice or a map") - } - - sliceElementType := sliceValue.Type().Elem() - if sliceElementType.Kind() == reflect.Ptr { - sliceElementType = sliceElementType.Elem() - } - session.autoResetStatement = true - - if session.statement.selectStr != "" { - session.statement.selectStr = "" - } - if session.statement.OrderStr != "" { - session.statement.OrderStr = "" - } - - return session.Count(reflect.New(sliceElementType).Interface()) -} - -func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { - defer session.resetStatement() - - if session.statement.lastError != nil { - return session.statement.lastError - } - - sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) - if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { - return errors.New("needs a pointer to a slice or a map") - } - - sliceElementType := sliceValue.Type().Elem() - - var tp = tpStruct - if session.statement.RefTable == nil { - if sliceElementType.Kind() == reflect.Ptr { - if sliceElementType.Elem().Kind() == reflect.Struct { - pv := reflect.New(sliceElementType.Elem()) - if err := session.statement.setRefValue(pv); err != nil { - return err - } - } else { - tp = tpNonStruct - } - } else if sliceElementType.Kind() == reflect.Struct { - pv := reflect.New(sliceElementType) - if err := session.statement.setRefValue(pv); err != nil { - return err - } - } else { - tp = tpNonStruct - } - } - - var table = session.statement.RefTable - - var addedTableName = (len(session.statement.JoinStr) > 0) - var autoCond builder.Cond - if tp == tpStruct { - if !session.statement.noAutoCondition && len(condiBean) > 0 { - var err error - autoCond, err = session.statement.buildConds(table, condiBean[0], true, true, false, true, addedTableName) - if err != nil { - return err - } - } else { - // !oinume! Add " IS NULL" to WHERE whatever condiBean is given. - // See https://github.com/go-xorm/xorm/issues/179 - if col := table.DeletedColumn(); col != nil && !session.statement.unscoped { // tag "deleted" is enabled - var colName = session.engine.Quote(col.Name) - if addedTableName { - var nm = session.statement.TableName() - if len(session.statement.TableAlias) > 0 { - nm = session.statement.TableAlias - } - colName = session.engine.Quote(nm) + "." + colName - } - - autoCond = session.engine.CondDeleted(colName) - } - } - } - - var sqlStr string - var args []interface{} - var err error - if session.statement.RawSQL == "" { - if len(session.statement.TableName()) <= 0 { - return ErrTableNotFound - } - - var columnStr = session.statement.ColumnStr - if len(session.statement.selectStr) > 0 { - columnStr = session.statement.selectStr - } else { - if session.statement.JoinStr == "" { - if columnStr == "" { - if session.statement.GroupByStr != "" { - columnStr = session.engine.quoteColumns(session.statement.GroupByStr) - } else { - columnStr = session.statement.genColumnStr() - } - } - } else { - if columnStr == "" { - if session.statement.GroupByStr != "" { - columnStr = session.engine.quoteColumns(session.statement.GroupByStr) - } else { - columnStr = "*" - } - } - } - if columnStr == "" { - columnStr = "*" - } - } - - session.statement.cond = session.statement.cond.And(autoCond) - condSQL, condArgs, err := builder.ToSQL(session.statement.cond) - if err != nil { - return err - } - - args = append(session.statement.joinArgs, condArgs...) - sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL, true, true) - if err != nil { - return err - } - // for mssql and use limit - qs := strings.Count(sqlStr, "?") - if len(args)*2 == qs { - args = append(args, args...) - } - } else { - sqlStr = session.statement.RawSQL - args = session.statement.RawParams - } - - if session.canCache() { - if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil && - !session.statement.IsDistinct && - !session.statement.unscoped { - err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) - if err != ErrCacheFailed { - return err - } - err = nil // !nashtsai! reset err to nil for ErrCacheFailed - session.engine.logger.Warn("Cache Find Failed") - } - } - - return session.noCacheFind(table, sliceValue, sqlStr, args...) -} - -func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error { - rows, err := session.queryRows(sqlStr, args...) - if err != nil { - return err - } - defer rows.Close() - - fields, err := rows.Columns() - if err != nil { - return err - } - - var newElemFunc func(fields []string) reflect.Value - elemType := containerValue.Type().Elem() - var isPointer bool - if elemType.Kind() == reflect.Ptr { - isPointer = true - elemType = elemType.Elem() - } - if elemType.Kind() == reflect.Ptr { - return errors.New("pointer to pointer is not supported") - } - - newElemFunc = func(fields []string) reflect.Value { - switch elemType.Kind() { - case reflect.Slice: - slice := reflect.MakeSlice(elemType, len(fields), len(fields)) - x := reflect.New(slice.Type()) - x.Elem().Set(slice) - return x - case reflect.Map: - mp := reflect.MakeMap(elemType) - x := reflect.New(mp.Type()) - x.Elem().Set(mp) - return x - } - return reflect.New(elemType) - } - - var containerValueSetFunc func(*reflect.Value, core.PK) error - - if containerValue.Kind() == reflect.Slice { - containerValueSetFunc = func(newValue *reflect.Value, pk core.PK) error { - if isPointer { - containerValue.Set(reflect.Append(containerValue, newValue.Elem().Addr())) - } else { - containerValue.Set(reflect.Append(containerValue, newValue.Elem())) - } - return nil - } - } else { - keyType := containerValue.Type().Key() - if len(table.PrimaryKeys) == 0 { - return errors.New("don't support multiple primary key's map has non-slice key type") - } - if len(table.PrimaryKeys) > 1 && keyType.Kind() != reflect.Slice { - return errors.New("don't support multiple primary key's map has non-slice key type") - } - - containerValueSetFunc = func(newValue *reflect.Value, pk core.PK) error { - keyValue := reflect.New(keyType) - err := convertPKToValue(table, keyValue.Interface(), pk) - if err != nil { - return err - } - if isPointer { - containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem().Addr()) - } else { - containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem()) - } - return nil - } - } - - if elemType.Kind() == reflect.Struct { - var newValue = newElemFunc(fields) - dataStruct := rValue(newValue.Interface()) - tb, err := session.engine.autoMapType(dataStruct) - if err != nil { - return err - } - err = session.rows2Beans(rows, fields, tb, newElemFunc, containerValueSetFunc) - rows.Close() - if err != nil { - return err - } - return session.executeProcessors() - } - - for rows.Next() { - var newValue = newElemFunc(fields) - bean := newValue.Interface() - - switch elemType.Kind() { - case reflect.Slice: - err = rows.ScanSlice(bean) - case reflect.Map: - err = rows.ScanMap(bean) - default: - err = rows.Scan(bean) - } - - if err != nil { - return err - } - - if err := containerValueSetFunc(&newValue, nil); err != nil { - return err - } - } - return nil -} - -func convertPKToValue(table *core.Table, dst interface{}, pk core.PK) error { - cols := table.PKColumns() - if len(cols) == 1 { - return convertAssign(dst, pk[0]) - } - - dst = pk - return nil -} - -func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) { - if !session.canCache() || - indexNoCase(sqlStr, "having") != -1 || - indexNoCase(sqlStr, "group by") != -1 { - return ErrCacheFailed - } - - tableName := session.statement.TableName() - cacher := session.engine.getCacher(tableName) - if cacher == nil { - return nil - } - - for _, filter := range session.engine.dialect.Filters() { - sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable) - } - - newsql := session.statement.convertIDSQL(sqlStr) - if newsql == "" { - return ErrCacheFailed - } - - table := session.statement.RefTable - ids, err := core.GetCacheSql(cacher, tableName, newsql, args) - if err != nil { - rows, err := session.queryRows(newsql, args...) - if err != nil { - return err - } - defer rows.Close() - - var i int - ids = make([]core.PK, 0) - for rows.Next() { - i++ - if i > 500 { - session.engine.logger.Debug("[cacheFind] ids length > 500, no cache") - return ErrCacheFailed - } - var res = make([]string, len(table.PrimaryKeys)) - err = rows.ScanSlice(&res) - if err != nil { - return err - } - var pk core.PK = make([]interface{}, len(table.PrimaryKeys)) - for i, col := range table.PKColumns() { - pk[i], err = session.engine.idTypeAssertion(col, res[i]) - if err != nil { - return err - } - } - - ids = append(ids, pk) - } - - session.engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, sqlStr, newsql, args) - err = core.PutCacheSql(cacher, ids, tableName, newsql, args) - if err != nil { - return err - } - } else { - session.engine.logger.Debug("[cacheFind] cache hit sql:", tableName, sqlStr, newsql, args) - } - - sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) - - ididxes := make(map[string]int) - var ides []core.PK - var temps = make([]interface{}, len(ids)) - - for idx, id := range ids { - sid, err := id.ToString() - if err != nil { - return err - } - bean := cacher.GetBean(tableName, sid) - if bean == nil || reflect.ValueOf(bean).Elem().Type() != t { - ides = append(ides, id) - ididxes[sid] = idx - } else { - session.engine.logger.Debug("[cacheFind] cache hit bean:", tableName, id, bean) - - pk := session.engine.IdOf(bean) - xid, err := pk.ToString() - if err != nil { - return err - } - - if sid != xid { - session.engine.logger.Error("[cacheFind] error cache", xid, sid, bean) - return ErrCacheFailed - } - temps[idx] = bean - } - } - - if len(ides) > 0 { - slices := reflect.New(reflect.SliceOf(t)) - beans := slices.Interface() - - if len(table.PrimaryKeys) == 1 { - ff := make([]interface{}, 0, len(ides)) - for _, ie := range ides { - ff = append(ff, ie[0]) - } - - session.In("`"+table.PrimaryKeys[0]+"`", ff...) - } else { - for _, ie := range ides { - cond := builder.NewCond() - for i, name := range table.PrimaryKeys { - cond = cond.And(builder.Eq{"`" + name + "`": ie[i]}) - } - session.Or(cond) - } - } - - err = session.NoCache().Table(tableName).find(beans) - if err != nil { - return err - } - - vs := reflect.Indirect(reflect.ValueOf(beans)) - for i := 0; i < vs.Len(); i++ { - rv := vs.Index(i) - if rv.Kind() != reflect.Ptr { - rv = rv.Addr() - } - id, err := session.engine.idOfV(rv) - if err != nil { - return err - } - sid, err := id.ToString() - if err != nil { - return err - } - - bean := rv.Interface() - temps[ididxes[sid]] = bean - session.engine.logger.Debug("[cacheFind] cache bean:", tableName, id, bean, temps) - cacher.PutBean(tableName, sid, bean) - } - } - - for j := 0; j < len(temps); j++ { - bean := temps[j] - if bean == nil { - session.engine.logger.Warn("[cacheFind] cache no hit:", tableName, ids[j], temps) - // return errors.New("cache error") // !nashtsai! no need to return error, but continue instead - continue - } - if sliceValue.Kind() == reflect.Slice { - if t.Kind() == reflect.Ptr { - sliceValue.Set(reflect.Append(sliceValue, reflect.ValueOf(bean))) - } else { - sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(bean)))) - } - } else if sliceValue.Kind() == reflect.Map { - var key = ids[j] - keyType := sliceValue.Type().Key() - var ikey interface{} - if len(key) == 1 { - ikey, err = str2PK(fmt.Sprintf("%v", key[0]), keyType) - if err != nil { - return err - } - } else { - if keyType.Kind() != reflect.Slice { - return errors.New("table have multiple primary keys, key is not core.PK or slice") - } - ikey = key - } - - if t.Kind() == reflect.Ptr { - sliceValue.SetMapIndex(reflect.ValueOf(ikey), reflect.ValueOf(bean)) - } else { - sliceValue.SetMapIndex(reflect.ValueOf(ikey), reflect.Indirect(reflect.ValueOf(bean))) - } - } - } - - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/session_get.go b/vendor/github.com/go-xorm/xorm/session_get.go deleted file mode 100644 index cc0a2019ea..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_get.go +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql" - "errors" - "fmt" - "reflect" - "strconv" - - "xorm.io/core" -) - -// Get retrieve one record from database, bean's non-empty fields -// will be as conditions -func (session *Session) Get(bean interface{}) (bool, error) { - if session.isAutoClose { - defer session.Close() - } - return session.get(bean) -} - -func (session *Session) get(bean interface{}) (bool, error) { - defer session.resetStatement() - - if session.statement.lastError != nil { - return false, session.statement.lastError - } - - beanValue := reflect.ValueOf(bean) - if beanValue.Kind() != reflect.Ptr { - return false, errors.New("needs a pointer to a value") - } else if beanValue.Elem().Kind() == reflect.Ptr { - return false, errors.New("a pointer to a pointer is not allowed") - } - - if beanValue.Elem().Kind() == reflect.Struct { - if err := session.statement.setRefBean(bean); err != nil { - return false, err - } - } - - var sqlStr string - var args []interface{} - var err error - - if session.statement.RawSQL == "" { - if len(session.statement.TableName()) <= 0 { - return false, ErrTableNotFound - } - session.statement.Limit(1) - sqlStr, args, err = session.statement.genGetSQL(bean) - if err != nil { - return false, err - } - } else { - sqlStr = session.statement.RawSQL - args = session.statement.RawParams - } - - table := session.statement.RefTable - - if session.canCache() && beanValue.Elem().Kind() == reflect.Struct { - if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil && - !session.statement.unscoped { - has, err := session.cacheGet(bean, sqlStr, args...) - if err != ErrCacheFailed { - return has, err - } - } - } - - context := session.statement.context - if context != nil { - res := context.Get(fmt.Sprintf("%v-%v", sqlStr, args)) - if res != nil { - session.engine.logger.Debug("hit context cache", sqlStr) - - structValue := reflect.Indirect(reflect.ValueOf(bean)) - structValue.Set(reflect.Indirect(reflect.ValueOf(res))) - session.lastSQL = "" - session.lastSQLArgs = nil - return true, nil - } - } - - has, err := session.nocacheGet(beanValue.Elem().Kind(), table, bean, sqlStr, args...) - if err != nil || !has { - return has, err - } - - if context != nil { - context.Put(fmt.Sprintf("%v-%v", sqlStr, args), bean) - } - - return true, nil -} - -func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bean interface{}, sqlStr string, args ...interface{}) (bool, error) { - rows, err := session.queryRows(sqlStr, args...) - if err != nil { - return false, err - } - defer rows.Close() - - if !rows.Next() { - if rows.Err() != nil { - return false, rows.Err() - } - return false, nil - } - - switch bean.(type) { - case sql.NullInt64, sql.NullBool, sql.NullFloat64, sql.NullString: - return true, rows.Scan(&bean) - case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString: - return true, rows.Scan(bean) - case *string: - var res sql.NullString - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*string)) = res.String - } - return true, nil - case *int: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*int)) = int(res.Int64) - } - return true, nil - case *int8: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*int8)) = int8(res.Int64) - } - return true, nil - case *int16: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*int16)) = int16(res.Int64) - } - return true, nil - case *int32: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*int32)) = int32(res.Int64) - } - return true, nil - case *int64: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*int64)) = int64(res.Int64) - } - return true, nil - case *uint: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*uint)) = uint(res.Int64) - } - return true, nil - case *uint8: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*uint8)) = uint8(res.Int64) - } - return true, nil - case *uint16: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*uint16)) = uint16(res.Int64) - } - return true, nil - case *uint32: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*uint32)) = uint32(res.Int64) - } - return true, nil - case *uint64: - var res sql.NullInt64 - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*uint64)) = uint64(res.Int64) - } - return true, nil - case *bool: - var res sql.NullBool - if err := rows.Scan(&res); err != nil { - return true, err - } - if res.Valid { - *(bean.(*bool)) = res.Bool - } - return true, nil - } - - switch beanKind { - case reflect.Struct: - fields, err := rows.Columns() - if err != nil { - // WARN: Alougth rows return true, but get fields failed - return true, err - } - - scanResults, err := session.row2Slice(rows, fields, bean) - if err != nil { - return false, err - } - // close it before covert data - rows.Close() - - dataStruct := rValue(bean) - _, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table) - if err != nil { - return true, err - } - - return true, session.executeProcessors() - case reflect.Slice: - err = rows.ScanSlice(bean) - case reflect.Map: - err = rows.ScanMap(bean) - case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - err = rows.Scan(bean) - default: - err = rows.Scan(bean) - } - - return true, err -} - -func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) { - // if has no reftable, then don't use cache currently - if !session.canCache() { - return false, ErrCacheFailed - } - - for _, filter := range session.engine.dialect.Filters() { - sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable) - } - newsql := session.statement.convertIDSQL(sqlStr) - if newsql == "" { - return false, ErrCacheFailed - } - - tableName := session.statement.TableName() - cacher := session.engine.getCacher(tableName) - - session.engine.logger.Debug("[cacheGet] find sql:", newsql, args) - table := session.statement.RefTable - ids, err := core.GetCacheSql(cacher, tableName, newsql, args) - if err != nil { - var res = make([]string, len(table.PrimaryKeys)) - rows, err := session.NoCache().queryRows(newsql, args...) - if err != nil { - return false, err - } - defer rows.Close() - - if rows.Next() { - err = rows.ScanSlice(&res) - if err != nil { - return false, err - } - } else { - return false, ErrCacheFailed - } - - var pk core.PK = make([]interface{}, len(table.PrimaryKeys)) - for i, col := range table.PKColumns() { - if col.SQLType.IsText() { - pk[i] = res[i] - } else if col.SQLType.IsNumeric() { - n, err := strconv.ParseInt(res[i], 10, 64) - if err != nil { - return false, err - } - pk[i] = n - } else { - return false, errors.New("unsupported") - } - } - - ids = []core.PK{pk} - session.engine.logger.Debug("[cacheGet] cache ids:", newsql, ids) - err = core.PutCacheSql(cacher, ids, tableName, newsql, args) - if err != nil { - return false, err - } - } else { - session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql, ids) - } - - if len(ids) > 0 { - structValue := reflect.Indirect(reflect.ValueOf(bean)) - id := ids[0] - session.engine.logger.Debug("[cacheGet] get bean:", tableName, id) - sid, err := id.ToString() - if err != nil { - return false, err - } - cacheBean := cacher.GetBean(tableName, sid) - if cacheBean == nil { - cacheBean = bean - has, err = session.nocacheGet(reflect.Struct, table, cacheBean, sqlStr, args...) - if err != nil || !has { - return has, err - } - - session.engine.logger.Debug("[cacheGet] cache bean:", tableName, id, cacheBean) - cacher.PutBean(tableName, sid, cacheBean) - } else { - session.engine.logger.Debug("[cacheGet] cache hit bean:", tableName, id, cacheBean) - has = true - } - structValue.Set(reflect.Indirect(reflect.ValueOf(cacheBean))) - - return has, nil - } - return false, nil -} diff --git a/vendor/github.com/go-xorm/xorm/session_insert.go b/vendor/github.com/go-xorm/xorm/session_insert.go deleted file mode 100644 index 1e19ce7a4e..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_insert.go +++ /dev/null @@ -1,878 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "reflect" - "sort" - "strconv" - "strings" - - "xorm.io/builder" - "xorm.io/core" -) - -// Insert insert one or more beans -func (session *Session) Insert(beans ...interface{}) (int64, error) { - var affected int64 - var err error - - if session.isAutoClose { - defer session.Close() - } - - session.autoResetStatement = false - defer func() { - session.autoResetStatement = true - session.resetStatement() - }() - - for _, bean := range beans { - switch bean.(type) { - case map[string]interface{}: - cnt, err := session.insertMapInterface(bean.(map[string]interface{})) - if err != nil { - return affected, err - } - affected += cnt - case []map[string]interface{}: - s := bean.([]map[string]interface{}) - for i := 0; i < len(s); i++ { - cnt, err := session.insertMapInterface(s[i]) - if err != nil { - return affected, err - } - affected += cnt - } - case map[string]string: - cnt, err := session.insertMapString(bean.(map[string]string)) - if err != nil { - return affected, err - } - affected += cnt - case []map[string]string: - s := bean.([]map[string]string) - for i := 0; i < len(s); i++ { - cnt, err := session.insertMapString(s[i]) - if err != nil { - return affected, err - } - affected += cnt - } - default: - sliceValue := reflect.Indirect(reflect.ValueOf(bean)) - if sliceValue.Kind() == reflect.Slice { - size := sliceValue.Len() - if size > 0 { - if session.engine.SupportInsertMany() { - cnt, err := session.innerInsertMulti(bean) - if err != nil { - return affected, err - } - affected += cnt - } else { - for i := 0; i < size; i++ { - cnt, err := session.innerInsert(sliceValue.Index(i).Interface()) - if err != nil { - return affected, err - } - affected += cnt - } - } - } - } else { - cnt, err := session.innerInsert(bean) - if err != nil { - return affected, err - } - affected += cnt - } - } - } - - return affected, err -} - -func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error) { - sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) - if sliceValue.Kind() != reflect.Slice { - return 0, errors.New("needs a pointer to a slice") - } - - if sliceValue.Len() <= 0 { - return 0, errors.New("could not insert a empty slice") - } - - if err := session.statement.setRefBean(sliceValue.Index(0).Interface()); err != nil { - return 0, err - } - - tableName := session.statement.TableName() - if len(tableName) <= 0 { - return 0, ErrTableNotFound - } - - table := session.statement.RefTable - size := sliceValue.Len() - - var colNames []string - var colMultiPlaces []string - var args []interface{} - var cols []*core.Column - - for i := 0; i < size; i++ { - v := sliceValue.Index(i) - vv := reflect.Indirect(v) - elemValue := v.Interface() - var colPlaces []string - - // handle BeforeInsertProcessor - // !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi?? - for _, closure := range session.beforeClosures { - closure(elemValue) - } - - if processor, ok := interface{}(elemValue).(BeforeInsertProcessor); ok { - processor.BeforeInsert() - } - // -- - - if i == 0 { - for _, col := range table.Columns() { - ptrFieldValue, err := col.ValueOfV(&vv) - if err != nil { - return 0, err - } - fieldValue := *ptrFieldValue - if col.IsAutoIncrement && isZero(fieldValue.Interface()) { - continue - } - if col.MapType == core.ONLYFROMDB { - continue - } - if col.IsDeleted { - continue - } - if session.statement.omitColumnMap.contain(col.Name) { - continue - } - if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { - continue - } - if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { - val, t := session.engine.nowTime(col) - args = append(args, val) - - var colName = col.Name - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnTime(bean, col, t) - }) - } else if col.IsVersion && session.statement.checkVersion { - args = append(args, 1) - var colName = col.Name - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnInt(bean, col, 1) - }) - } else { - arg, err := session.value2Interface(col, fieldValue) - if err != nil { - return 0, err - } - args = append(args, arg) - } - - colNames = append(colNames, col.Name) - cols = append(cols, col) - colPlaces = append(colPlaces, "?") - } - } else { - for _, col := range cols { - ptrFieldValue, err := col.ValueOfV(&vv) - if err != nil { - return 0, err - } - fieldValue := *ptrFieldValue - - if col.IsAutoIncrement && isZero(fieldValue.Interface()) { - continue - } - if col.MapType == core.ONLYFROMDB { - continue - } - if col.IsDeleted { - continue - } - if session.statement.omitColumnMap.contain(col.Name) { - continue - } - if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { - continue - } - if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { - val, t := session.engine.nowTime(col) - args = append(args, val) - - var colName = col.Name - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnTime(bean, col, t) - }) - } else if col.IsVersion && session.statement.checkVersion { - args = append(args, 1) - var colName = col.Name - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnInt(bean, col, 1) - }) - } else { - arg, err := session.value2Interface(col, fieldValue) - if err != nil { - return 0, err - } - args = append(args, arg) - } - - colPlaces = append(colPlaces, "?") - } - } - colMultiPlaces = append(colMultiPlaces, strings.Join(colPlaces, ", ")) - } - cleanupProcessorsClosures(&session.beforeClosures) - - var sql string - if session.engine.dialect.DBType() == core.ORACLE { - temp := fmt.Sprintf(") INTO %s (%v) VALUES (", - session.engine.Quote(tableName), - quoteColumns(colNames, session.engine.Quote, ",")) - sql = fmt.Sprintf("INSERT ALL INTO %s (%v) VALUES (%v) SELECT 1 FROM DUAL", - session.engine.Quote(tableName), - quoteColumns(colNames, session.engine.Quote, ","), - strings.Join(colMultiPlaces, temp)) - } else { - sql = fmt.Sprintf("INSERT INTO %s (%v) VALUES (%v)", - session.engine.Quote(tableName), - quoteColumns(colNames, session.engine.Quote, ","), - strings.Join(colMultiPlaces, "),(")) - } - res, err := session.exec(sql, args...) - if err != nil { - return 0, err - } - - session.cacheInsert(tableName) - - lenAfterClosures := len(session.afterClosures) - for i := 0; i < size; i++ { - elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface() - - // handle AfterInsertProcessor - if session.isAutoCommit { - // !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi?? - for _, closure := range session.afterClosures { - closure(elemValue) - } - if processor, ok := interface{}(elemValue).(AfterInsertProcessor); ok { - processor.AfterInsert() - } - } else { - if lenAfterClosures > 0 { - if value, has := session.afterInsertBeans[elemValue]; has && value != nil { - *value = append(*value, session.afterClosures...) - } else { - afterClosures := make([]func(interface{}), lenAfterClosures) - copy(afterClosures, session.afterClosures) - session.afterInsertBeans[elemValue] = &afterClosures - } - } else { - if _, ok := interface{}(elemValue).(AfterInsertProcessor); ok { - session.afterInsertBeans[elemValue] = nil - } - } - } - } - - cleanupProcessorsClosures(&session.afterClosures) - return res.RowsAffected() -} - -// InsertMulti insert multiple records -func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) { - if session.isAutoClose { - defer session.Close() - } - - sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) - if sliceValue.Kind() != reflect.Slice { - return 0, ErrParamsType - - } - - if sliceValue.Len() <= 0 { - return 0, nil - } - - return session.innerInsertMulti(rowsSlicePtr) -} - -func (session *Session) innerInsert(bean interface{}) (int64, error) { - if err := session.statement.setRefBean(bean); err != nil { - return 0, err - } - if len(session.statement.TableName()) <= 0 { - return 0, ErrTableNotFound - } - - table := session.statement.RefTable - - // handle BeforeInsertProcessor - for _, closure := range session.beforeClosures { - closure(bean) - } - cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used - - if processor, ok := interface{}(bean).(BeforeInsertProcessor); ok { - processor.BeforeInsert() - } - - colNames, args, err := session.genInsertColumns(bean) - if err != nil { - return 0, err - } - - exprs := session.statement.exprColumns - colPlaces := strings.Repeat("?, ", len(colNames)) - if exprs.Len() <= 0 && len(colPlaces) > 0 { - colPlaces = colPlaces[0 : len(colPlaces)-2] - } - - var tableName = session.statement.TableName() - var output string - if session.engine.dialect.DBType() == core.MSSQL && len(table.AutoIncrement) > 0 { - output = fmt.Sprintf(" OUTPUT Inserted.%s", table.AutoIncrement) - } - - var buf = builder.NewWriter() - if _, err := buf.WriteString(fmt.Sprintf("INSERT INTO %s", session.engine.Quote(tableName))); err != nil { - return 0, err - } - - if len(colPlaces) <= 0 { - if session.engine.dialect.DBType() == core.MYSQL { - if _, err := buf.WriteString(" VALUES ()"); err != nil { - return 0, err - } - } else { - if _, err := buf.WriteString(fmt.Sprintf("%s DEFAULT VALUES", output)); err != nil { - return 0, err - } - } - } else { - if _, err := buf.WriteString(" ("); err != nil { - return 0, err - } - - if err := writeStrings(buf, append(colNames, exprs.colNames...), "`", "`"); err != nil { - return 0, err - } - - if session.statement.cond.IsValid() { - if _, err := buf.WriteString(fmt.Sprintf(")%s SELECT ", output)); err != nil { - return 0, err - } - - if err := session.statement.writeArgs(buf, args); err != nil { - return 0, err - } - - if len(exprs.args) > 0 { - if _, err := buf.WriteString(","); err != nil { - return 0, err - } - } - if err := exprs.writeArgs(buf); err != nil { - return 0, err - } - - if _, err := buf.WriteString(fmt.Sprintf(" FROM %v WHERE ", session.engine.Quote(tableName))); err != nil { - return 0, err - } - - if err := session.statement.cond.WriteTo(buf); err != nil { - return 0, err - } - } else { - buf.Append(args...) - - if _, err := buf.WriteString(fmt.Sprintf(")%s VALUES (%v", - output, - colPlaces)); err != nil { - return 0, err - } - - if err := exprs.writeArgs(buf); err != nil { - return 0, err - } - - if _, err := buf.WriteString(")"); err != nil { - return 0, err - } - } - } - - if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == core.POSTGRES { - if _, err := buf.WriteString(" RETURNING " + session.engine.Quote(table.AutoIncrement)); err != nil { - return 0, err - } - } - - sqlStr := buf.String() - args = buf.Args() - - handleAfterInsertProcessorFunc := func(bean interface{}) { - if session.isAutoCommit { - for _, closure := range session.afterClosures { - closure(bean) - } - if processor, ok := interface{}(bean).(AfterInsertProcessor); ok { - processor.AfterInsert() - } - } else { - lenAfterClosures := len(session.afterClosures) - if lenAfterClosures > 0 { - if value, has := session.afterInsertBeans[bean]; has && value != nil { - *value = append(*value, session.afterClosures...) - } else { - afterClosures := make([]func(interface{}), lenAfterClosures) - copy(afterClosures, session.afterClosures) - session.afterInsertBeans[bean] = &afterClosures - } - - } else { - if _, ok := interface{}(bean).(AfterInsertProcessor); ok { - session.afterInsertBeans[bean] = nil - } - } - } - cleanupProcessorsClosures(&session.afterClosures) // cleanup after used - } - - // for postgres, many of them didn't implement lastInsertId, so we should - // implemented it ourself. - if session.engine.dialect.DBType() == core.ORACLE && len(table.AutoIncrement) > 0 { - res, err := session.queryBytes("select seq_atable.currval from dual", args...) - if err != nil { - return 0, err - } - - defer handleAfterInsertProcessorFunc(bean) - - session.cacheInsert(tableName) - - if table.Version != "" && session.statement.checkVersion { - verValue, err := table.VersionColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } else if verValue.IsValid() && verValue.CanSet() { - session.incrVersionFieldValue(verValue) - } - } - - if len(res) < 1 { - return 0, errors.New("insert no error but not returned id") - } - - idByte := res[0][table.AutoIncrement] - id, err := strconv.ParseInt(string(idByte), 10, 64) - if err != nil || id <= 0 { - return 1, err - } - - aiValue, err := table.AutoIncrColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } - - if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { - return 1, nil - } - - aiValue.Set(int64ToIntValue(id, aiValue.Type())) - - return 1, nil - } else if len(table.AutoIncrement) > 0 && (session.engine.dialect.DBType() == core.POSTGRES || session.engine.dialect.DBType() == core.MSSQL) { - res, err := session.queryBytes(sqlStr, args...) - - if err != nil { - return 0, err - } - defer handleAfterInsertProcessorFunc(bean) - - session.cacheInsert(tableName) - - if table.Version != "" && session.statement.checkVersion { - verValue, err := table.VersionColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } else if verValue.IsValid() && verValue.CanSet() { - session.incrVersionFieldValue(verValue) - } - } - - if len(res) < 1 { - return 0, errors.New("insert successfully but not returned id") - } - - idByte := res[0][table.AutoIncrement] - id, err := strconv.ParseInt(string(idByte), 10, 64) - if err != nil || id <= 0 { - return 1, err - } - - aiValue, err := table.AutoIncrColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } - - if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { - return 1, nil - } - - aiValue.Set(int64ToIntValue(id, aiValue.Type())) - - return 1, nil - } else { - res, err := session.exec(sqlStr, args...) - if err != nil { - return 0, err - } - - defer handleAfterInsertProcessorFunc(bean) - - session.cacheInsert(tableName) - - if table.Version != "" && session.statement.checkVersion { - verValue, err := table.VersionColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } else if verValue.IsValid() && verValue.CanSet() { - session.incrVersionFieldValue(verValue) - } - } - - if table.AutoIncrement == "" { - return res.RowsAffected() - } - - var id int64 - id, err = res.LastInsertId() - if err != nil || id <= 0 { - return res.RowsAffected() - } - - aiValue, err := table.AutoIncrColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } - - if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { - return res.RowsAffected() - } - - aiValue.Set(int64ToIntValue(id, aiValue.Type())) - - return res.RowsAffected() - } -} - -// InsertOne insert only one struct into database as a record. -// The in parameter bean must a struct or a point to struct. The return -// parameter is inserted and error -func (session *Session) InsertOne(bean interface{}) (int64, error) { - if session.isAutoClose { - defer session.Close() - } - - return session.innerInsert(bean) -} - -func (session *Session) cacheInsert(table string) error { - if !session.statement.UseCache { - return nil - } - cacher := session.engine.getCacher(table) - if cacher == nil { - return nil - } - session.engine.logger.Debug("[cache] clear sql:", table) - cacher.ClearIds(table) - return nil -} - -// genInsertColumns generates insert needed columns -func (session *Session) genInsertColumns(bean interface{}) ([]string, []interface{}, error) { - table := session.statement.RefTable - colNames := make([]string, 0, len(table.ColumnsSeq())) - args := make([]interface{}, 0, len(table.ColumnsSeq())) - - for _, col := range table.Columns() { - if col.MapType == core.ONLYFROMDB { - continue - } - - if col.IsDeleted { - continue - } - - if session.statement.omitColumnMap.contain(col.Name) { - continue - } - - if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { - continue - } - - if session.statement.incrColumns.isColExist(col.Name) { - continue - } else if session.statement.decrColumns.isColExist(col.Name) { - continue - } else if session.statement.exprColumns.isColExist(col.Name) { - continue - } - - fieldValuePtr, err := col.ValueOf(bean) - if err != nil { - return nil, nil, err - } - fieldValue := *fieldValuePtr - - if col.IsAutoIncrement { - switch fieldValue.Type().Kind() { - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: - if fieldValue.Int() == 0 { - continue - } - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: - if fieldValue.Uint() == 0 { - continue - } - case reflect.String: - if len(fieldValue.String()) == 0 { - continue - } - case reflect.Ptr: - if fieldValue.Pointer() == 0 { - continue - } - } - } - - // !evalphobia! set fieldValue as nil when column is nullable and zero-value - if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok { - if col.Nullable && isZero(fieldValue.Interface()) { - var nilValue *int - fieldValue = reflect.ValueOf(nilValue) - } - } - - if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { - // if time is non-empty, then set to auto time - val, t := session.engine.nowTime(col) - args = append(args, val) - - var colName = col.Name - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnTime(bean, col, t) - }) - } else if col.IsVersion && session.statement.checkVersion { - args = append(args, 1) - } else { - arg, err := session.value2Interface(col, fieldValue) - if err != nil { - return colNames, args, err - } - args = append(args, arg) - } - - colNames = append(colNames, col.Name) - } - return colNames, args, nil -} - -func (session *Session) insertMapInterface(m map[string]interface{}) (int64, error) { - if len(m) == 0 { - return 0, ErrParamsType - } - - tableName := session.statement.TableName() - if len(tableName) <= 0 { - return 0, ErrTableNotFound - } - - var columns = make([]string, 0, len(m)) - exprs := session.statement.exprColumns - for k := range m { - if !exprs.isColExist(k) { - columns = append(columns, k) - } - } - sort.Strings(columns) - - var args = make([]interface{}, 0, len(m)) - for _, colName := range columns { - args = append(args, m[colName]) - } - - w := builder.NewWriter() - if session.statement.cond.IsValid() { - if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil { - return 0, err - } - - if err := writeStrings(w, append(columns, exprs.colNames...), "`", "`"); err != nil { - return 0, err - } - - if _, err := w.WriteString(") SELECT "); err != nil { - return 0, err - } - - if err := session.statement.writeArgs(w, args); err != nil { - return 0, err - } - - if len(exprs.args) > 0 { - if _, err := w.WriteString(","); err != nil { - return 0, err - } - if err := exprs.writeArgs(w); err != nil { - return 0, err - } - } - - if _, err := w.WriteString(fmt.Sprintf(" FROM %s WHERE ", session.engine.Quote(tableName))); err != nil { - return 0, err - } - - if err := session.statement.cond.WriteTo(w); err != nil { - return 0, err - } - } else { - qm := strings.Repeat("?,", len(columns)) - qm = qm[:len(qm)-1] - - if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)); err != nil { - return 0, err - } - w.Append(args...) - } - - sql := w.String() - args = w.Args() - - if err := session.cacheInsert(tableName); err != nil { - return 0, err - } - - res, err := session.exec(sql, args...) - if err != nil { - return 0, err - } - affected, err := res.RowsAffected() - if err != nil { - return 0, err - } - return affected, nil -} - -func (session *Session) insertMapString(m map[string]string) (int64, error) { - if len(m) == 0 { - return 0, ErrParamsType - } - - tableName := session.statement.TableName() - if len(tableName) <= 0 { - return 0, ErrTableNotFound - } - - var columns = make([]string, 0, len(m)) - exprs := session.statement.exprColumns - for k := range m { - if !exprs.isColExist(k) { - columns = append(columns, k) - } - } - sort.Strings(columns) - - var args = make([]interface{}, 0, len(m)) - for _, colName := range columns { - args = append(args, m[colName]) - } - - w := builder.NewWriter() - if session.statement.cond.IsValid() { - if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil { - return 0, err - } - - if err := writeStrings(w, append(columns, exprs.colNames...), "`", "`"); err != nil { - return 0, err - } - - if _, err := w.WriteString(") SELECT "); err != nil { - return 0, err - } - - if err := session.statement.writeArgs(w, args); err != nil { - return 0, err - } - - if len(exprs.args) > 0 { - if _, err := w.WriteString(","); err != nil { - return 0, err - } - if err := exprs.writeArgs(w); err != nil { - return 0, err - } - } - - if _, err := w.WriteString(fmt.Sprintf(" FROM %s WHERE ", session.engine.Quote(tableName))); err != nil { - return 0, err - } - - if err := session.statement.cond.WriteTo(w); err != nil { - return 0, err - } - } else { - qm := strings.Repeat("?,", len(columns)) - qm = qm[:len(qm)-1] - - if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)); err != nil { - return 0, err - } - w.Append(args...) - } - - sql := w.String() - args = w.Args() - - if err := session.cacheInsert(tableName); err != nil { - return 0, err - } - - res, err := session.exec(sql, args...) - if err != nil { - return 0, err - } - affected, err := res.RowsAffected() - if err != nil { - return 0, err - } - return affected, nil -} diff --git a/vendor/github.com/go-xorm/xorm/session_iterate.go b/vendor/github.com/go-xorm/xorm/session_iterate.go deleted file mode 100644 index ca996c2884..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_iterate.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import "reflect" - -// IterFunc only use by Iterate -type IterFunc func(idx int, bean interface{}) error - -// Rows return sql.Rows compatible Rows obj, as a forward Iterator object for iterating record by record, bean's non-empty fields -// are conditions. -func (session *Session) Rows(bean interface{}) (*Rows, error) { - return newRows(session, bean) -} - -// Iterate record by record handle records from table, condiBeans's non-empty fields -// are conditions. beans could be []Struct, []*Struct, map[int64]Struct -// map[int64]*Struct -func (session *Session) Iterate(bean interface{}, fun IterFunc) error { - if session.isAutoClose { - defer session.Close() - } - - if session.statement.lastError != nil { - return session.statement.lastError - } - - if session.statement.bufferSize > 0 { - return session.bufferIterate(bean, fun) - } - - rows, err := session.Rows(bean) - if err != nil { - return err - } - defer rows.Close() - - i := 0 - for rows.Next() { - b := reflect.New(rows.beanType).Interface() - err = rows.Scan(b) - if err != nil { - return err - } - err = fun(i, b) - if err != nil { - return err - } - i++ - } - return err -} - -// BufferSize sets the buffersize for iterate -func (session *Session) BufferSize(size int) *Session { - session.statement.bufferSize = size - return session -} - -func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error { - if session.isAutoClose { - defer session.Close() - } - - var bufferSize = session.statement.bufferSize - var limit = session.statement.LimitN - if limit > 0 && bufferSize > limit { - bufferSize = limit - } - var start = session.statement.Start - v := rValue(bean) - sliceType := reflect.SliceOf(v.Type()) - var idx = 0 - for { - slice := reflect.New(sliceType) - if err := session.Limit(bufferSize, start).find(slice.Interface(), bean); err != nil { - return err - } - - for i := 0; i < slice.Elem().Len(); i++ { - if err := fun(idx, slice.Elem().Index(i).Addr().Interface()); err != nil { - return err - } - idx++ - } - - start = start + slice.Elem().Len() - if limit > 0 && idx+bufferSize > limit { - bufferSize = limit - idx - } - - if bufferSize <= 0 || slice.Elem().Len() < bufferSize || idx == limit { - break - } - } - - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/session_query.go b/vendor/github.com/go-xorm/xorm/session_query.go deleted file mode 100644 index 21c00b8d7f..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_query.go +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "time" - - "xorm.io/builder" - "xorm.io/core" -) - -func (session *Session) genQuerySQL(sqlOrArgs ...interface{}) (string, []interface{}, error) { - if len(sqlOrArgs) > 0 { - return convertSQLOrArgs(sqlOrArgs...) - } - - if session.statement.RawSQL != "" { - return session.statement.RawSQL, session.statement.RawParams, nil - } - - if len(session.statement.TableName()) <= 0 { - return "", nil, ErrTableNotFound - } - - var columnStr = session.statement.ColumnStr - if len(session.statement.selectStr) > 0 { - columnStr = session.statement.selectStr - } else { - if session.statement.JoinStr == "" { - if columnStr == "" { - if session.statement.GroupByStr != "" { - columnStr = session.engine.quoteColumns(session.statement.GroupByStr) - } else { - columnStr = session.statement.genColumnStr() - } - } - } else { - if columnStr == "" { - if session.statement.GroupByStr != "" { - columnStr = session.engine.quoteColumns(session.statement.GroupByStr) - } else { - columnStr = "*" - } - } - } - if columnStr == "" { - columnStr = "*" - } - } - - if err := session.statement.processIDParam(); err != nil { - return "", nil, err - } - - condSQL, condArgs, err := builder.ToSQL(session.statement.cond) - if err != nil { - return "", nil, err - } - - args := append(session.statement.joinArgs, condArgs...) - sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL, true, true) - if err != nil { - return "", nil, err - } - // for mssql and use limit - qs := strings.Count(sqlStr, "?") - if len(args)*2 == qs { - args = append(args, args...) - } - - return sqlStr, args, nil -} - -// Query runs a raw sql and return records as []map[string][]byte -func (session *Session) Query(sqlOrArgs ...interface{}) ([]map[string][]byte, error) { - if session.isAutoClose { - defer session.Close() - } - - sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) - if err != nil { - return nil, err - } - - return session.queryBytes(sqlStr, args...) -} - -func value2String(rawValue *reflect.Value) (str string, err error) { - aa := reflect.TypeOf((*rawValue).Interface()) - vv := reflect.ValueOf((*rawValue).Interface()) - switch aa.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - str = strconv.FormatInt(vv.Int(), 10) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - str = strconv.FormatUint(vv.Uint(), 10) - case reflect.Float32, reflect.Float64: - str = strconv.FormatFloat(vv.Float(), 'f', -1, 64) - case reflect.String: - str = vv.String() - case reflect.Array, reflect.Slice: - switch aa.Elem().Kind() { - case reflect.Uint8: - data := rawValue.Interface().([]byte) - str = string(data) - if str == "\x00" { - str = "0" - } - default: - err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) - } - // time type - case reflect.Struct: - if aa.ConvertibleTo(core.TimeType) { - str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano) - } else { - err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) - } - case reflect.Bool: - str = strconv.FormatBool(vv.Bool()) - case reflect.Complex128, reflect.Complex64: - str = fmt.Sprintf("%v", vv.Complex()) - /* TODO: unsupported types below - case reflect.Map: - case reflect.Ptr: - case reflect.Uintptr: - case reflect.UnsafePointer: - case reflect.Chan, reflect.Func, reflect.Interface: - */ - default: - err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) - } - return -} - -func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) { - result := make(map[string]string) - scanResultContainers := make([]interface{}, len(fields)) - for i := 0; i < len(fields); i++ { - var scanResultContainer interface{} - scanResultContainers[i] = &scanResultContainer - } - if err := rows.Scan(scanResultContainers...); err != nil { - return nil, err - } - - for ii, key := range fields { - rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])) - // if row is null then as empty string - if rawValue.Interface() == nil { - result[key] = "" - continue - } - - if data, err := value2String(&rawValue); err == nil { - result[key] = data - } else { - return nil, err - } - } - return result, nil -} - -func row2sliceStr(rows *core.Rows, fields []string) (results []string, err error) { - result := make([]string, 0, len(fields)) - scanResultContainers := make([]interface{}, len(fields)) - for i := 0; i < len(fields); i++ { - var scanResultContainer interface{} - scanResultContainers[i] = &scanResultContainer - } - if err := rows.Scan(scanResultContainers...); err != nil { - return nil, err - } - - for i := 0; i < len(fields); i++ { - rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[i])) - // if row is null then as empty string - if rawValue.Interface() == nil { - result = append(result, "") - continue - } - - if data, err := value2String(&rawValue); err == nil { - result = append(result, data) - } else { - return nil, err - } - } - return result, nil -} - -func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) { - fields, err := rows.Columns() - if err != nil { - return nil, err - } - for rows.Next() { - result, err := row2mapStr(rows, fields) - if err != nil { - return nil, err - } - resultsSlice = append(resultsSlice, result) - } - - return resultsSlice, nil -} - -func rows2SliceString(rows *core.Rows) (resultsSlice [][]string, err error) { - fields, err := rows.Columns() - if err != nil { - return nil, err - } - for rows.Next() { - record, err := row2sliceStr(rows, fields) - if err != nil { - return nil, err - } - resultsSlice = append(resultsSlice, record) - } - - return resultsSlice, nil -} - -// QueryString runs a raw sql and return records as []map[string]string -func (session *Session) QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) { - if session.isAutoClose { - defer session.Close() - } - - sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) - if err != nil { - return nil, err - } - - rows, err := session.queryRows(sqlStr, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - return rows2Strings(rows) -} - -// QuerySliceString runs a raw sql and return records as [][]string -func (session *Session) QuerySliceString(sqlOrArgs ...interface{}) ([][]string, error) { - if session.isAutoClose { - defer session.Close() - } - - sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) - if err != nil { - return nil, err - } - - rows, err := session.queryRows(sqlStr, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - return rows2SliceString(rows) -} - -func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) { - resultsMap = make(map[string]interface{}, len(fields)) - scanResultContainers := make([]interface{}, len(fields)) - for i := 0; i < len(fields); i++ { - var scanResultContainer interface{} - scanResultContainers[i] = &scanResultContainer - } - if err := rows.Scan(scanResultContainers...); err != nil { - return nil, err - } - - for ii, key := range fields { - resultsMap[key] = reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])).Interface() - } - return -} - -func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) { - fields, err := rows.Columns() - if err != nil { - return nil, err - } - for rows.Next() { - result, err := row2mapInterface(rows, fields) - if err != nil { - return nil, err - } - resultsSlice = append(resultsSlice, result) - } - - return resultsSlice, nil -} - -// QueryInterface runs a raw sql and return records as []map[string]interface{} -func (session *Session) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) { - if session.isAutoClose { - defer session.Close() - } - - sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) - if err != nil { - return nil, err - } - - rows, err := session.queryRows(sqlStr, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - return rows2Interfaces(rows) -} diff --git a/vendor/github.com/go-xorm/xorm/session_raw.go b/vendor/github.com/go-xorm/xorm/session_raw.go deleted file mode 100644 index 67648ef130..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_raw.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql" - "reflect" - "time" - - "xorm.io/builder" - "xorm.io/core" -) - -func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) { - for _, filter := range session.engine.dialect.Filters() { - *sqlStr = filter.Do(*sqlStr, session.engine.dialect, session.statement.RefTable) - } - - session.lastSQL = *sqlStr - session.lastSQLArgs = paramStr -} - -func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Rows, error) { - defer session.resetStatement() - - session.queryPreprocess(&sqlStr, args...) - - if session.engine.showSQL { - if session.engine.showExecTime { - b4ExecTime := time.Now() - defer func() { - execDuration := time.Since(b4ExecTime) - if len(args) > 0 { - session.engine.logger.Infof("[SQL] %s %#v - took: %v", sqlStr, args, execDuration) - } else { - session.engine.logger.Infof("[SQL] %s - took: %v", sqlStr, execDuration) - } - }() - } else { - if len(args) > 0 { - session.engine.logger.Infof("[SQL] %v %#v", sqlStr, args) - } else { - session.engine.logger.Infof("[SQL] %v", sqlStr) - } - } - } - - if session.isAutoCommit { - var db *core.DB - if session.sessionType == groupSession { - db = session.engine.engineGroup.Slave().DB() - } else { - db = session.DB() - } - - if session.prepareStmt { - // don't clear stmt since session will cache them - stmt, err := session.doPrepare(db, sqlStr) - if err != nil { - return nil, err - } - - rows, err := stmt.QueryContext(session.ctx, args...) - if err != nil { - return nil, err - } - return rows, nil - } - - rows, err := db.QueryContext(session.ctx, sqlStr, args...) - if err != nil { - return nil, err - } - return rows, nil - } - - rows, err := session.tx.QueryContext(session.ctx, sqlStr, args...) - if err != nil { - return nil, err - } - return rows, nil -} - -func (session *Session) queryRow(sqlStr string, args ...interface{}) *core.Row { - return core.NewRow(session.queryRows(sqlStr, args...)) -} - -func value2Bytes(rawValue *reflect.Value) ([]byte, error) { - str, err := value2String(rawValue) - if err != nil { - return nil, err - } - return []byte(str), nil -} - -func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) { - result := make(map[string][]byte) - scanResultContainers := make([]interface{}, len(fields)) - for i := 0; i < len(fields); i++ { - var scanResultContainer interface{} - scanResultContainers[i] = &scanResultContainer - } - if err := rows.Scan(scanResultContainers...); err != nil { - return nil, err - } - - for ii, key := range fields { - rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])) - //if row is null then ignore - if rawValue.Interface() == nil { - result[key] = []byte{} - continue - } - - if data, err := value2Bytes(&rawValue); err == nil { - result[key] = data - } else { - return nil, err // !nashtsai! REVIEW, should return err or just error log? - } - } - return result, nil -} - -func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) { - fields, err := rows.Columns() - if err != nil { - return nil, err - } - for rows.Next() { - result, err := row2map(rows, fields) - if err != nil { - return nil, err - } - resultsSlice = append(resultsSlice, result) - } - - return resultsSlice, nil -} - -func (session *Session) queryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) { - rows, err := session.queryRows(sqlStr, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - return rows2maps(rows) -} - -func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) { - defer session.resetStatement() - - session.queryPreprocess(&sqlStr, args...) - - if session.engine.showSQL { - if session.engine.showExecTime { - b4ExecTime := time.Now() - defer func() { - execDuration := time.Since(b4ExecTime) - if len(args) > 0 { - session.engine.logger.Infof("[SQL] %s %#v - took: %v", sqlStr, args, execDuration) - } else { - session.engine.logger.Infof("[SQL] %s - took: %v", sqlStr, execDuration) - } - }() - } else { - if len(args) > 0 { - session.engine.logger.Infof("[SQL] %v %#v", sqlStr, args) - } else { - session.engine.logger.Infof("[SQL] %v", sqlStr) - } - } - } - - if !session.isAutoCommit { - return session.tx.ExecContext(session.ctx, sqlStr, args...) - } - - if session.prepareStmt { - stmt, err := session.doPrepare(session.DB(), sqlStr) - if err != nil { - return nil, err - } - - res, err := stmt.ExecContext(session.ctx, args...) - if err != nil { - return nil, err - } - return res, nil - } - - return session.DB().ExecContext(session.ctx, sqlStr, args...) -} - -func convertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) { - switch sqlOrArgs[0].(type) { - case string: - return sqlOrArgs[0].(string), sqlOrArgs[1:], nil - case *builder.Builder: - return sqlOrArgs[0].(*builder.Builder).ToSQL() - case builder.Builder: - bd := sqlOrArgs[0].(builder.Builder) - return bd.ToSQL() - } - - return "", nil, ErrUnSupportedType -} - -// Exec raw sql -func (session *Session) Exec(sqlOrArgs ...interface{}) (sql.Result, error) { - if session.isAutoClose { - defer session.Close() - } - - if len(sqlOrArgs) == 0 { - return nil, ErrUnSupportedType - } - - sqlStr, args, err := convertSQLOrArgs(sqlOrArgs...) - if err != nil { - return nil, err - } - - return session.exec(sqlStr, args...) -} diff --git a/vendor/github.com/go-xorm/xorm/session_schema.go b/vendor/github.com/go-xorm/xorm/session_schema.go deleted file mode 100644 index 5e576c29aa..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_schema.go +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql" - "fmt" - "strings" - - "xorm.io/core" -) - -// Ping test if database is ok -func (session *Session) Ping() error { - if session.isAutoClose { - defer session.Close() - } - - session.engine.logger.Infof("PING DATABASE %v", session.engine.DriverName()) - return session.DB().PingContext(session.ctx) -} - -// CreateTable create a table according a bean -func (session *Session) CreateTable(bean interface{}) error { - if session.isAutoClose { - defer session.Close() - } - - return session.createTable(bean) -} - -func (session *Session) createTable(bean interface{}) error { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - - sqlStr := session.statement.genCreateTableSQL() - _, err := session.exec(sqlStr) - return err -} - -// CreateIndexes create indexes -func (session *Session) CreateIndexes(bean interface{}) error { - if session.isAutoClose { - defer session.Close() - } - - return session.createIndexes(bean) -} - -func (session *Session) createIndexes(bean interface{}) error { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - - sqls := session.statement.genIndexSQL() - for _, sqlStr := range sqls { - _, err := session.exec(sqlStr) - if err != nil { - return err - } - } - return nil -} - -// CreateUniques create uniques -func (session *Session) CreateUniques(bean interface{}) error { - if session.isAutoClose { - defer session.Close() - } - return session.createUniques(bean) -} - -func (session *Session) createUniques(bean interface{}) error { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - - sqls := session.statement.genUniqueSQL() - for _, sqlStr := range sqls { - _, err := session.exec(sqlStr) - if err != nil { - return err - } - } - return nil -} - -// DropIndexes drop indexes -func (session *Session) DropIndexes(bean interface{}) error { - if session.isAutoClose { - defer session.Close() - } - - return session.dropIndexes(bean) -} - -func (session *Session) dropIndexes(bean interface{}) error { - if err := session.statement.setRefBean(bean); err != nil { - return err - } - - sqls := session.statement.genDelIndexSQL() - for _, sqlStr := range sqls { - _, err := session.exec(sqlStr) - if err != nil { - return err - } - } - return nil -} - -// DropTable drop table will drop table if exist, if drop failed, it will return error -func (session *Session) DropTable(beanOrTableName interface{}) error { - if session.isAutoClose { - defer session.Close() - } - - return session.dropTable(beanOrTableName) -} - -func (session *Session) dropTable(beanOrTableName interface{}) error { - tableName := session.engine.TableName(beanOrTableName) - var needDrop = true - if !session.engine.dialect.SupportDropIfExists() { - sqlStr, args := session.engine.dialect.TableCheckSql(tableName) - results, err := session.queryBytes(sqlStr, args...) - if err != nil { - return err - } - needDrop = len(results) > 0 - } - - if needDrop { - sqlStr := session.engine.Dialect().DropTableSql(session.engine.TableName(tableName, true)) - _, err := session.exec(sqlStr) - return err - } - return nil -} - -// IsTableExist if a table is exist -func (session *Session) IsTableExist(beanOrTableName interface{}) (bool, error) { - if session.isAutoClose { - defer session.Close() - } - - tableName := session.engine.TableName(beanOrTableName) - - return session.isTableExist(tableName) -} - -func (session *Session) isTableExist(tableName string) (bool, error) { - sqlStr, args := session.engine.dialect.TableCheckSql(tableName) - results, err := session.queryBytes(sqlStr, args...) - return len(results) > 0, err -} - -// IsTableEmpty if table have any records -func (session *Session) IsTableEmpty(bean interface{}) (bool, error) { - if session.isAutoClose { - defer session.Close() - } - return session.isTableEmpty(session.engine.TableName(bean)) -} - -func (session *Session) isTableEmpty(tableName string) (bool, error) { - var total int64 - sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(session.engine.TableName(tableName, true))) - err := session.queryRow(sqlStr).Scan(&total) - if err != nil { - if err == sql.ErrNoRows { - err = nil - } - return true, err - } - - return total == 0, nil -} - -// find if index is exist according cols -func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) { - indexes, err := session.engine.dialect.GetIndexes(tableName) - if err != nil { - return false, err - } - - for _, index := range indexes { - if sliceEq(index.Cols, cols) { - if unique { - return index.Type == core.UniqueType, nil - } - return index.Type == core.IndexType, nil - } - } - return false, nil -} - -func (session *Session) addColumn(colName string) error { - col := session.statement.RefTable.GetColumn(colName) - sql, args := session.statement.genAddColumnStr(col) - _, err := session.exec(sql, args...) - return err -} - -func (session *Session) addIndex(tableName, idxName string) error { - index := session.statement.RefTable.Indexes[idxName] - sqlStr := session.engine.dialect.CreateIndexSql(tableName, index) - _, err := session.exec(sqlStr) - return err -} - -func (session *Session) addUnique(tableName, uqeName string) error { - index := session.statement.RefTable.Indexes[uqeName] - sqlStr := session.engine.dialect.CreateIndexSql(tableName, index) - _, err := session.exec(sqlStr) - return err -} - -// Sync2 synchronize structs to database tables -func (session *Session) Sync2(beans ...interface{}) error { - engine := session.engine - - if session.isAutoClose { - session.isAutoClose = false - defer session.Close() - } - - tables, err := engine.dialect.GetTables() - if err != nil { - return err - } - - session.autoResetStatement = false - defer func() { - session.autoResetStatement = true - session.resetStatement() - }() - - for _, bean := range beans { - v := rValue(bean) - table, err := engine.mapType(v) - if err != nil { - return err - } - var tbName string - if len(session.statement.AltTableName) > 0 { - tbName = session.statement.AltTableName - } else { - tbName = engine.TableName(bean) - } - tbNameWithSchema := engine.tbNameWithSchema(tbName) - - var oriTable *core.Table - for _, tb := range tables { - if strings.EqualFold(engine.tbNameWithSchema(tb.Name), engine.tbNameWithSchema(tbName)) { - oriTable = tb - break - } - } - - // this is a new table - if oriTable == nil { - err = session.StoreEngine(session.statement.StoreEngine).createTable(bean) - if err != nil { - return err - } - - err = session.createUniques(bean) - if err != nil { - return err - } - - err = session.createIndexes(bean) - if err != nil { - return err - } - continue - } - - // this will modify an old table - if err = engine.loadTableInfo(oriTable); err != nil { - return err - } - - // check columns - for _, col := range table.Columns() { - var oriCol *core.Column - for _, col2 := range oriTable.Columns() { - if strings.EqualFold(col.Name, col2.Name) { - oriCol = col2 - break - } - } - - // column is not exist on table - if oriCol == nil { - session.statement.RefTable = table - session.statement.tableName = tbNameWithSchema - if err = session.addColumn(col.Name); err != nil { - return err - } - continue - } - - err = nil - expectedType := engine.dialect.SqlType(col) - curType := engine.dialect.SqlType(oriCol) - if expectedType != curType { - if expectedType == core.Text && - strings.HasPrefix(curType, core.Varchar) { - // currently only support mysql & postgres - if engine.dialect.DBType() == core.MYSQL || - engine.dialect.DBType() == core.POSTGRES { - engine.logger.Infof("Table %s column %s change type from %s to %s\n", - tbNameWithSchema, col.Name, curType, expectedType) - _, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) - } else { - engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n", - tbNameWithSchema, col.Name, curType, expectedType) - } - } else if strings.HasPrefix(curType, core.Varchar) && strings.HasPrefix(expectedType, core.Varchar) { - if engine.dialect.DBType() == core.MYSQL { - if oriCol.Length < col.Length { - engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", - tbNameWithSchema, col.Name, oriCol.Length, col.Length) - _, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) - } - } - } else { - if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') { - engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s", - tbNameWithSchema, col.Name, curType, expectedType) - } - } - } else if expectedType == core.Varchar { - if engine.dialect.DBType() == core.MYSQL { - if oriCol.Length < col.Length { - engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", - tbNameWithSchema, col.Name, oriCol.Length, col.Length) - _, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) - } - } - } - - if col.Default != oriCol.Default { - if (col.SQLType.Name == core.Bool || col.SQLType.Name == core.Boolean) && - ((strings.EqualFold(col.Default, "true") && oriCol.Default == "1") || - (strings.EqualFold(col.Default, "false") && oriCol.Default == "0")) { - } else { - engine.logger.Warnf("Table %s Column %s db default is %s, struct default is %s", - tbName, col.Name, oriCol.Default, col.Default) - } - } - if col.Nullable != oriCol.Nullable { - engine.logger.Warnf("Table %s Column %s db nullable is %v, struct nullable is %v", - tbName, col.Name, oriCol.Nullable, col.Nullable) - } - - if err != nil { - return err - } - } - - var foundIndexNames = make(map[string]bool) - var addedNames = make(map[string]*core.Index) - - for name, index := range table.Indexes { - var oriIndex *core.Index - for name2, index2 := range oriTable.Indexes { - if index.Equal(index2) { - oriIndex = index2 - foundIndexNames[name2] = true - break - } - } - - if oriIndex != nil { - if oriIndex.Type != index.Type { - sql := engine.dialect.DropIndexSql(tbNameWithSchema, oriIndex) - _, err = session.exec(sql) - if err != nil { - return err - } - oriIndex = nil - } - } - - if oriIndex == nil { - addedNames[name] = index - } - } - - for name2, index2 := range oriTable.Indexes { - if _, ok := foundIndexNames[name2]; !ok { - sql := engine.dialect.DropIndexSql(tbNameWithSchema, index2) - _, err = session.exec(sql) - if err != nil { - return err - } - } - } - - for name, index := range addedNames { - if index.Type == core.UniqueType { - session.statement.RefTable = table - session.statement.tableName = tbNameWithSchema - err = session.addUnique(tbNameWithSchema, name) - } else if index.Type == core.IndexType { - session.statement.RefTable = table - session.statement.tableName = tbNameWithSchema - err = session.addIndex(tbNameWithSchema, name) - } - if err != nil { - return err - } - } - - // check all the columns which removed from struct fields but left on database tables. - for _, colName := range oriTable.ColumnsSeq() { - if table.GetColumn(colName) == nil { - engine.logger.Warnf("Table %s has column %s but struct has not related field", engine.TableName(oriTable.Name, true), colName) - } - } - } - - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/session_stats.go b/vendor/github.com/go-xorm/xorm/session_stats.go deleted file mode 100644 index c2cac83069..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_stats.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql" - "errors" - "reflect" -) - -// Count counts the records. bean's non-empty fields -// are conditions. -func (session *Session) Count(bean ...interface{}) (int64, error) { - if session.isAutoClose { - defer session.Close() - } - - var sqlStr string - var args []interface{} - var err error - if session.statement.RawSQL == "" { - sqlStr, args, err = session.statement.genCountSQL(bean...) - if err != nil { - return 0, err - } - } else { - sqlStr = session.statement.RawSQL - args = session.statement.RawParams - } - - var total int64 - err = session.queryRow(sqlStr, args...).Scan(&total) - if err == sql.ErrNoRows || err == nil { - return total, nil - } - - return 0, err -} - -// sum call sum some column. bean's non-empty fields are conditions. -func (session *Session) sum(res interface{}, bean interface{}, columnNames ...string) error { - if session.isAutoClose { - defer session.Close() - } - - v := reflect.ValueOf(res) - if v.Kind() != reflect.Ptr { - return errors.New("need a pointer to a variable") - } - - var isSlice = v.Elem().Kind() == reflect.Slice - var sqlStr string - var args []interface{} - var err error - if len(session.statement.RawSQL) == 0 { - sqlStr, args, err = session.statement.genSumSQL(bean, columnNames...) - if err != nil { - return err - } - } else { - sqlStr = session.statement.RawSQL - args = session.statement.RawParams - } - - if isSlice { - err = session.queryRow(sqlStr, args...).ScanSlice(res) - } else { - err = session.queryRow(sqlStr, args...).Scan(res) - } - if err == sql.ErrNoRows || err == nil { - return nil - } - return err -} - -// Sum call sum some column. bean's non-empty fields are conditions. -func (session *Session) Sum(bean interface{}, columnName string) (res float64, err error) { - return res, session.sum(&res, bean, columnName) -} - -// SumInt call sum some column. bean's non-empty fields are conditions. -func (session *Session) SumInt(bean interface{}, columnName string) (res int64, err error) { - return res, session.sum(&res, bean, columnName) -} - -// Sums call sum some columns. bean's non-empty fields are conditions. -func (session *Session) Sums(bean interface{}, columnNames ...string) ([]float64, error) { - var res = make([]float64, len(columnNames), len(columnNames)) - return res, session.sum(&res, bean, columnNames...) -} - -// SumsInt sum specify columns and return as []int64 instead of []float64 -func (session *Session) SumsInt(bean interface{}, columnNames ...string) ([]int64, error) { - var res = make([]int64, len(columnNames), len(columnNames)) - return res, session.sum(&res, bean, columnNames...) -} diff --git a/vendor/github.com/go-xorm/xorm/session_tx.go b/vendor/github.com/go-xorm/xorm/session_tx.go deleted file mode 100644 index ee3d473f95..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_tx.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -// Begin a transaction -func (session *Session) Begin() error { - if session.isAutoCommit { - tx, err := session.DB().BeginTx(session.ctx, nil) - if err != nil { - return err - } - session.isAutoCommit = false - session.isCommitedOrRollbacked = false - session.tx = tx - session.saveLastSQL("BEGIN TRANSACTION") - } - return nil -} - -// Rollback When using transaction, you can rollback if any error -func (session *Session) Rollback() error { - if !session.isAutoCommit && !session.isCommitedOrRollbacked { - session.saveLastSQL(session.engine.dialect.RollBackStr()) - session.isCommitedOrRollbacked = true - session.isAutoCommit = true - return session.tx.Rollback() - } - return nil -} - -// Commit When using transaction, Commit will commit all operations. -func (session *Session) Commit() error { - if !session.isAutoCommit && !session.isCommitedOrRollbacked { - session.saveLastSQL("COMMIT") - session.isCommitedOrRollbacked = true - session.isAutoCommit = true - var err error - if err = session.tx.Commit(); err == nil { - // handle processors after tx committed - closureCallFunc := func(closuresPtr *[]func(interface{}), bean interface{}) { - if closuresPtr != nil { - for _, closure := range *closuresPtr { - closure(bean) - } - } - } - - for bean, closuresPtr := range session.afterInsertBeans { - closureCallFunc(closuresPtr, bean) - - if processor, ok := interface{}(bean).(AfterInsertProcessor); ok { - processor.AfterInsert() - } - } - for bean, closuresPtr := range session.afterUpdateBeans { - closureCallFunc(closuresPtr, bean) - - if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok { - processor.AfterUpdate() - } - } - for bean, closuresPtr := range session.afterDeleteBeans { - closureCallFunc(closuresPtr, bean) - - if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok { - processor.AfterDelete() - } - } - cleanUpFunc := func(slices *map[interface{}]*[]func(interface{})) { - if len(*slices) > 0 { - *slices = make(map[interface{}]*[]func(interface{}), 0) - } - } - cleanUpFunc(&session.afterInsertBeans) - cleanUpFunc(&session.afterUpdateBeans) - cleanUpFunc(&session.afterDeleteBeans) - } - return err - } - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/session_update.go b/vendor/github.com/go-xorm/xorm/session_update.go deleted file mode 100644 index c5c65a452a..0000000000 --- a/vendor/github.com/go-xorm/xorm/session_update.go +++ /dev/null @@ -1,525 +0,0 @@ -// Copyright 2016 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "errors" - "fmt" - "reflect" - "strconv" - "strings" - - "xorm.io/builder" - "xorm.io/core" -) - -func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string, args ...interface{}) error { - if table == nil || - session.tx != nil { - return ErrCacheFailed - } - - oldhead, newsql := session.statement.convertUpdateSQL(sqlStr) - if newsql == "" { - return ErrCacheFailed - } - for _, filter := range session.engine.dialect.Filters() { - newsql = filter.Do(newsql, session.engine.dialect, table) - } - session.engine.logger.Debug("[cacheUpdate] new sql", oldhead, newsql) - - var nStart int - if len(args) > 0 { - if strings.Index(sqlStr, "?") > -1 { - nStart = strings.Count(oldhead, "?") - } else { - // only for pq, TODO: if any other databse? - nStart = strings.Count(oldhead, "$") - } - } - - cacher := session.engine.getCacher(tableName) - session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:]) - ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:]) - if err != nil { - rows, err := session.NoCache().queryRows(newsql, args[nStart:]...) - if err != nil { - return err - } - defer rows.Close() - - ids = make([]core.PK, 0) - for rows.Next() { - var res = make([]string, len(table.PrimaryKeys)) - err = rows.ScanSlice(&res) - if err != nil { - return err - } - var pk core.PK = make([]interface{}, len(table.PrimaryKeys)) - for i, col := range table.PKColumns() { - if col.SQLType.IsNumeric() { - n, err := strconv.ParseInt(res[i], 10, 64) - if err != nil { - return err - } - pk[i] = n - } else if col.SQLType.IsText() { - pk[i] = res[i] - } else { - return errors.New("not supported") - } - } - - ids = append(ids, pk) - } - session.engine.logger.Debug("[cacheUpdate] find updated id", ids) - } /*else { - session.engine.LogDebug("[xorm:cacheUpdate] del cached sql:", tableName, newsql, args) - cacher.DelIds(tableName, genSqlKey(newsql, args)) - }*/ - - for _, id := range ids { - sid, err := id.ToString() - if err != nil { - return err - } - if bean := cacher.GetBean(tableName, sid); bean != nil { - sqls := splitNNoCase(sqlStr, "where", 2) - if len(sqls) == 0 || len(sqls) > 2 { - return ErrCacheFailed - } - - sqls = splitNNoCase(sqls[0], "set", 2) - if len(sqls) != 2 { - return ErrCacheFailed - } - kvs := strings.Split(strings.TrimSpace(sqls[1]), ",") - - for idx, kv := range kvs { - sps := strings.SplitN(kv, "=", 2) - sps2 := strings.Split(sps[0], ".") - colName := sps2[len(sps2)-1] - // treat quote prefix, suffix and '`' as quotes - quotes := append(strings.Split(session.engine.Quote(""), ""), "`") - if strings.ContainsAny(colName, strings.Join(quotes, "")) { - colName = strings.TrimSpace(eraseAny(colName, quotes...)) - } else { - session.engine.logger.Debug("[cacheUpdate] cannot find column", tableName, colName) - return ErrCacheFailed - } - - if col := table.GetColumn(colName); col != nil { - fieldValue, err := col.ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } else { - session.engine.logger.Debug("[cacheUpdate] set bean field", bean, colName, fieldValue.Interface()) - if col.IsVersion && session.statement.checkVersion { - session.incrVersionFieldValue(fieldValue) - } else { - fieldValue.Set(reflect.ValueOf(args[idx])) - } - } - } else { - session.engine.logger.Errorf("[cacheUpdate] ERROR: column %v is not table %v's", - colName, table.Name) - } - } - - session.engine.logger.Debug("[cacheUpdate] update cache", tableName, id, bean) - cacher.PutBean(tableName, sid, bean) - } - } - session.engine.logger.Debug("[cacheUpdate] clear cached table sql:", tableName) - cacher.ClearIds(tableName) - return nil -} - -// Update records, bean's non-empty fields are updated contents, -// condiBean' non-empty filds are conditions -// CAUTION: -// 1.bool will defaultly be updated content nor conditions -// You should call UseBool if you have bool to use. -// 2.float32 & float64 may be not inexact as conditions -func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) { - if session.isAutoClose { - defer session.Close() - } - - if session.statement.lastError != nil { - return 0, session.statement.lastError - } - - v := rValue(bean) - t := v.Type() - - var colNames []string - var args []interface{} - - // handle before update processors - for _, closure := range session.beforeClosures { - closure(bean) - } - cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used - if processor, ok := interface{}(bean).(BeforeUpdateProcessor); ok { - processor.BeforeUpdate() - } - // -- - - var err error - var isMap = t.Kind() == reflect.Map - var isStruct = t.Kind() == reflect.Struct - if isStruct { - if err := session.statement.setRefBean(bean); err != nil { - return 0, err - } - - if len(session.statement.TableName()) <= 0 { - return 0, ErrTableNotFound - } - - if session.statement.ColumnStr == "" { - colNames, args = session.statement.buildUpdates(bean, false, false, - false, false, true) - } else { - colNames, args, err = session.genUpdateColumns(bean) - if err != nil { - return 0, err - } - } - } else if isMap { - colNames = make([]string, 0) - args = make([]interface{}, 0) - bValue := reflect.Indirect(reflect.ValueOf(bean)) - - for _, v := range bValue.MapKeys() { - colNames = append(colNames, session.engine.Quote(v.String())+" = ?") - args = append(args, bValue.MapIndex(v).Interface()) - } - } else { - return 0, ErrParamsType - } - - table := session.statement.RefTable - - if session.statement.UseAutoTime && table != nil && table.Updated != "" { - if !session.statement.columnMap.contain(table.Updated) && - !session.statement.omitColumnMap.contain(table.Updated) { - colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?") - col := table.UpdatedColumn() - val, t := session.engine.nowTime(col) - args = append(args, val) - - var colName = col.Name - if isStruct { - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnTime(bean, col, t) - }) - } - } - } - - // for update action to like "column = column + ?" - incColumns := session.statement.incrColumns - for i, colName := range incColumns.colNames { - colNames = append(colNames, session.engine.Quote(colName)+" = "+session.engine.Quote(colName)+" + ?") - args = append(args, incColumns.args[i]) - } - // for update action to like "column = column - ?" - decColumns := session.statement.decrColumns - for i, colName := range decColumns.colNames { - colNames = append(colNames, session.engine.Quote(colName)+" = "+session.engine.Quote(colName)+" - ?") - args = append(args, decColumns.args[i]) - } - // for update action to like "column = expression" - exprColumns := session.statement.exprColumns - for i, colName := range exprColumns.colNames { - switch tp := exprColumns.args[i].(type) { - case string: - colNames = append(colNames, session.engine.Quote(colName)+" = "+tp) - case *builder.Builder: - subQuery, subArgs, err := builder.ToSQL(tp) - if err != nil { - return 0, err - } - colNames = append(colNames, session.engine.Quote(colName)+" = ("+subQuery+")") - args = append(args, subArgs...) - } - } - - if err = session.statement.processIDParam(); err != nil { - return 0, err - } - - var autoCond builder.Cond - if !session.statement.noAutoCondition { - condBeanIsStruct := false - if len(condiBean) > 0 { - if c, ok := condiBean[0].(map[string]interface{}); ok { - autoCond = builder.Eq(c) - } else { - ct := reflect.TypeOf(condiBean[0]) - k := ct.Kind() - if k == reflect.Ptr { - k = ct.Elem().Kind() - } - if k == reflect.Struct { - var err error - autoCond, err = session.statement.buildConds(session.statement.RefTable, condiBean[0], true, true, false, true, false) - if err != nil { - return 0, err - } - condBeanIsStruct = true - } else { - return 0, ErrConditionType - } - } - } - - if !condBeanIsStruct && table != nil { - if col := table.DeletedColumn(); col != nil && !session.statement.unscoped { // tag "deleted" is enabled - autoCond1 := session.engine.CondDeleted(session.engine.Quote(col.Name)) - - if autoCond == nil { - autoCond = autoCond1 - } else { - autoCond = autoCond.And(autoCond1) - } - } - } - } - - st := &session.statement - - var sqlStr string - var condArgs []interface{} - var condSQL string - cond := session.statement.cond.And(autoCond) - - var doIncVer = (table != nil && table.Version != "" && session.statement.checkVersion) - var verValue *reflect.Value - if doIncVer { - verValue, err = table.VersionColumn().ValueOf(bean) - if err != nil { - return 0, err - } - - cond = cond.And(builder.Eq{session.engine.Quote(table.Version): verValue.Interface()}) - colNames = append(colNames, session.engine.Quote(table.Version)+" = "+session.engine.Quote(table.Version)+" + 1") - } - - condSQL, condArgs, err = builder.ToSQL(cond) - if err != nil { - return 0, err - } - - if len(condSQL) > 0 { - condSQL = "WHERE " + condSQL - } - - if st.OrderStr != "" { - condSQL = condSQL + fmt.Sprintf(" ORDER BY %v", st.OrderStr) - } - - var tableName = session.statement.TableName() - // TODO: Oracle support needed - var top string - if st.LimitN > 0 { - if st.Engine.dialect.DBType() == core.MYSQL { - condSQL = condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN) - } else if st.Engine.dialect.DBType() == core.SQLITE { - tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN) - cond = cond.And(builder.Expr(fmt.Sprintf("rowid IN (SELECT rowid FROM %v %v)", - session.engine.Quote(tableName), tempCondSQL), condArgs...)) - condSQL, condArgs, err = builder.ToSQL(cond) - if err != nil { - return 0, err - } - if len(condSQL) > 0 { - condSQL = "WHERE " + condSQL - } - } else if st.Engine.dialect.DBType() == core.POSTGRES { - tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN) - cond = cond.And(builder.Expr(fmt.Sprintf("CTID IN (SELECT CTID FROM %v %v)", - session.engine.Quote(tableName), tempCondSQL), condArgs...)) - condSQL, condArgs, err = builder.ToSQL(cond) - if err != nil { - return 0, err - } - - if len(condSQL) > 0 { - condSQL = "WHERE " + condSQL - } - } else if st.Engine.dialect.DBType() == core.MSSQL { - if st.OrderStr != "" && st.Engine.dialect.DBType() == core.MSSQL && - table != nil && len(table.PrimaryKeys) == 1 { - cond = builder.Expr(fmt.Sprintf("%s IN (SELECT TOP (%d) %s FROM %v%v)", - table.PrimaryKeys[0], st.LimitN, table.PrimaryKeys[0], - session.engine.Quote(tableName), condSQL), condArgs...) - - condSQL, condArgs, err = builder.ToSQL(cond) - if err != nil { - return 0, err - } - if len(condSQL) > 0 { - condSQL = "WHERE " + condSQL - } - } else { - top = fmt.Sprintf("TOP (%d) ", st.LimitN) - } - } - } - - if len(colNames) <= 0 { - return 0, errors.New("No content found to be updated") - } - - sqlStr = fmt.Sprintf("UPDATE %v%v SET %v %v", - top, - session.engine.Quote(tableName), - strings.Join(colNames, ", "), - condSQL) - - res, err := session.exec(sqlStr, append(args, condArgs...)...) - if err != nil { - return 0, err - } else if doIncVer { - if verValue != nil && verValue.IsValid() && verValue.CanSet() { - session.incrVersionFieldValue(verValue) - } - } - - if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache { - // session.cacheUpdate(table, tableName, sqlStr, args...) - session.engine.logger.Debug("[cacheUpdate] clear table ", tableName) - cacher.ClearIds(tableName) - cacher.ClearBeans(tableName) - } - - // handle after update processors - if session.isAutoCommit { - for _, closure := range session.afterClosures { - closure(bean) - } - if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok { - session.engine.logger.Debug("[event]", tableName, " has after update processor") - processor.AfterUpdate() - } - } else { - lenAfterClosures := len(session.afterClosures) - if lenAfterClosures > 0 { - if value, has := session.afterUpdateBeans[bean]; has && value != nil { - *value = append(*value, session.afterClosures...) - } else { - afterClosures := make([]func(interface{}), lenAfterClosures) - copy(afterClosures, session.afterClosures) - // FIXME: if bean is a map type, it will panic because map cannot be as map key - session.afterUpdateBeans[bean] = &afterClosures - } - - } else { - if _, ok := interface{}(bean).(AfterUpdateProcessor); ok { - session.afterUpdateBeans[bean] = nil - } - } - } - cleanupProcessorsClosures(&session.afterClosures) // cleanup after used - // -- - - return res.RowsAffected() -} - -func (session *Session) genUpdateColumns(bean interface{}) ([]string, []interface{}, error) { - table := session.statement.RefTable - colNames := make([]string, 0, len(table.ColumnsSeq())) - args := make([]interface{}, 0, len(table.ColumnsSeq())) - - for _, col := range table.Columns() { - if !col.IsVersion && !col.IsCreated && !col.IsUpdated { - if session.statement.omitColumnMap.contain(col.Name) { - continue - } - } - if col.MapType == core.ONLYFROMDB { - continue - } - - fieldValuePtr, err := col.ValueOf(bean) - if err != nil { - return nil, nil, err - } - fieldValue := *fieldValuePtr - - if col.IsAutoIncrement { - switch fieldValue.Type().Kind() { - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: - if fieldValue.Int() == 0 { - continue - } - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: - if fieldValue.Uint() == 0 { - continue - } - case reflect.String: - if len(fieldValue.String()) == 0 { - continue - } - case reflect.Ptr: - if fieldValue.Pointer() == 0 { - continue - } - } - } - - if (col.IsDeleted && !session.statement.unscoped) || col.IsCreated { - continue - } - - // if only update specify columns - if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { - continue - } - - if session.statement.incrColumns.isColExist(col.Name) { - continue - } else if session.statement.decrColumns.isColExist(col.Name) { - continue - } else if session.statement.exprColumns.isColExist(col.Name) { - continue - } - - // !evalphobia! set fieldValue as nil when column is nullable and zero-value - if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok { - if col.Nullable && isZero(fieldValue.Interface()) { - var nilValue *int - fieldValue = reflect.ValueOf(nilValue) - } - } - - if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { - // if time is non-empty, then set to auto time - val, t := session.engine.nowTime(col) - args = append(args, val) - - var colName = col.Name - session.afterClosures = append(session.afterClosures, func(bean interface{}) { - col := table.GetColumn(colName) - setColumnTime(bean, col, t) - }) - } else if col.IsVersion && session.statement.checkVersion { - args = append(args, 1) - } else { - arg, err := session.value2Interface(col, fieldValue) - if err != nil { - return colNames, args, err - } - args = append(args, arg) - } - - colNames = append(colNames, session.engine.Quote(col.Name)+" = ?") - } - return colNames, args, nil -} diff --git a/vendor/github.com/go-xorm/xorm/statement.go b/vendor/github.com/go-xorm/xorm/statement.go deleted file mode 100644 index ae396c4bae..0000000000 --- a/vendor/github.com/go-xorm/xorm/statement.go +++ /dev/null @@ -1,1252 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "database/sql/driver" - "fmt" - "reflect" - "strings" - "time" - - "xorm.io/builder" - "xorm.io/core" -) - -// Statement save all the sql info for executing SQL -type Statement struct { - RefTable *core.Table - Engine *Engine - Start int - LimitN int - idParam *core.PK - OrderStr string - JoinStr string - joinArgs []interface{} - GroupByStr string - HavingStr string - ColumnStr string - selectStr string - useAllCols bool - OmitStr string - AltTableName string - tableName string - RawSQL string - RawParams []interface{} - UseCascade bool - UseAutoJoin bool - StoreEngine string - Charset string - UseCache bool - UseAutoTime bool - noAutoCondition bool - IsDistinct bool - IsForUpdate bool - TableAlias string - allUseBool bool - checkVersion bool - unscoped bool - columnMap columnMap - omitColumnMap columnMap - mustColumnMap map[string]bool - nullableMap map[string]bool - incrColumns exprParams - decrColumns exprParams - exprColumns exprParams - cond builder.Cond - bufferSize int - context ContextCache - lastError error -} - -// Init reset all the statement's fields -func (statement *Statement) Init() { - statement.RefTable = nil - statement.Start = 0 - statement.LimitN = 0 - statement.OrderStr = "" - statement.UseCascade = true - statement.JoinStr = "" - statement.joinArgs = make([]interface{}, 0) - statement.GroupByStr = "" - statement.HavingStr = "" - statement.ColumnStr = "" - statement.OmitStr = "" - statement.columnMap = columnMap{} - statement.omitColumnMap = columnMap{} - statement.AltTableName = "" - statement.tableName = "" - statement.idParam = nil - statement.RawSQL = "" - statement.RawParams = make([]interface{}, 0) - statement.UseCache = true - statement.UseAutoTime = true - statement.noAutoCondition = false - statement.IsDistinct = false - statement.IsForUpdate = false - statement.TableAlias = "" - statement.selectStr = "" - statement.allUseBool = false - statement.useAllCols = false - statement.mustColumnMap = make(map[string]bool) - statement.nullableMap = make(map[string]bool) - statement.checkVersion = true - statement.unscoped = false - statement.incrColumns = exprParams{} - statement.decrColumns = exprParams{} - statement.exprColumns = exprParams{} - statement.cond = builder.NewCond() - statement.bufferSize = 0 - statement.context = nil - statement.lastError = nil -} - -// NoAutoCondition if you do not want convert bean's field as query condition, then use this function -func (statement *Statement) NoAutoCondition(no ...bool) *Statement { - statement.noAutoCondition = true - if len(no) > 0 { - statement.noAutoCondition = no[0] - } - return statement -} - -// Alias set the table alias -func (statement *Statement) Alias(alias string) *Statement { - statement.TableAlias = alias - return statement -} - -// SQL adds raw sql statement -func (statement *Statement) SQL(query interface{}, args ...interface{}) *Statement { - switch query.(type) { - case (*builder.Builder): - var err error - statement.RawSQL, statement.RawParams, err = query.(*builder.Builder).ToSQL() - if err != nil { - statement.lastError = err - } - case string: - statement.RawSQL = query.(string) - statement.RawParams = args - default: - statement.lastError = ErrUnSupportedSQLType - } - - return statement -} - -// Where add Where statement -func (statement *Statement) Where(query interface{}, args ...interface{}) *Statement { - return statement.And(query, args...) -} - -// And add Where & and statement -func (statement *Statement) And(query interface{}, args ...interface{}) *Statement { - switch query.(type) { - case string: - cond := builder.Expr(query.(string), args...) - statement.cond = statement.cond.And(cond) - case map[string]interface{}: - cond := builder.Eq(query.(map[string]interface{})) - statement.cond = statement.cond.And(cond) - case builder.Cond: - cond := query.(builder.Cond) - statement.cond = statement.cond.And(cond) - for _, v := range args { - if vv, ok := v.(builder.Cond); ok { - statement.cond = statement.cond.And(vv) - } - } - default: - statement.lastError = ErrConditionType - } - - return statement -} - -// Or add Where & Or statement -func (statement *Statement) Or(query interface{}, args ...interface{}) *Statement { - switch query.(type) { - case string: - cond := builder.Expr(query.(string), args...) - statement.cond = statement.cond.Or(cond) - case map[string]interface{}: - cond := builder.Eq(query.(map[string]interface{})) - statement.cond = statement.cond.Or(cond) - case builder.Cond: - cond := query.(builder.Cond) - statement.cond = statement.cond.Or(cond) - for _, v := range args { - if vv, ok := v.(builder.Cond); ok { - statement.cond = statement.cond.Or(vv) - } - } - default: - // TODO: not support condition type - } - return statement -} - -// In generate "Where column IN (?) " statement -func (statement *Statement) In(column string, args ...interface{}) *Statement { - in := builder.In(statement.Engine.Quote(column), args...) - statement.cond = statement.cond.And(in) - return statement -} - -// NotIn generate "Where column NOT IN (?) " statement -func (statement *Statement) NotIn(column string, args ...interface{}) *Statement { - notIn := builder.NotIn(statement.Engine.Quote(column), args...) - statement.cond = statement.cond.And(notIn) - return statement -} - -func (statement *Statement) setRefValue(v reflect.Value) error { - var err error - statement.RefTable, err = statement.Engine.autoMapType(reflect.Indirect(v)) - if err != nil { - return err - } - statement.tableName = statement.Engine.TableName(v, true) - return nil -} - -func (statement *Statement) setRefBean(bean interface{}) error { - var err error - statement.RefTable, err = statement.Engine.autoMapType(rValue(bean)) - if err != nil { - return err - } - statement.tableName = statement.Engine.TableName(bean, true) - return nil -} - -// Auto generating update columnes and values according a struct -func (statement *Statement) buildUpdates(bean interface{}, - includeVersion, includeUpdated, includeNil, - includeAutoIncr, update bool) ([]string, []interface{}) { - engine := statement.Engine - table := statement.RefTable - allUseBool := statement.allUseBool - useAllCols := statement.useAllCols - mustColumnMap := statement.mustColumnMap - nullableMap := statement.nullableMap - columnMap := statement.columnMap - omitColumnMap := statement.omitColumnMap - unscoped := statement.unscoped - - var colNames = make([]string, 0) - var args = make([]interface{}, 0) - for _, col := range table.Columns() { - if !includeVersion && col.IsVersion { - continue - } - if col.IsCreated { - continue - } - if !includeUpdated && col.IsUpdated { - continue - } - if !includeAutoIncr && col.IsAutoIncrement { - continue - } - if col.IsDeleted && !unscoped { - continue - } - if omitColumnMap.contain(col.Name) { - continue - } - if len(columnMap) > 0 && !columnMap.contain(col.Name) { - continue - } - - if col.MapType == core.ONLYFROMDB { - continue - } - - if statement.incrColumns.isColExist(col.Name) { - continue - } else if statement.decrColumns.isColExist(col.Name) { - continue - } else if statement.exprColumns.isColExist(col.Name) { - continue - } - - fieldValuePtr, err := col.ValueOf(bean) - if err != nil { - engine.logger.Error(err) - continue - } - - fieldValue := *fieldValuePtr - fieldType := reflect.TypeOf(fieldValue.Interface()) - if fieldType == nil { - continue - } - - requiredField := useAllCols - includeNil := useAllCols - - if b, ok := getFlagForColumn(mustColumnMap, col); ok { - if b { - requiredField = true - } else { - continue - } - } - - // !evalphobia! set fieldValue as nil when column is nullable and zero-value - if b, ok := getFlagForColumn(nullableMap, col); ok { - if b && col.Nullable && isZero(fieldValue.Interface()) { - var nilValue *int - fieldValue = reflect.ValueOf(nilValue) - fieldType = reflect.TypeOf(fieldValue.Interface()) - includeNil = true - } - } - - var val interface{} - - if fieldValue.CanAddr() { - if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { - data, err := structConvert.ToDB() - if err != nil { - engine.logger.Error(err) - } else { - val = data - } - goto APPEND - } - } - - if structConvert, ok := fieldValue.Interface().(core.Conversion); ok { - data, err := structConvert.ToDB() - if err != nil { - engine.logger.Error(err) - } else { - val = data - } - goto APPEND - } - - if fieldType.Kind() == reflect.Ptr { - if fieldValue.IsNil() { - if includeNil { - args = append(args, nil) - colNames = append(colNames, fmt.Sprintf("%v=?", engine.Quote(col.Name))) - } - continue - } else if !fieldValue.IsValid() { - continue - } else { - // dereference ptr type to instance type - fieldValue = fieldValue.Elem() - fieldType = reflect.TypeOf(fieldValue.Interface()) - requiredField = true - } - } - - switch fieldType.Kind() { - case reflect.Bool: - if allUseBool || requiredField { - val = fieldValue.Interface() - } else { - // if a bool in a struct, it will not be as a condition because it default is false, - // please use Where() instead - continue - } - case reflect.String: - if !requiredField && fieldValue.String() == "" { - continue - } - // for MyString, should convert to string or panic - if fieldType.String() != reflect.String.String() { - val = fieldValue.String() - } else { - val = fieldValue.Interface() - } - case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64: - if !requiredField && fieldValue.Int() == 0 { - continue - } - val = fieldValue.Interface() - case reflect.Float32, reflect.Float64: - if !requiredField && fieldValue.Float() == 0.0 { - continue - } - val = fieldValue.Interface() - case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64: - if !requiredField && fieldValue.Uint() == 0 { - continue - } - t := int64(fieldValue.Uint()) - val = reflect.ValueOf(&t).Interface() - case reflect.Struct: - if fieldType.ConvertibleTo(core.TimeType) { - t := fieldValue.Convert(core.TimeType).Interface().(time.Time) - if !requiredField && (t.IsZero() || !fieldValue.IsValid()) { - continue - } - val = engine.formatColTime(col, t) - } else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok { - val, _ = nulType.Value() - } else { - if !col.SQLType.IsJson() { - engine.autoMapType(fieldValue) - if table, ok := engine.Tables[fieldValue.Type()]; ok { - if len(table.PrimaryKeys) == 1 { - pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName) - // fix non-int pk issues - if pkField.IsValid() && (!requiredField && !isZero(pkField.Interface())) { - val = pkField.Interface() - } else { - continue - } - } else { - // TODO: how to handler? - panic("not supported") - } - } else { - val = fieldValue.Interface() - } - } else { - // Blank struct could not be as update data - if requiredField || !isStructZero(fieldValue) { - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - panic(fmt.Sprintf("mashal %v failed", fieldValue.Interface())) - } - if col.SQLType.IsText() { - val = string(bytes) - } else if col.SQLType.IsBlob() { - val = bytes - } - } else { - continue - } - } - } - case reflect.Array, reflect.Slice, reflect.Map: - if !requiredField { - if fieldValue == reflect.Zero(fieldType) { - continue - } - if fieldType.Kind() == reflect.Array { - if isArrayValueZero(fieldValue) { - continue - } - } else if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 { - continue - } - } - - if col.SQLType.IsText() { - bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - engine.logger.Error(err) - continue - } - val = string(bytes) - } else if col.SQLType.IsBlob() { - var bytes []byte - var err error - if fieldType.Kind() == reflect.Slice && - fieldType.Elem().Kind() == reflect.Uint8 { - if fieldValue.Len() > 0 { - val = fieldValue.Bytes() - } else { - continue - } - } else if fieldType.Kind() == reflect.Array && - fieldType.Elem().Kind() == reflect.Uint8 { - val = fieldValue.Slice(0, 0).Interface() - } else { - bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) - if err != nil { - engine.logger.Error(err) - continue - } - val = bytes - } - } else { - continue - } - default: - val = fieldValue.Interface() - } - - APPEND: - args = append(args, val) - if col.IsPrimaryKey && engine.dialect.DBType() == "ql" { - continue - } - colNames = append(colNames, fmt.Sprintf("%v = ?", engine.Quote(col.Name))) - } - - return colNames, args -} - -func (statement *Statement) needTableName() bool { - return len(statement.JoinStr) > 0 -} - -func (statement *Statement) colName(col *core.Column, tableName string) string { - if statement.needTableName() { - var nm = tableName - if len(statement.TableAlias) > 0 { - nm = statement.TableAlias - } - return statement.Engine.Quote(nm) + "." + statement.Engine.Quote(col.Name) - } - return statement.Engine.Quote(col.Name) -} - -// TableName return current tableName -func (statement *Statement) TableName() string { - if statement.AltTableName != "" { - return statement.AltTableName - } - - return statement.tableName -} - -// ID generate "where id = ? " statement or for composite key "where key1 = ? and key2 = ?" -func (statement *Statement) ID(id interface{}) *Statement { - idValue := reflect.ValueOf(id) - idType := reflect.TypeOf(idValue.Interface()) - - switch idType { - case ptrPkType: - if pkPtr, ok := (id).(*core.PK); ok { - statement.idParam = pkPtr - return statement - } - case pkType: - if pk, ok := (id).(core.PK); ok { - statement.idParam = &pk - return statement - } - } - - switch idType.Kind() { - case reflect.String: - statement.idParam = &core.PK{idValue.Convert(reflect.TypeOf("")).Interface()} - return statement - } - - statement.idParam = &core.PK{id} - return statement -} - -// Incr Generate "Update ... Set column = column + arg" statement -func (statement *Statement) Incr(column string, arg ...interface{}) *Statement { - if len(arg) > 0 { - statement.incrColumns.addParam(column, arg[0]) - } else { - statement.incrColumns.addParam(column, 1) - } - return statement -} - -// Decr Generate "Update ... Set column = column - arg" statement -func (statement *Statement) Decr(column string, arg ...interface{}) *Statement { - if len(arg) > 0 { - statement.decrColumns.addParam(column, arg[0]) - } else { - statement.decrColumns.addParam(column, 1) - } - return statement -} - -// SetExpr Generate "Update ... Set column = {expression}" statement -func (statement *Statement) SetExpr(column string, expression interface{}) *Statement { - statement.exprColumns.addParam(column, expression) - return statement -} - -func (statement *Statement) col2NewColsWithQuote(columns ...string) []string { - newColumns := make([]string, 0) - quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`") - for _, col := range columns { - newColumns = append(newColumns, statement.Engine.Quote(eraseAny(col, quotes...))) - } - return newColumns -} - -func (statement *Statement) colmap2NewColsWithQuote() []string { - newColumns := make([]string, len(statement.columnMap), len(statement.columnMap)) - copy(newColumns, statement.columnMap) - for i := 0; i < len(statement.columnMap); i++ { - newColumns[i] = statement.Engine.Quote(newColumns[i]) - } - return newColumns -} - -// Distinct generates "DISTINCT col1, col2 " statement -func (statement *Statement) Distinct(columns ...string) *Statement { - statement.IsDistinct = true - statement.Cols(columns...) - return statement -} - -// ForUpdate generates "SELECT ... FOR UPDATE" statement -func (statement *Statement) ForUpdate() *Statement { - statement.IsForUpdate = true - return statement -} - -// Select replace select -func (statement *Statement) Select(str string) *Statement { - statement.selectStr = str - return statement -} - -// Cols generate "col1, col2" statement -func (statement *Statement) Cols(columns ...string) *Statement { - cols := col2NewCols(columns...) - for _, nc := range cols { - statement.columnMap.add(nc) - } - - newColumns := statement.colmap2NewColsWithQuote() - - statement.ColumnStr = strings.Join(newColumns, ", ") - statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.quote("*"), "*", -1) - return statement -} - -// AllCols update use only: update all columns -func (statement *Statement) AllCols() *Statement { - statement.useAllCols = true - return statement -} - -// MustCols update use only: must update columns -func (statement *Statement) MustCols(columns ...string) *Statement { - newColumns := col2NewCols(columns...) - for _, nc := range newColumns { - statement.mustColumnMap[strings.ToLower(nc)] = true - } - return statement -} - -// UseBool indicates that use bool fields as update contents and query contiditions -func (statement *Statement) UseBool(columns ...string) *Statement { - if len(columns) > 0 { - statement.MustCols(columns...) - } else { - statement.allUseBool = true - } - return statement -} - -// Omit do not use the columns -func (statement *Statement) Omit(columns ...string) { - newColumns := col2NewCols(columns...) - for _, nc := range newColumns { - statement.omitColumnMap = append(statement.omitColumnMap, nc) - } - statement.OmitStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", "))) -} - -// Nullable Update use only: update columns to null when value is nullable and zero-value -func (statement *Statement) Nullable(columns ...string) { - newColumns := col2NewCols(columns...) - for _, nc := range newColumns { - statement.nullableMap[strings.ToLower(nc)] = true - } -} - -// Top generate LIMIT limit statement -func (statement *Statement) Top(limit int) *Statement { - statement.Limit(limit) - return statement -} - -// Limit generate LIMIT start, limit statement -func (statement *Statement) Limit(limit int, start ...int) *Statement { - statement.LimitN = limit - if len(start) > 0 { - statement.Start = start[0] - } - return statement -} - -// OrderBy generate "Order By order" statement -func (statement *Statement) OrderBy(order string) *Statement { - if len(statement.OrderStr) > 0 { - statement.OrderStr += ", " - } - statement.OrderStr += order - return statement -} - -// Desc generate `ORDER BY xx DESC` -func (statement *Statement) Desc(colNames ...string) *Statement { - var buf strings.Builder - if len(statement.OrderStr) > 0 { - fmt.Fprint(&buf, statement.OrderStr, ", ") - } - newColNames := statement.col2NewColsWithQuote(colNames...) - fmt.Fprintf(&buf, "%v DESC", strings.Join(newColNames, " DESC, ")) - statement.OrderStr = buf.String() - return statement -} - -// Asc provide asc order by query condition, the input parameters are columns. -func (statement *Statement) Asc(colNames ...string) *Statement { - var buf strings.Builder - if len(statement.OrderStr) > 0 { - fmt.Fprint(&buf, statement.OrderStr, ", ") - } - newColNames := statement.col2NewColsWithQuote(colNames...) - fmt.Fprintf(&buf, "%v ASC", strings.Join(newColNames, " ASC, ")) - statement.OrderStr = buf.String() - return statement -} - -// Table tempororily set table name, the parameter could be a string or a pointer of struct -func (statement *Statement) Table(tableNameOrBean interface{}) *Statement { - v := rValue(tableNameOrBean) - t := v.Type() - if t.Kind() == reflect.Struct { - var err error - statement.RefTable, err = statement.Engine.autoMapType(v) - if err != nil { - statement.Engine.logger.Error(err) - return statement - } - } - - statement.AltTableName = statement.Engine.TableName(tableNameOrBean, true) - return statement -} - -// Join The joinOP should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN -func (statement *Statement) Join(joinOP string, tablename interface{}, condition string, args ...interface{}) *Statement { - var buf strings.Builder - if len(statement.JoinStr) > 0 { - fmt.Fprintf(&buf, "%v %v JOIN ", statement.JoinStr, joinOP) - } else { - fmt.Fprintf(&buf, "%v JOIN ", joinOP) - } - - switch tp := tablename.(type) { - case builder.Builder: - subSQL, subQueryArgs, err := tp.ToSQL() - if err != nil { - statement.lastError = err - return statement - } - tbs := strings.Split(tp.TableName(), ".") - quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`") - - var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, "")) - fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition) - statement.joinArgs = append(statement.joinArgs, subQueryArgs...) - case *builder.Builder: - subSQL, subQueryArgs, err := tp.ToSQL() - if err != nil { - statement.lastError = err - return statement - } - tbs := strings.Split(tp.TableName(), ".") - quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`") - - var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, "")) - fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition) - statement.joinArgs = append(statement.joinArgs, subQueryArgs...) - default: - tbName := statement.Engine.TableName(tablename, true) - fmt.Fprintf(&buf, "%s ON %v", tbName, condition) - } - - statement.JoinStr = buf.String() - statement.joinArgs = append(statement.joinArgs, args...) - return statement -} - -// GroupBy generate "Group By keys" statement -func (statement *Statement) GroupBy(keys string) *Statement { - statement.GroupByStr = keys - return statement -} - -// Having generate "Having conditions" statement -func (statement *Statement) Having(conditions string) *Statement { - statement.HavingStr = fmt.Sprintf("HAVING %v", conditions) - return statement -} - -// Unscoped always disable struct tag "deleted" -func (statement *Statement) Unscoped() *Statement { - statement.unscoped = true - return statement -} - -func (statement *Statement) genColumnStr() string { - if statement.RefTable == nil { - return "" - } - - var buf strings.Builder - columns := statement.RefTable.Columns() - - for _, col := range columns { - if statement.omitColumnMap.contain(col.Name) { - continue - } - - if len(statement.columnMap) > 0 && !statement.columnMap.contain(col.Name) { - continue - } - - if col.MapType == core.ONLYTODB { - continue - } - - if buf.Len() != 0 { - buf.WriteString(", ") - } - - if statement.JoinStr != "" { - if statement.TableAlias != "" { - buf.WriteString(statement.TableAlias) - } else { - buf.WriteString(statement.TableName()) - } - - buf.WriteString(".") - } - - statement.Engine.QuoteTo(&buf, col.Name) - } - - return buf.String() -} - -func (statement *Statement) genCreateTableSQL() string { - return statement.Engine.dialect.CreateTableSql(statement.RefTable, statement.TableName(), - statement.StoreEngine, statement.Charset) -} - -func (statement *Statement) genIndexSQL() []string { - var sqls []string - tbName := statement.TableName() - for _, index := range statement.RefTable.Indexes { - if index.Type == core.IndexType { - sql := statement.Engine.dialect.CreateIndexSql(tbName, index) - /*idxTBName := strings.Replace(tbName, ".", "_", -1) - idxTBName = strings.Replace(idxTBName, `"`, "", -1) - sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(idxTBName, idxName)), - quote(tbName), quote(strings.Join(index.Cols, quote(","))))*/ - sqls = append(sqls, sql) - } - } - return sqls -} - -func uniqueName(tableName, uqeName string) string { - return fmt.Sprintf("UQE_%v_%v", tableName, uqeName) -} - -func (statement *Statement) genUniqueSQL() []string { - var sqls []string - tbName := statement.TableName() - for _, index := range statement.RefTable.Indexes { - if index.Type == core.UniqueType { - sql := statement.Engine.dialect.CreateIndexSql(tbName, index) - sqls = append(sqls, sql) - } - } - return sqls -} - -func (statement *Statement) genDelIndexSQL() []string { - var sqls []string - tbName := statement.TableName() - idxPrefixName := strings.Replace(tbName, `"`, "", -1) - idxPrefixName = strings.Replace(idxPrefixName, `.`, "_", -1) - for idxName, index := range statement.RefTable.Indexes { - var rIdxName string - if index.Type == core.UniqueType { - rIdxName = uniqueName(idxPrefixName, idxName) - } else if index.Type == core.IndexType { - rIdxName = indexName(idxPrefixName, idxName) - } - sql := fmt.Sprintf("DROP INDEX %v", statement.Engine.Quote(statement.Engine.TableName(rIdxName, true))) - if statement.Engine.dialect.IndexOnTable() { - sql += fmt.Sprintf(" ON %v", statement.Engine.Quote(tbName)) - } - sqls = append(sqls, sql) - } - return sqls -} - -func (statement *Statement) genAddColumnStr(col *core.Column) (string, []interface{}) { - quote := statement.Engine.Quote - sql := fmt.Sprintf("ALTER TABLE %v ADD %v", quote(statement.TableName()), - col.String(statement.Engine.dialect)) - if statement.Engine.dialect.DBType() == core.MYSQL && len(col.Comment) > 0 { - sql += " COMMENT '" + col.Comment + "'" - } - sql += ";" - return sql, []interface{}{} -} - -func (statement *Statement) buildConds(table *core.Table, bean interface{}, includeVersion bool, includeUpdated bool, includeNil bool, includeAutoIncr bool, addedTableName bool) (builder.Cond, error) { - return statement.Engine.buildConds(table, bean, includeVersion, includeUpdated, includeNil, includeAutoIncr, statement.allUseBool, statement.useAllCols, - statement.unscoped, statement.mustColumnMap, statement.TableName(), statement.TableAlias, addedTableName) -} - -func (statement *Statement) mergeConds(bean interface{}) error { - if !statement.noAutoCondition { - var addedTableName = (len(statement.JoinStr) > 0) - autoCond, err := statement.buildConds(statement.RefTable, bean, true, true, false, true, addedTableName) - if err != nil { - return err - } - statement.cond = statement.cond.And(autoCond) - } - - if err := statement.processIDParam(); err != nil { - return err - } - return nil -} - -func (statement *Statement) genConds(bean interface{}) (string, []interface{}, error) { - if err := statement.mergeConds(bean); err != nil { - return "", nil, err - } - - return builder.ToSQL(statement.cond) -} - -func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{}, error) { - v := rValue(bean) - isStruct := v.Kind() == reflect.Struct - if isStruct { - statement.setRefBean(bean) - } - - var columnStr = statement.ColumnStr - if len(statement.selectStr) > 0 { - columnStr = statement.selectStr - } else { - // TODO: always generate column names, not use * even if join - if len(statement.JoinStr) == 0 { - if len(columnStr) == 0 { - if len(statement.GroupByStr) > 0 { - columnStr = statement.Engine.quoteColumns(statement.GroupByStr) - } else { - columnStr = statement.genColumnStr() - } - } - } else { - if len(columnStr) == 0 { - if len(statement.GroupByStr) > 0 { - columnStr = statement.Engine.quoteColumns(statement.GroupByStr) - } - } - } - } - - if len(columnStr) == 0 { - columnStr = "*" - } - - if isStruct { - if err := statement.mergeConds(bean); err != nil { - return "", nil, err - } - } else { - if err := statement.processIDParam(); err != nil { - return "", nil, err - } - } - condSQL, condArgs, err := builder.ToSQL(statement.cond) - if err != nil { - return "", nil, err - } - - sqlStr, err := statement.genSelectSQL(columnStr, condSQL, true, true) - if err != nil { - return "", nil, err - } - - return sqlStr, append(statement.joinArgs, condArgs...), nil -} - -func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interface{}, error) { - var condSQL string - var condArgs []interface{} - var err error - if len(beans) > 0 { - statement.setRefBean(beans[0]) - condSQL, condArgs, err = statement.genConds(beans[0]) - } else { - condSQL, condArgs, err = builder.ToSQL(statement.cond) - } - if err != nil { - return "", nil, err - } - - var selectSQL = statement.selectStr - if len(selectSQL) <= 0 { - if statement.IsDistinct { - selectSQL = fmt.Sprintf("count(DISTINCT %s)", statement.ColumnStr) - } else { - selectSQL = "count(*)" - } - } - sqlStr, err := statement.genSelectSQL(selectSQL, condSQL, false, false) - if err != nil { - return "", nil, err - } - - return sqlStr, append(statement.joinArgs, condArgs...), nil -} - -func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (string, []interface{}, error) { - statement.setRefBean(bean) - - var sumStrs = make([]string, 0, len(columns)) - for _, colName := range columns { - if !strings.Contains(colName, " ") && !strings.Contains(colName, "(") { - colName = statement.Engine.Quote(colName) - } - sumStrs = append(sumStrs, fmt.Sprintf("COALESCE(sum(%s),0)", colName)) - } - sumSelect := strings.Join(sumStrs, ", ") - - condSQL, condArgs, err := statement.genConds(bean) - if err != nil { - return "", nil, err - } - - sqlStr, err := statement.genSelectSQL(sumSelect, condSQL, true, true) - if err != nil { - return "", nil, err - } - - return sqlStr, append(statement.joinArgs, condArgs...), nil -} - -func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit, needOrderBy bool) (string, error) { - var ( - distinct string - dialect = statement.Engine.Dialect() - quote = statement.Engine.Quote - fromStr = " FROM " - top, mssqlCondi, whereStr string - ) - if statement.IsDistinct && !strings.HasPrefix(columnStr, "count") { - distinct = "DISTINCT " - } - if len(condSQL) > 0 { - whereStr = " WHERE " + condSQL - } - - if dialect.DBType() == core.MSSQL && strings.Contains(statement.TableName(), "..") { - fromStr += statement.TableName() - } else { - fromStr += quote(statement.TableName()) - } - - if statement.TableAlias != "" { - if dialect.DBType() == core.ORACLE { - fromStr += " " + quote(statement.TableAlias) - } else { - fromStr += " AS " + quote(statement.TableAlias) - } - } - if statement.JoinStr != "" { - fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr) - } - - if dialect.DBType() == core.MSSQL { - if statement.LimitN > 0 { - top = fmt.Sprintf("TOP %d ", statement.LimitN) - } - if statement.Start > 0 { - var column string - if len(statement.RefTable.PKColumns()) == 0 { - for _, index := range statement.RefTable.Indexes { - if len(index.Cols) == 1 { - column = index.Cols[0] - break - } - } - if len(column) == 0 { - column = statement.RefTable.ColumnsSeq()[0] - } - } else { - column = statement.RefTable.PKColumns()[0].Name - } - if statement.needTableName() { - if len(statement.TableAlias) > 0 { - column = statement.TableAlias + "." + column - } else { - column = statement.TableName() + "." + column - } - } - - var orderStr string - if needOrderBy && len(statement.OrderStr) > 0 { - orderStr = " ORDER BY " + statement.OrderStr - } - - var groupStr string - if len(statement.GroupByStr) > 0 { - groupStr = " GROUP BY " + statement.GroupByStr - } - mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s%s%s))", - column, statement.Start, column, fromStr, whereStr, orderStr, groupStr) - } - } - - var buf strings.Builder - fmt.Fprintf(&buf, "SELECT %v%v%v%v%v", distinct, top, columnStr, fromStr, whereStr) - if len(mssqlCondi) > 0 { - if len(whereStr) > 0 { - fmt.Fprint(&buf, " AND ", mssqlCondi) - } else { - fmt.Fprint(&buf, " WHERE ", mssqlCondi) - } - } - - if statement.GroupByStr != "" { - fmt.Fprint(&buf, " GROUP BY ", statement.GroupByStr) - } - if statement.HavingStr != "" { - fmt.Fprint(&buf, " ", statement.HavingStr) - } - if needOrderBy && statement.OrderStr != "" { - fmt.Fprint(&buf, " ORDER BY ", statement.OrderStr) - } - if needLimit { - if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE { - if statement.Start > 0 { - fmt.Fprintf(&buf, " LIMIT %v OFFSET %v", statement.LimitN, statement.Start) - } else if statement.LimitN > 0 { - fmt.Fprint(&buf, " LIMIT ", statement.LimitN) - } - } else if dialect.DBType() == core.ORACLE { - if statement.Start != 0 || statement.LimitN != 0 { - oldString := buf.String() - buf.Reset() - rawColStr := columnStr - if rawColStr == "*" { - rawColStr = "at.*" - } - fmt.Fprintf(&buf, "SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", - columnStr, rawColStr, oldString, statement.Start+statement.LimitN, statement.Start) - } - } - } - if statement.IsForUpdate { - return dialect.ForUpdateSql(buf.String()), nil - } - - return buf.String(), nil -} - -func (statement *Statement) processIDParam() error { - if statement.idParam == nil || statement.RefTable == nil { - return nil - } - - if len(statement.RefTable.PrimaryKeys) != len(*statement.idParam) { - return fmt.Errorf("ID condition is error, expect %d primarykeys, there are %d", - len(statement.RefTable.PrimaryKeys), - len(*statement.idParam), - ) - } - - for i, col := range statement.RefTable.PKColumns() { - var colName = statement.colName(col, statement.TableName()) - statement.cond = statement.cond.And(builder.Eq{colName: (*(statement.idParam))[i]}) - } - return nil -} - -func (statement *Statement) joinColumns(cols []*core.Column, includeTableName bool) string { - var colnames = make([]string, len(cols)) - for i, col := range cols { - if includeTableName { - colnames[i] = statement.Engine.Quote(statement.TableName()) + - "." + statement.Engine.Quote(col.Name) - } else { - colnames[i] = statement.Engine.Quote(col.Name) - } - } - return strings.Join(colnames, ", ") -} - -func (statement *Statement) convertIDSQL(sqlStr string) string { - if statement.RefTable != nil { - cols := statement.RefTable.PKColumns() - if len(cols) == 0 { - return "" - } - - colstrs := statement.joinColumns(cols, false) - sqls := splitNNoCase(sqlStr, " from ", 2) - if len(sqls) != 2 { - return "" - } - - var top string - if statement.LimitN > 0 && statement.Engine.dialect.DBType() == core.MSSQL { - top = fmt.Sprintf("TOP %d ", statement.LimitN) - } - - newsql := fmt.Sprintf("SELECT %s%s FROM %v", top, colstrs, sqls[1]) - return newsql - } - return "" -} - -func (statement *Statement) convertUpdateSQL(sqlStr string) (string, string) { - if statement.RefTable == nil || len(statement.RefTable.PrimaryKeys) != 1 { - return "", "" - } - - colstrs := statement.joinColumns(statement.RefTable.PKColumns(), true) - sqls := splitNNoCase(sqlStr, "where", 2) - if len(sqls) != 2 { - if len(sqls) == 1 { - return sqls[0], fmt.Sprintf("SELECT %v FROM %v", - colstrs, statement.Engine.Quote(statement.TableName())) - } - return "", "" - } - - var whereStr = sqls[1] - - // TODO: for postgres only, if any other database? - var paraStr string - if statement.Engine.dialect.DBType() == core.POSTGRES { - paraStr = "$" - } else if statement.Engine.dialect.DBType() == core.MSSQL { - paraStr = ":" - } - - if paraStr != "" { - if strings.Contains(sqls[1], paraStr) { - dollers := strings.Split(sqls[1], paraStr) - whereStr = dollers[0] - for i, c := range dollers[1:] { - ccs := strings.SplitN(c, " ", 2) - whereStr += fmt.Sprintf(paraStr+"%v %v", i+1, ccs[1]) - } - } - } - - return sqls[0], fmt.Sprintf("SELECT %v FROM %v WHERE %v", - colstrs, statement.Engine.Quote(statement.TableName()), - whereStr) -} diff --git a/vendor/github.com/go-xorm/xorm/statement_args.go b/vendor/github.com/go-xorm/xorm/statement_args.go deleted file mode 100644 index 310f24d6b9..0000000000 --- a/vendor/github.com/go-xorm/xorm/statement_args.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2019 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "fmt" - "reflect" - "strings" - "time" - - "xorm.io/builder" - "xorm.io/core" -) - -func quoteNeeded(a interface{}) bool { - switch a.(type) { - case int, int8, int16, int32, int64: - return false - case uint, uint8, uint16, uint32, uint64: - return false - case float32, float64: - return false - case bool: - return false - case string: - return true - case time.Time, *time.Time: - return true - case builder.Builder, *builder.Builder: - return false - } - - t := reflect.TypeOf(a) - switch t.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return false - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return false - case reflect.Float32, reflect.Float64: - return false - case reflect.Bool: - return false - case reflect.String: - return true - } - - return true -} - -func convertStringSingleQuote(arg string) string { - return "'" + strings.Replace(arg, "'", "''", -1) + "'" -} - -func convertString(arg string) string { - var buf strings.Builder - buf.WriteRune('\'') - for _, c := range arg { - if c == '\\' || c == '\'' { - buf.WriteRune('\\') - } - buf.WriteRune(c) - } - buf.WriteRune('\'') - return buf.String() -} - -func convertArg(arg interface{}, convertFunc func(string) string) string { - if quoteNeeded(arg) { - argv := fmt.Sprintf("%v", arg) - return convertFunc(argv) - } - - return fmt.Sprintf("%v", arg) -} - -const insertSelectPlaceHolder = true - -func (statement *Statement) writeArg(w *builder.BytesWriter, arg interface{}) error { - switch argv := arg.(type) { - case bool: - if statement.Engine.dialect.DBType() == core.MSSQL { - if argv { - if _, err := w.WriteString("1"); err != nil { - return err - } - } else { - if _, err := w.WriteString("0"); err != nil { - return err - } - } - } else { - if argv { - if _, err := w.WriteString("true"); err != nil { - return err - } - } else { - if _, err := w.WriteString("false"); err != nil { - return err - } - } - } - case *builder.Builder: - if _, err := w.WriteString("("); err != nil { - return err - } - if err := argv.WriteTo(w); err != nil { - return err - } - if _, err := w.WriteString(")"); err != nil { - return err - } - default: - if insertSelectPlaceHolder { - if err := w.WriteByte('?'); err != nil { - return err - } - w.Append(arg) - } else { - var convertFunc = convertStringSingleQuote - if statement.Engine.dialect.DBType() == core.MYSQL { - convertFunc = convertString - } - if _, err := w.WriteString(convertArg(arg, convertFunc)); err != nil { - return err - } - } - } - return nil -} - -func (statement *Statement) writeArgs(w *builder.BytesWriter, args []interface{}) error { - for i, arg := range args { - if err := statement.writeArg(w, arg); err != nil { - return err - } - - if i+1 != len(args) { - if _, err := w.WriteString(","); err != nil { - return err - } - } - } - return nil -} - -func writeStrings(w *builder.BytesWriter, cols []string, leftQuote, rightQuote string) error { - for i, colName := range cols { - if len(leftQuote) > 0 && colName[0] != '`' { - if _, err := w.WriteString(leftQuote); err != nil { - return err - } - } - if _, err := w.WriteString(colName); err != nil { - return err - } - if len(rightQuote) > 0 && colName[len(colName)-1] != '`' { - if _, err := w.WriteString(rightQuote); err != nil { - return err - } - } - if i+1 != len(cols) { - if _, err := w.WriteString(","); err != nil { - return err - } - } - } - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/statement_columnmap.go b/vendor/github.com/go-xorm/xorm/statement_columnmap.go deleted file mode 100644 index b6523b1e7a..0000000000 --- a/vendor/github.com/go-xorm/xorm/statement_columnmap.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import "strings" - -type columnMap []string - -func (m columnMap) contain(colName string) bool { - if len(m) == 0 { - return false - } - - n := len(colName) - for _, mk := range m { - if len(mk) != n { - continue - } - if strings.EqualFold(mk, colName) { - return true - } - } - - return false -} - -func (m *columnMap) add(colName string) bool { - if m.contain(colName) { - return false - } - *m = append(*m, colName) - return true -} diff --git a/vendor/github.com/go-xorm/xorm/statement_exprparam.go b/vendor/github.com/go-xorm/xorm/statement_exprparam.go deleted file mode 100644 index 4da4f1ea12..0000000000 --- a/vendor/github.com/go-xorm/xorm/statement_exprparam.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2019 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "fmt" - "strings" - - "xorm.io/builder" -) - -type ErrUnsupportedExprType struct { - tp string -} - -func (err ErrUnsupportedExprType) Error() string { - return fmt.Sprintf("Unsupported expression type: %v", err.tp) -} - -type exprParam struct { - colName string - arg interface{} -} - -type exprParams struct { - colNames []string - args []interface{} -} - -func (exprs *exprParams) Len() int { - return len(exprs.colNames) -} - -func (exprs *exprParams) addParam(colName string, arg interface{}) { - exprs.colNames = append(exprs.colNames, colName) - exprs.args = append(exprs.args, arg) -} - -func (exprs *exprParams) isColExist(colName string) bool { - for _, name := range exprs.colNames { - if strings.EqualFold(trimQuote(name), trimQuote(colName)) { - return true - } - } - return false -} - -func (exprs *exprParams) getByName(colName string) (exprParam, bool) { - for i, name := range exprs.colNames { - if strings.EqualFold(name, colName) { - return exprParam{name, exprs.args[i]}, true - } - } - return exprParam{}, false -} - -func (exprs *exprParams) writeArgs(w *builder.BytesWriter) error { - for i, expr := range exprs.args { - switch arg := expr.(type) { - case *builder.Builder: - if _, err := w.WriteString("("); err != nil { - return err - } - if err := arg.WriteTo(w); err != nil { - return err - } - if _, err := w.WriteString(")"); err != nil { - return err - } - default: - if _, err := w.WriteString(fmt.Sprintf("%v", arg)); err != nil { - return err - } - } - if i != len(exprs.args)-1 { - if _, err := w.WriteString(","); err != nil { - return err - } - } - } - return nil -} - -func (exprs *exprParams) writeNameArgs(w *builder.BytesWriter) error { - for i, colName := range exprs.colNames { - if _, err := w.WriteString(colName); err != nil { - return err - } - if _, err := w.WriteString("="); err != nil { - return err - } - - switch arg := exprs.args[i].(type) { - case *builder.Builder: - if _, err := w.WriteString("("); err != nil { - return err - } - if err := arg.WriteTo(w); err != nil { - return err - } - if _, err := w.WriteString("("); err != nil { - return err - } - default: - w.Append(exprs.args[i]) - } - - if i+1 != len(exprs.colNames) { - if _, err := w.WriteString(","); err != nil { - return err - } - } - } - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/statement_quote.go b/vendor/github.com/go-xorm/xorm/statement_quote.go deleted file mode 100644 index e22e0d1471..0000000000 --- a/vendor/github.com/go-xorm/xorm/statement_quote.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2019 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -func trimQuote(s string) string { - if len(s) == 0 { - return s - } - - if s[0] == '`' { - s = s[1:] - } - if len(s) > 0 && s[len(s)-1] == '`' { - return s[:len(s)-1] - } - return s -} diff --git a/vendor/github.com/go-xorm/xorm/syslogger.go b/vendor/github.com/go-xorm/xorm/syslogger.go deleted file mode 100644 index 11ba01e7bd..0000000000 --- a/vendor/github.com/go-xorm/xorm/syslogger.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !windows,!nacl,!plan9 - -package xorm - -import ( - "fmt" - "log/syslog" - - "xorm.io/core" -) - -var _ core.ILogger = &SyslogLogger{} - -// SyslogLogger will be depricated -type SyslogLogger struct { - w *syslog.Writer - showSQL bool -} - -// NewSyslogLogger implements core.ILogger -func NewSyslogLogger(w *syslog.Writer) *SyslogLogger { - return &SyslogLogger{w: w} -} - -// Debug log content as Debug -func (s *SyslogLogger) Debug(v ...interface{}) { - s.w.Debug(fmt.Sprint(v...)) -} - -// Debugf log content as Debug and format -func (s *SyslogLogger) Debugf(format string, v ...interface{}) { - s.w.Debug(fmt.Sprintf(format, v...)) -} - -// Error log content as Error -func (s *SyslogLogger) Error(v ...interface{}) { - s.w.Err(fmt.Sprint(v...)) -} - -// Errorf log content as Errorf and format -func (s *SyslogLogger) Errorf(format string, v ...interface{}) { - s.w.Err(fmt.Sprintf(format, v...)) -} - -// Info log content as Info -func (s *SyslogLogger) Info(v ...interface{}) { - s.w.Info(fmt.Sprint(v...)) -} - -// Infof log content as Infof and format -func (s *SyslogLogger) Infof(format string, v ...interface{}) { - s.w.Info(fmt.Sprintf(format, v...)) -} - -// Warn log content as Warn -func (s *SyslogLogger) Warn(v ...interface{}) { - s.w.Warning(fmt.Sprint(v...)) -} - -// Warnf log content as Warnf and format -func (s *SyslogLogger) Warnf(format string, v ...interface{}) { - s.w.Warning(fmt.Sprintf(format, v...)) -} - -// Level shows log level -func (s *SyslogLogger) Level() core.LogLevel { - return core.LOG_UNKNOWN -} - -// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created -func (s *SyslogLogger) SetLevel(l core.LogLevel) {} - -// ShowSQL set if logging SQL -func (s *SyslogLogger) ShowSQL(show ...bool) { - if len(show) == 0 { - s.showSQL = true - return - } - s.showSQL = show[0] -} - -// IsShowSQL if logging SQL -func (s *SyslogLogger) IsShowSQL() bool { - return s.showSQL -} diff --git a/vendor/github.com/go-xorm/xorm/tag.go b/vendor/github.com/go-xorm/xorm/tag.go deleted file mode 100644 index ec8d5cf05b..0000000000 --- a/vendor/github.com/go-xorm/xorm/tag.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "time" - - "xorm.io/core" -) - -type tagContext struct { - tagName string - params []string - preTag, nextTag string - table *core.Table - col *core.Column - fieldValue reflect.Value - isIndex bool - isUnique bool - indexNames map[string]int - engine *Engine - hasCacheTag bool - hasNoCacheTag bool - ignoreNext bool -} - -// tagHandler describes tag handler for XORM -type tagHandler func(ctx *tagContext) error - -var ( - // defaultTagHandlers enumerates all the default tag handler - defaultTagHandlers = map[string]tagHandler{ - "<-": OnlyFromDBTagHandler, - "->": OnlyToDBTagHandler, - "PK": PKTagHandler, - "NULL": NULLTagHandler, - "NOT": IgnoreTagHandler, - "AUTOINCR": AutoIncrTagHandler, - "DEFAULT": DefaultTagHandler, - "CREATED": CreatedTagHandler, - "UPDATED": UpdatedTagHandler, - "DELETED": DeletedTagHandler, - "VERSION": VersionTagHandler, - "UTC": UTCTagHandler, - "LOCAL": LocalTagHandler, - "NOTNULL": NotNullTagHandler, - "INDEX": IndexTagHandler, - "UNIQUE": UniqueTagHandler, - "CACHE": CacheTagHandler, - "NOCACHE": NoCacheTagHandler, - "COMMENT": CommentTagHandler, - } -) - -func init() { - for k := range core.SqlTypes { - defaultTagHandlers[k] = SQLTypeTagHandler - } -} - -// IgnoreTagHandler describes ignored tag handler -func IgnoreTagHandler(ctx *tagContext) error { - return nil -} - -// OnlyFromDBTagHandler describes mapping direction tag handler -func OnlyFromDBTagHandler(ctx *tagContext) error { - ctx.col.MapType = core.ONLYFROMDB - return nil -} - -// OnlyToDBTagHandler describes mapping direction tag handler -func OnlyToDBTagHandler(ctx *tagContext) error { - ctx.col.MapType = core.ONLYTODB - return nil -} - -// PKTagHandler decribes primary key tag handler -func PKTagHandler(ctx *tagContext) error { - ctx.col.IsPrimaryKey = true - ctx.col.Nullable = false - return nil -} - -// NULLTagHandler describes null tag handler -func NULLTagHandler(ctx *tagContext) error { - ctx.col.Nullable = (strings.ToUpper(ctx.preTag) != "NOT") - return nil -} - -// NotNullTagHandler describes notnull tag handler -func NotNullTagHandler(ctx *tagContext) error { - ctx.col.Nullable = false - return nil -} - -// AutoIncrTagHandler describes autoincr tag handler -func AutoIncrTagHandler(ctx *tagContext) error { - ctx.col.IsAutoIncrement = true - /* - if len(ctx.params) > 0 { - autoStartInt, err := strconv.Atoi(ctx.params[0]) - if err != nil { - return err - } - ctx.col.AutoIncrStart = autoStartInt - } else { - ctx.col.AutoIncrStart = 1 - } - */ - return nil -} - -// DefaultTagHandler describes default tag handler -func DefaultTagHandler(ctx *tagContext) error { - if len(ctx.params) > 0 { - ctx.col.Default = ctx.params[0] - } else { - ctx.col.Default = ctx.nextTag - ctx.ignoreNext = true - } - ctx.col.DefaultIsEmpty = false - return nil -} - -// CreatedTagHandler describes created tag handler -func CreatedTagHandler(ctx *tagContext) error { - ctx.col.IsCreated = true - return nil -} - -// VersionTagHandler describes version tag handler -func VersionTagHandler(ctx *tagContext) error { - ctx.col.IsVersion = true - ctx.col.Default = "1" - return nil -} - -// UTCTagHandler describes utc tag handler -func UTCTagHandler(ctx *tagContext) error { - ctx.col.TimeZone = time.UTC - return nil -} - -// LocalTagHandler describes local tag handler -func LocalTagHandler(ctx *tagContext) error { - if len(ctx.params) == 0 { - ctx.col.TimeZone = time.Local - } else { - var err error - ctx.col.TimeZone, err = time.LoadLocation(ctx.params[0]) - if err != nil { - return err - } - } - return nil -} - -// UpdatedTagHandler describes updated tag handler -func UpdatedTagHandler(ctx *tagContext) error { - ctx.col.IsUpdated = true - return nil -} - -// DeletedTagHandler describes deleted tag handler -func DeletedTagHandler(ctx *tagContext) error { - ctx.col.IsDeleted = true - return nil -} - -// IndexTagHandler describes index tag handler -func IndexTagHandler(ctx *tagContext) error { - if len(ctx.params) > 0 { - ctx.indexNames[ctx.params[0]] = core.IndexType - } else { - ctx.isIndex = true - } - return nil -} - -// UniqueTagHandler describes unique tag handler -func UniqueTagHandler(ctx *tagContext) error { - if len(ctx.params) > 0 { - ctx.indexNames[ctx.params[0]] = core.UniqueType - } else { - ctx.isUnique = true - } - return nil -} - -// CommentTagHandler add comment to column -func CommentTagHandler(ctx *tagContext) error { - if len(ctx.params) > 0 { - ctx.col.Comment = strings.Trim(ctx.params[0], "' ") - } - return nil -} - -// SQLTypeTagHandler describes SQL Type tag handler -func SQLTypeTagHandler(ctx *tagContext) error { - ctx.col.SQLType = core.SQLType{Name: ctx.tagName} - if len(ctx.params) > 0 { - if ctx.tagName == core.Enum { - ctx.col.EnumOptions = make(map[string]int) - for k, v := range ctx.params { - v = strings.TrimSpace(v) - v = strings.Trim(v, "'") - ctx.col.EnumOptions[v] = k - } - } else if ctx.tagName == core.Set { - ctx.col.SetOptions = make(map[string]int) - for k, v := range ctx.params { - v = strings.TrimSpace(v) - v = strings.Trim(v, "'") - ctx.col.SetOptions[v] = k - } - } else { - var err error - if len(ctx.params) == 2 { - ctx.col.Length, err = strconv.Atoi(ctx.params[0]) - if err != nil { - return err - } - ctx.col.Length2, err = strconv.Atoi(ctx.params[1]) - if err != nil { - return err - } - } else if len(ctx.params) == 1 { - ctx.col.Length, err = strconv.Atoi(ctx.params[0]) - if err != nil { - return err - } - } - } - } - return nil -} - -// ExtendsTagHandler describes extends tag handler -func ExtendsTagHandler(ctx *tagContext) error { - var fieldValue = ctx.fieldValue - var isPtr = false - switch fieldValue.Kind() { - case reflect.Ptr: - f := fieldValue.Type().Elem() - if f.Kind() == reflect.Struct { - fieldPtr := fieldValue - fieldValue = fieldValue.Elem() - if !fieldValue.IsValid() || fieldPtr.IsNil() { - fieldValue = reflect.New(f).Elem() - } - } - isPtr = true - fallthrough - case reflect.Struct: - parentTable, err := ctx.engine.mapType(fieldValue) - if err != nil { - return err - } - for _, col := range parentTable.Columns() { - col.FieldName = fmt.Sprintf("%v.%v", ctx.col.FieldName, col.FieldName) - - var tagPrefix = ctx.col.FieldName - if len(ctx.params) > 0 { - col.Nullable = isPtr - tagPrefix = ctx.params[0] - if col.IsPrimaryKey { - col.Name = ctx.col.FieldName - col.IsPrimaryKey = false - } else { - col.Name = fmt.Sprintf("%v%v", tagPrefix, col.Name) - } - } - - if col.Nullable { - col.IsAutoIncrement = false - col.IsPrimaryKey = false - } - - ctx.table.AddColumn(col) - for indexName, indexType := range col.Indexes { - addIndex(indexName, ctx.table, col, indexType) - } - } - default: - //TODO: warning - } - return nil -} - -// CacheTagHandler describes cache tag handler -func CacheTagHandler(ctx *tagContext) error { - if !ctx.hasCacheTag { - ctx.hasCacheTag = true - } - return nil -} - -// NoCacheTagHandler describes nocache tag handler -func NoCacheTagHandler(ctx *tagContext) error { - if !ctx.hasNoCacheTag { - ctx.hasNoCacheTag = true - } - return nil -} diff --git a/vendor/github.com/go-xorm/xorm/test_mssql.sh b/vendor/github.com/go-xorm/xorm/test_mssql.sh deleted file mode 100644 index 7f060cff32..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_mssql.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=mssql -conn_str="server=localhost;user id=sa;password=yourStrong(!)Password;database=xorm_test" \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_mssql_cache.sh b/vendor/github.com/go-xorm/xorm/test_mssql_cache.sh deleted file mode 100644 index 76efd6ca0a..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_mssql_cache.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=mssql -conn_str="server=192.168.1.58;user id=sa;password=123456;database=xorm_test" -cache=true \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_mymysql.sh b/vendor/github.com/go-xorm/xorm/test_mymysql.sh deleted file mode 100644 index f7780d14fa..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_mymysql.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=mymysql -conn_str="xorm_test/root/" \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_mymysql_cache.sh b/vendor/github.com/go-xorm/xorm/test_mymysql_cache.sh deleted file mode 100644 index 0100286d65..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_mymysql_cache.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=mymysql -conn_str="xorm_test/root/" -cache=true \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_mysql.sh b/vendor/github.com/go-xorm/xorm/test_mysql.sh deleted file mode 100644 index 650e4ee170..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_mysql.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=mysql -conn_str="root:@/xorm_test" \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_mysql_cache.sh b/vendor/github.com/go-xorm/xorm/test_mysql_cache.sh deleted file mode 100644 index c542e73594..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_mysql_cache.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=mysql -conn_str="root:@/xorm_test" -cache=true \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_postgres.sh b/vendor/github.com/go-xorm/xorm/test_postgres.sh deleted file mode 100644 index dc1152e0a6..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_postgres.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable" \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_postgres_cache.sh b/vendor/github.com/go-xorm/xorm/test_postgres_cache.sh deleted file mode 100644 index 462fc948cb..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_postgres_cache.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable" -cache=true \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_sqlite.sh b/vendor/github.com/go-xorm/xorm/test_sqlite.sh deleted file mode 100644 index 6352b5cb5f..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_sqlite.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_sqlite_cache.sh b/vendor/github.com/go-xorm/xorm/test_sqlite_cache.sh deleted file mode 100644 index 75a054c3f1..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_sqlite_cache.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" -cache=true \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/test_tidb.sh b/vendor/github.com/go-xorm/xorm/test_tidb.sh deleted file mode 100644 index 03d2d6cd82..0000000000 --- a/vendor/github.com/go-xorm/xorm/test_tidb.sh +++ /dev/null @@ -1 +0,0 @@ -go test -db=mysql -conn_str="root:@tcp(localhost:4000)/xorm_test" -ignore_select_update=true \ No newline at end of file diff --git a/vendor/github.com/go-xorm/xorm/transaction.go b/vendor/github.com/go-xorm/xorm/transaction.go deleted file mode 100644 index 4104103fd5..0000000000 --- a/vendor/github.com/go-xorm/xorm/transaction.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -// Transaction Execute sql wrapped in a transaction(abbr as tx), tx will automatic commit if no errors occurred -func (engine *Engine) Transaction(f func(*Session) (interface{}, error)) (interface{}, error) { - session := engine.NewSession() - defer session.Close() - - if err := session.Begin(); err != nil { - return nil, err - } - - result, err := f(session) - if err != nil { - return nil, err - } - - if err := session.Commit(); err != nil { - return nil, err - } - - return result, nil -} diff --git a/vendor/github.com/go-xorm/xorm/types.go b/vendor/github.com/go-xorm/xorm/types.go deleted file mode 100644 index c76a546065..0000000000 --- a/vendor/github.com/go-xorm/xorm/types.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package xorm - -import ( - "reflect" - - "xorm.io/core" -) - -var ( - ptrPkType = reflect.TypeOf(&core.PK{}) - pkType = reflect.TypeOf(core.PK{}) -) diff --git a/vendor/github.com/go-xorm/xorm/xorm.go b/vendor/github.com/go-xorm/xorm/xorm.go deleted file mode 100644 index 26d00d264d..0000000000 --- a/vendor/github.com/go-xorm/xorm/xorm.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2015 The Xorm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.8 - -package xorm - -import ( - "context" - "fmt" - "os" - "reflect" - "runtime" - "sync" - "time" - - "xorm.io/core" -) - -const ( - // Version show the xorm's version - Version string = "0.7.0.0504" -) - -func regDrvsNDialects() bool { - providedDrvsNDialects := map[string]struct { - dbType core.DbType - getDriver func() core.Driver - getDialect func() core.Dialect - }{ - "mssql": {"mssql", func() core.Driver { return &odbcDriver{} }, func() core.Dialect { return &mssql{} }}, - "odbc": {"mssql", func() core.Driver { return &odbcDriver{} }, func() core.Dialect { return &mssql{} }}, // !nashtsai! TODO change this when supporting MS Access - "mysql": {"mysql", func() core.Driver { return &mysqlDriver{} }, func() core.Dialect { return &mysql{} }}, - "mymysql": {"mysql", func() core.Driver { return &mymysqlDriver{} }, func() core.Dialect { return &mysql{} }}, - "postgres": {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }}, - "pgx": {"postgres", func() core.Driver { return &pqDriverPgx{} }, func() core.Dialect { return &postgres{} }}, - "sqlite3": {"sqlite3", func() core.Driver { return &sqlite3Driver{} }, func() core.Dialect { return &sqlite3{} }}, - "oci8": {"oracle", func() core.Driver { return &oci8Driver{} }, func() core.Dialect { return &oracle{} }}, - "goracle": {"oracle", func() core.Driver { return &goracleDriver{} }, func() core.Dialect { return &oracle{} }}, - } - - for driverName, v := range providedDrvsNDialects { - if driver := core.QueryDriver(driverName); driver == nil { - core.RegisterDriver(driverName, v.getDriver()) - core.RegisterDialect(v.dbType, v.getDialect) - } - } - return true -} - -func close(engine *Engine) { - engine.Close() -} - -func init() { - regDrvsNDialects() -} - -// NewEngine new a db manager according to the parameter. Currently support four -// drivers -func NewEngine(driverName string, dataSourceName string) (*Engine, error) { - driver := core.QueryDriver(driverName) - if driver == nil { - return nil, fmt.Errorf("Unsupported driver name: %v", driverName) - } - - uri, err := driver.Parse(driverName, dataSourceName) - if err != nil { - return nil, err - } - - dialect := core.QueryDialect(uri.DbType) - if dialect == nil { - return nil, fmt.Errorf("Unsupported dialect type: %v", uri.DbType) - } - - db, err := core.Open(driverName, dataSourceName) - if err != nil { - return nil, err - } - - err = dialect.Init(db, uri, driverName, dataSourceName) - if err != nil { - return nil, err - } - - engine := &Engine{ - db: db, - dialect: dialect, - Tables: make(map[reflect.Type]*core.Table), - mutex: &sync.RWMutex{}, - TagIdentifier: "xorm", - TZLocation: time.Local, - tagHandlers: defaultTagHandlers, - cachers: make(map[string]core.Cacher), - defaultContext: context.Background(), - } - - if uri.DbType == core.SQLITE { - engine.DatabaseTZ = time.UTC - } else { - engine.DatabaseTZ = time.Local - } - - logger := NewSimpleLogger(os.Stdout) - logger.SetLevel(core.LOG_INFO) - engine.SetLogger(logger) - engine.SetMapper(core.NewCacheMapper(new(core.SnakeMapper))) - - runtime.SetFinalizer(engine, close) - - return engine, nil -} - -// NewEngineWithParams new a db manager with params. The params will be passed to dialect. -func NewEngineWithParams(driverName string, dataSourceName string, params map[string]string) (*Engine, error) { - engine, err := NewEngine(driverName, dataSourceName) - engine.dialect.SetParams(params) - return engine, err -} - -// Clone clone an engine -func (engine *Engine) Clone() (*Engine, error) { - return NewEngine(engine.DriverName(), engine.DataSourceName()) -} diff --git a/vendor/github.com/lafriks/xormstore/go.mod b/vendor/github.com/lafriks/xormstore/go.mod index 1a68ce6513..8a7528ee78 100644 --- a/vendor/github.com/lafriks/xormstore/go.mod +++ b/vendor/github.com/lafriks/xormstore/go.mod @@ -5,15 +5,14 @@ go 1.11 require ( github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538 github.com/go-sql-driver/mysql v1.4.1 - github.com/go-xorm/xorm v0.7.9 github.com/gorilla/context v1.1.1 github.com/gorilla/securecookie v1.1.1 github.com/gorilla/sessions v1.2.0 - github.com/kr/pretty v0.1.0 // indirect github.com/lib/pq v1.2.0 github.com/mattn/go-sqlite3 v1.11.0 golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad // indirect google.golang.org/appengine v1.6.4 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect xorm.io/core v0.7.2 + xorm.io/xorm v0.8.0 ) diff --git a/vendor/github.com/lafriks/xormstore/go.sum b/vendor/github.com/lafriks/xormstore/go.sum index d3dc6aee62..9d0273a87c 100644 --- a/vendor/github.com/lafriks/xormstore/go.sum +++ b/vendor/github.com/lafriks/xormstore/go.sum @@ -1,6 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -10,8 +9,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -29,9 +26,6 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= -github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0= -github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= @@ -43,7 +37,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -57,9 +50,6 @@ github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYb github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= -github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -70,11 +60,9 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= @@ -86,8 +74,6 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -98,13 +84,10 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -113,7 +96,6 @@ github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wK go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad h1:5E5raQxcv+6CZ11RrBYQe5WRbUIWpScjh0kvHZkZIrQ= @@ -149,7 +131,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -160,7 +141,6 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.4 h1:WiKh4+/eMB2HaY7QhCfW/R7MuRAoA8QMCSJA6jP5/fo= @@ -172,7 +152,6 @@ google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -186,7 +165,7 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= -xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb h1:msX3zG3BPl8Ti+LDzP33/9K7BzO/WqFXk610K1kYKfo= -xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw= xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= +xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM= +xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY= diff --git a/vendor/github.com/lafriks/xormstore/xormstore.go b/vendor/github.com/lafriks/xormstore/xormstore.go index 85be25225e..e095508243 100644 --- a/vendor/github.com/lafriks/xormstore/xormstore.go +++ b/vendor/github.com/lafriks/xormstore/xormstore.go @@ -44,7 +44,7 @@ import ( "github.com/lafriks/xormstore/util" - "github.com/go-xorm/xorm" + "xorm.io/xorm" "github.com/gorilla/context" "github.com/gorilla/securecookie" "github.com/gorilla/sessions" diff --git a/vendor/modules.txt b/vendor/modules.txt index 91f7fce0d9..e24275236a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -191,8 +191,6 @@ github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd github.com/go-swagger/go-swagger/codescan github.com/go-swagger/go-swagger/generator github.com/go-swagger/go-swagger/scan -# github.com/go-xorm/xorm v0.7.9 -github.com/go-xorm/xorm # github.com/gobwas/glob v0.2.3 github.com/gobwas/glob github.com/gobwas/glob/compiler @@ -274,7 +272,7 @@ github.com/klauspost/crc32 github.com/kr/pretty # github.com/kr/text v0.1.0 github.com/kr/text -# github.com/lafriks/xormstore v1.3.1 +# github.com/lafriks/xormstore v1.3.2 github.com/lafriks/xormstore github.com/lafriks/xormstore/util # github.com/lib/pq v1.2.0 @@ -609,3 +607,5 @@ strk.kbt.io/projects/go/libravatar xorm.io/builder # xorm.io/core v0.7.2 xorm.io/core +# xorm.io/xorm v0.8.0 +xorm.io/xorm diff --git a/vendor/xorm.io/xorm/.drone.yml b/vendor/xorm.io/xorm/.drone.yml new file mode 100644 index 0000000000..c373975df6 --- /dev/null +++ b/vendor/xorm.io/xorm/.drone.yml @@ -0,0 +1,771 @@ +--- +kind: pipeline +name: matrix-1 + +platform: + os: linux + arch: amd64 + +workspace: + base: /go + path: src/gitea.com/xorm/xorm + +steps: +- name: build + pull: default + image: golang:1.10 + commands: + - go get -t -d -v ./... + - go get -u xorm.io/core + - go get -u xorm.io/builder + - go build -v + when: + event: + - push + - pull_request + +- name: test-sqlite + pull: default + image: golang:1.10 + commands: + - go get -u github.com/wadey/gocovmerge + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql + pull: default + image: golang:1.10 + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql-utf8mb4 + pull: default + image: golang:1.10 + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mymysql + pull: default + image: golang:1.10 + commands: + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres + pull: default + image: golang:1.10 + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres-schema + pull: default + image: golang:1.10 + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mssql + pull: default + image: golang:1.10 + commands: + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-tidb + pull: default + image: golang:1.10 + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" + - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt + when: + event: + - push + - pull_request + +services: +- name: mysql + pull: default + image: mysql:5.7 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: xorm_test + when: + event: + - push + - tag + - pull_request + +- name: tidb + pull: default + image: pingcap/tidb:v3.0.3 + when: + event: + - push + - tag + - pull_request + +- name: pgsql + pull: default + image: postgres:9.5 + environment: + POSTGRES_DB: xorm_test + POSTGRES_USER: postgres + when: + event: + - push + - tag + - pull_request + +- name: mssql + pull: default + image: microsoft/mssql-server-linux:latest + environment: + ACCEPT_EULA: Y + SA_PASSWORD: yourStrong(!)Password + MSSQL_PID: Developer + when: + event: + - push + - tag + - pull_request + +--- +kind: pipeline +name: matrix-2 + +platform: + os: linux + arch: amd64 + +workspace: + base: /go + path: src/gitea.com/xorm/xorm + +steps: +- name: build + pull: default + image: golang:1.11 + environment: + GO111MODULE: "off" + commands: + - go get -t -d -v ./... + - go get -u xorm.io/core + - go get -u xorm.io/builder + - go build -v + when: + event: + - push + - pull_request + +- name: build-gomod + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - go build -v + when: + event: + - push + - pull_request + +- name: test-sqlite + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql-utf8mb4 + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mymysql + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres-schema + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mssql + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" + + when: + event: + - push + - pull_request + +- name: test-tidb + pull: default + image: golang:1.11 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" + - go get github.com/wadey/gocovmerge + - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt + when: + event: + - push + - pull_request + +services: +- name: mysql + pull: default + image: mysql:5.7 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: xorm_test + when: + event: + - push + - tag + - pull_request + +- name: tidb + pull: default + image: pingcap/tidb:v3.0.3 + when: + event: + - push + - tag + - pull_request + +- name: pgsql + pull: default + image: postgres:9.5 + environment: + POSTGRES_DB: xorm_test + POSTGRES_USER: postgres + when: + event: + - push + - tag + - pull_request + +- name: mssql + pull: default + image: microsoft/mssql-server-linux:latest + environment: + ACCEPT_EULA: Y + SA_PASSWORD: yourStrong(!)Password + MSSQL_PID: Developer + when: + event: + - push + - tag + - pull_request + +--- +kind: pipeline +name: matrix-3 + +platform: + os: linux + arch: amd64 + +workspace: + base: /go + path: src/gitea.com/xorm/xorm + +steps: + +- name: build + pull: default + image: golang:1.12 + environment: + GO111MODULE: "off" + commands: + - go get -t -d -v ./... + - go get -u xorm.io/core + - go get -u xorm.io/builder + - go build -v + when: + event: + - push + - pull_request + +- name: build-gomod + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - go build -v + when: + event: + - push + - pull_request + +- name: test-sqlite + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql-utf8mb4 + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mymysql + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres-schema + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mssql + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-tidb + pull: default + image: golang:1.12 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" + - go get github.com/wadey/gocovmerge + - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt + when: + event: + - push + - pull_request + +services: +- name: mysql + pull: default + image: mysql:5.7 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: xorm_test + when: + event: + - push + - tag + - pull_request + +- name: tidb + pull: default + image: pingcap/tidb:v3.0.3 + when: + event: + - push + - tag + - pull_request + +- name: pgsql + pull: default + image: postgres:9.5 + environment: + POSTGRES_DB: xorm_test + POSTGRES_USER: postgres + when: + event: + - push + - tag + - pull_request + +- name: mssql + pull: default + image: microsoft/mssql-server-linux:latest + environment: + ACCEPT_EULA: Y + SA_PASSWORD: yourStrong(!)Password + MSSQL_PID: Developer + when: + event: + - push + - tag + - pull_request + +--- +kind: pipeline +name: go1.13 + +platform: + os: linux + arch: amd64 + +workspace: + base: /go + path: src/gitea.com/xorm/xorm + +steps: + +- name: build + pull: default + image: golang:1.13 + environment: + GO111MODULE: "off" + commands: + - go get -t -d -v ./... + - go get -u xorm.io/core + - go get -u xorm.io/builder + - go build -v + when: + event: + - push + - pull_request + +- name: build-gomod + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - go build -v + when: + event: + - push + - pull_request + +- name: test-sqlite + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic" + - "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mysql-utf8mb4 + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mymysql + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic" + - "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-postgres-schema + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic" + - "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-mssql + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" + - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" + when: + event: + - push + - pull_request + +- name: test-tidb + pull: default + image: golang:1.13 + environment: + GO111MODULE: "on" + GOPROXY: "https://goproxy.cn" + commands: + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic" + - "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic" + - go get github.com/wadey/gocovmerge + - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt + when: + event: + - push + - pull_request + +services: +- name: mysql + pull: default + image: mysql:5.7 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: xorm_test + when: + event: + - push + - tag + - pull_request + +- name: tidb + pull: default + image: pingcap/tidb:v3.0.3 + when: + event: + - push + - tag + - pull_request + +- name: pgsql + pull: default + image: postgres:9.5 + environment: + POSTGRES_DB: xorm_test + POSTGRES_USER: postgres + when: + event: + - push + - tag + - pull_request + +- name: mssql + pull: default + image: microsoft/mssql-server-linux:latest + environment: + ACCEPT_EULA: Y + SA_PASSWORD: yourStrong(!)Password + MSSQL_PID: Developer + when: + event: + - push + - tag + - pull_request \ No newline at end of file diff --git a/vendor/xorm.io/xorm/.gitignore b/vendor/xorm.io/xorm/.gitignore new file mode 100644 index 0000000000..f1757b9830 --- /dev/null +++ b/vendor/xorm.io/xorm/.gitignore @@ -0,0 +1,33 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so +*.db + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe + +*.log +.vendor +temp_test.go +.vscode +xorm.test +*.sqlite3 +test.db.sql + +.idea/ diff --git a/vendor/xorm.io/xorm/CONTRIBUTING.md b/vendor/xorm.io/xorm/CONTRIBUTING.md new file mode 100644 index 0000000000..442aa4d311 --- /dev/null +++ b/vendor/xorm.io/xorm/CONTRIBUTING.md @@ -0,0 +1,46 @@ +## Contributing to xorm + +`xorm` has a backlog of [pull requests](https://help.github.com/articles/using-pull-requests), but contributions are still very +much welcome. You can help with patch review, submitting bug reports, +or adding new functionality. There is no formal style guide, but +please conform to the style of existing code and general Go formatting +conventions when submitting patches. + +* [fork a repo](https://help.github.com/articles/fork-a-repo) +* [creating a pull request ](https://help.github.com/articles/creating-a-pull-request) + +### Language + +Since `xorm` is a world-wide open source project, please describe your issues or code changes in English as soon as possible. + +### Sign your codes with comments +``` +// !! your comments + +e.g., + +// !lunny! this is comments made by lunny +``` + +### Patch review + +Help review existing open [pull requests](https://help.github.com/articles/using-pull-requests) by commenting on the code or +proposed functionality. + +### Bug reports + +We appreciate any bug reports, but especially ones with self-contained +(doesn't depend on code outside of xorm), minimal (can't be simplified +further) test cases. It's especially helpful if you can submit a pull +request with just the failing test case(you can find some example test file like [session_get_test.go](https://gitea.com/xorm/xorm/src/branch/master/session_get_test.go)). + +If you implements a new database interface, you maybe need to add a test_.sh file. +For example, [mysql_test.go](https://gitea.com/xorm/xorm/src/branch/master/test_mysql.sh) + +### New functionality + +There are a number of pending patches for new functionality, so +additional feature patches will take a while to merge. Still, patches +are generally reviewed based on usefulness and complexity in addition +to time-in-queue, so if you have a knockout idea, take a shot. Feel +free to open an issue discussion your proposed patch beforehand. diff --git a/vendor/xorm.io/xorm/LICENSE b/vendor/xorm.io/xorm/LICENSE new file mode 100644 index 0000000000..84d2ae5386 --- /dev/null +++ b/vendor/xorm.io/xorm/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013 - 2015 The Xorm Authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the {organization} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/xorm.io/xorm/README.md b/vendor/xorm.io/xorm/README.md new file mode 100644 index 0000000000..17a6ed37ff --- /dev/null +++ b/vendor/xorm.io/xorm/README.md @@ -0,0 +1,503 @@ +# xorm + +[中文](https://gitea.com/xorm/xorm/src/branch/master/README_CN.md) + +Xorm is a simple and powerful ORM for Go. + +[![Build Status](https://drone.gitea.com/api/badges/xorm/xorm/status.svg)](https://drone.gitea.com/xorm/xorm) [![](http://gocover.io/_badge/xorm.io/xorm)](https://gocover.io/xorm.io/xorm) +[![](https://goreportcard.com/badge/xorm.io/xorm)](https://goreportcard.com/report/xorm.io/xorm) +[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](https://discord.gg/HuR2CF3) + +## Features + +* Struct <-> Table Mapping Support + +* Chainable APIs + +* Transaction Support + +* Both ORM and raw SQL operation Support + +* Sync database schema Support + +* Query Cache speed up + +* Database Reverse support, See [Xorm Tool README](https://github.com/go-xorm/cmd/blob/master/README.md) + +* Simple cascade loading support + +* Optimistic Locking support + +* SQL Builder support via [xorm.io/builder](https://xorm.io/builder) + +* Automatical Read/Write seperatelly + +* Postgres schema support + +* Context Cache support + +## Drivers Support + +Drivers for Go's sql package which currently support database/sql includes: + +* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) + +* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/tree/master/godrv) + +* Postgres: [github.com/lib/pq](https://github.com/lib/pq) + +* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb) + +* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) + +* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) + +* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment) + +## Installation + + go get xorm.io/xorm + +## Documents + +* [Manual](http://xorm.io/docs) + +* [GoDoc](http://godoc.org/xorm.io/xorm) + +## Quick Start + +* Create Engine + +```Go +engine, err := xorm.NewEngine(driverName, dataSourceName) +``` + +* Define a struct and Sync2 table struct to database + +```Go +type User struct { + Id int64 + Name string + Salt string + Age int + Passwd string `xorm:"varchar(200)"` + Created time.Time `xorm:"created"` + Updated time.Time `xorm:"updated"` +} + +err := engine.Sync2(new(User)) +``` + +* Create Engine Group + +```Go +dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName} +engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice) +``` + +```Go +masterEngine, err := xorm.NewEngine(driverName, masterDataSourceName) +slave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName) +slave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName) +engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine}) +``` + +Then all place where `engine` you can just use `engineGroup`. + +* `Query` runs a SQL string, the returned results is `[]map[string][]byte`, `QueryString` returns `[]map[string]string`, `QueryInterface` returns `[]map[string]interface{}`. + +```Go +results, err := engine.Query("select * from user") +results, err := engine.Where("a = 1").Query() + +results, err := engine.QueryString("select * from user") +results, err := engine.Where("a = 1").QueryString() + +results, err := engine.QueryInterface("select * from user") +results, err := engine.Where("a = 1").QueryInterface() +``` + +* `Exec` runs a SQL string, it returns `affected` and `error` + +```Go +affected, err := engine.Exec("update user set age = ? where name = ?", age, name) +``` + +* `Insert` one or multiple records to database + +```Go +affected, err := engine.Insert(&user) +// INSERT INTO struct () values () + +affected, err := engine.Insert(&user1, &user2) +// INSERT INTO struct1 () values () +// INSERT INTO struct2 () values () + +affected, err := engine.Insert(&users) +// INSERT INTO struct () values (),(),() + +affected, err := engine.Insert(&user1, &users) +// INSERT INTO struct1 () values () +// INSERT INTO struct2 () values (),(),() +``` + +* `Get` query one record from database + +```Go +has, err := engine.Get(&user) +// SELECT * FROM user LIMIT 1 + +has, err := engine.Where("name = ?", name).Desc("id").Get(&user) +// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1 + +var name string +has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name) +// SELECT name FROM user WHERE id = ? + +var id int64 +has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id) +has, err := engine.SQL("select id from user").Get(&id) +// SELECT id FROM user WHERE name = ? + +var valuesMap = make(map[string]string) +has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap) +// SELECT * FROM user WHERE id = ? + +var valuesSlice = make([]interface{}, len(cols)) +has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice) +// SELECT col1, col2, col3 FROM user WHERE id = ? +``` + +* `Exist` check if one record exist on table + +```Go +has, err := testEngine.Exist(new(RecordExist)) +// SELECT * FROM record_exist LIMIT 1 + +has, err = testEngine.Exist(&RecordExist{ + Name: "test1", + }) +// SELECT * FROM record_exist WHERE name = ? LIMIT 1 + +has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{}) +// SELECT * FROM record_exist WHERE name = ? LIMIT 1 + +has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist() +// select * from record_exist where name = ? + +has, err = testEngine.Table("record_exist").Exist() +// SELECT * FROM record_exist LIMIT 1 + +has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist() +// SELECT * FROM record_exist WHERE name = ? LIMIT 1 +``` + +* `Find` query multiple records from database, also you can use join and extends + +```Go +var users []User +err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users) +// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0 + +type Detail struct { + Id int64 + UserId int64 `xorm:"index"` +} + +type UserDetail struct { + User `xorm:"extends"` + Detail `xorm:"extends"` +} + +var users []UserDetail +err := engine.Table("user").Select("user.*, detail.*"). + Join("INNER", "detail", "detail.user_id = user.id"). + Where("user.name = ?", name).Limit(10, 0). + Find(&users) +// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0 +``` + +* `Iterate` and `Rows` query multiple records and record by record handle, there are two methods Iterate and Rows + +```Go +err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error { + user := bean.(*User) + return nil +}) +// SELECT * FROM user + +err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error { + user := bean.(*User) + return nil +}) +// SELECT * FROM user Limit 0, 100 +// SELECT * FROM user Limit 101, 100 + +rows, err := engine.Rows(&User{Name:name}) +// SELECT * FROM user +defer rows.Close() +bean := new(Struct) +for rows.Next() { + err = rows.Scan(bean) +} +``` + +* `Update` update one or more records, default will update non-empty and non-zero fields except when you use Cols, AllCols and so on. + +```Go +affected, err := engine.ID(1).Update(&user) +// UPDATE user SET ... Where id = ? + +affected, err := engine.Update(&user, &User{Name:name}) +// UPDATE user SET ... Where name = ? + +var ids = []int64{1, 2, 3} +affected, err := engine.In("id", ids).Update(&user) +// UPDATE user SET ... Where id IN (?, ?, ?) + +// force update indicated columns by Cols +affected, err := engine.ID(1).Cols("age").Update(&User{Name:name, Age: 12}) +// UPDATE user SET age = ?, updated=? Where id = ? + +// force NOT update indicated columns by Omit +affected, err := engine.ID(1).Omit("name").Update(&User{Name:name, Age: 12}) +// UPDATE user SET age = ?, updated=? Where id = ? + +affected, err := engine.ID(1).AllCols().Update(&user) +// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ? +``` + +* `Delete` delete one or more records, Delete MUST have condition + +```Go +affected, err := engine.Where(...).Delete(&user) +// DELETE FROM user Where ... + +affected, err := engine.ID(2).Delete(&user) +// DELETE FROM user Where id = ? +``` + +* `Count` count records + +```Go +counts, err := engine.Count(&user) +// SELECT count(*) AS total FROM user +``` + +* `FindAndCount` combines function `Find` with `Count` which is usually used in query by page + +```Go +var users []User +counts, err := engine.FindAndCount(&users) +``` + +* `Sum` sum functions + +```Go +agesFloat64, err := engine.Sum(&user, "age") +// SELECT sum(age) AS total FROM user + +agesInt64, err := engine.SumInt(&user, "age") +// SELECT sum(age) AS total FROM user + +sumFloat64Slice, err := engine.Sums(&user, "age", "score") +// SELECT sum(age), sum(score) FROM user + +sumInt64Slice, err := engine.SumsInt(&user, "age", "score") +// SELECT sum(age), sum(score) FROM user +``` + +* Query conditions builder + +```Go +err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users) +// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?) +``` + +* Multiple operations in one go routine, no transation here but resue session memory + +```Go +session := engine.NewSession() +defer session.Close() + +user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} +if _, err := session.Insert(&user1); err != nil { + return err +} + +user2 := Userinfo{Username: "yyy"} +if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { + return err +} + +if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { + return err +} + +return nil +``` + +* Transation should be on one go routine. There is transaction and resue session memory + +```Go +session := engine.NewSession() +defer session.Close() + +// add Begin() before any action +if err := session.Begin(); err != nil { + // if returned then will rollback automatically + return err +} + +user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} +if _, err := session.Insert(&user1); err != nil { + return err +} + +user2 := Userinfo{Username: "yyy"} +if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { + return err +} + +if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { + return err +} + +// add Commit() after all actions +return session.Commit() +``` + +* Or you can use `Transaction` to replace above codes. + +```Go +res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) { + user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} + if _, err := session.Insert(&user1); err != nil { + return nil, err + } + + user2 := Userinfo{Username: "yyy"} + if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { + return nil, err + } + + if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { + return nil, err + } + return nil, nil +}) +``` + +* Context Cache, if enabled, current query result will be cached on session and be used by next same statement on the same session. + +```Go + sess := engine.NewSession() + defer sess.Close() + + var context = xorm.NewMemoryContextCache() + + var c2 ContextGetStruct + has, err := sess.ID(1).ContextCache(context).Get(&c2) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, c2.Id) + assert.EqualValues(t, "1", c2.Name) + sql, args := sess.LastSQL() + assert.True(t, len(sql) > 0) + assert.True(t, len(args) > 0) + + var c3 ContextGetStruct + has, err = sess.ID(1).ContextCache(context).Get(&c3) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, c3.Id) + assert.EqualValues(t, "1", c3.Name) + sql, args = sess.LastSQL() + assert.True(t, len(sql) == 0) + assert.True(t, len(args) == 0) +``` + +## Contributing + +If you want to pull request, please see [CONTRIBUTING](https://gitea.com/xorm/xorm/src/branch/master/CONTRIBUTING.md). And we also provide [Xorm on Google Groups](https://groups.google.com/forum/#!forum/xorm) to discuss. + +## Credits + +### Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + + +### Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/xorm#backer)] + + + +### Sponsors + +Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/xorm#sponsor)] + +## Changelog + +* **v0.7.0** + * Some bugs fixed + +* **v0.6.6** + * Some bugs fixed + +* **v0.6.5** + * Postgres schema support + * vgo support + * Add FindAndCount + * Database special params support via NewEngineWithParams + * Some bugs fixed + +* **v0.6.4** + * Automatical Read/Write seperatelly + * Query/QueryString/QueryInterface and action with Where/And + * Get support non-struct variables + * BufferSize on Iterate + * fix some other bugs. + +[More changes ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16) + +## Cases + +* [studygolang](http://studygolang.com/) - [github.com/studygolang/studygolang](https://github.com/studygolang/studygolang) + +* [Gitea](http://gitea.io) - [github.com/go-gitea/gitea](http://github.com/go-gitea/gitea) + +* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs) + +* [grafana](https://grafana.com/) - [github.com/grafana/grafana](http://github.com/grafana/grafana) + +* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader) + +* [Wego](http://github.com/go-tango/wego) + +* [Docker.cn](https://docker.cn/) + +* [Xorm Adapter](https://github.com/casbin/xorm-adapter) for [Casbin](https://github.com/casbin/casbin) - [github.com/casbin/xorm-adapter](https://github.com/casbin/xorm-adapter) + +* [Gorevel](http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel) + +* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker) + +* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild) + +* [Sudo China](http://sudochina.com) - [github.com/insionng/toropress](http://github.com/insionng/toropress) + +* [Godaily](http://godaily.org) - [github.com/govc/godaily](http://github.com/govc/godaily) + +* [YouGam](http://www.yougam.com/) + +* [GoCMS - github.com/zzboy/GoCMS](https://github.com/zzdboy/GoCMS) + +* [GoBBS - gobbs.domolo.com](http://gobbs.domolo.com/) + +* [go-blog](http://wangcheng.me) - [github.com/easykoo/go-blog](https://github.com/easykoo/go-blog) + +## LICENSE + +BSD License [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/) diff --git a/vendor/xorm.io/xorm/README_CN.md b/vendor/xorm.io/xorm/README_CN.md new file mode 100644 index 0000000000..644bdc0b63 --- /dev/null +++ b/vendor/xorm.io/xorm/README_CN.md @@ -0,0 +1,498 @@ +# xorm + +[English](https://gitea.com/xorm/xorm/src/branch/master/README.md) + +xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。 + +[![Build Status](https://drone.gitea.com/api/badges/xorm/builder/status.svg)](https://drone.gitea.com/xorm/builder) [![](http://gocover.io/_badge/xorm.io/xorm)](https://gocover.io/xorm.io/xorm) +[![](https://goreportcard.com/badge/xorm.io/xorm)](https://goreportcard.com/report/xorm.io/xorm) +[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](https://discord.gg/HuR2CF3) + +## 特性 + +* 支持Struct和数据库表之间的灵活映射,并支持自动同步 + +* 事务支持 + +* 同时支持原始SQL语句和ORM操作的混合执行 + +* 使用连写来简化调用 + +* 支持使用Id, In, Where, Limit, Join, Having, Table, Sql, Cols等函数和结构体等方式作为条件 + +* 支持级联加载Struct + +* Schema支持(仅Postgres) + +* 支持缓存 + +* 支持根据数据库自动生成xorm的结构体 + +* 支持记录版本(即乐观锁) + +* 内置SQL Builder支持 + +* 上下文缓存支持 + +## 驱动支持 + +目前支持的Go数据库驱动和对应的数据库如下: + +* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) + +* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv) + +* Postgres: [github.com/lib/pq](https://github.com/lib/pq) + +* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb) + +* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) + +* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) + +* MsSql: [github.com/lunny/godbc](https://github.com/lunny/godbc) + +* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (试验性支持) + +## 安装 + + go get xorm.io/xorm + +## 文档 + +* [操作指南](http://xorm.io/docs) + +* [Godoc代码文档](http://godoc.org/xorm.io/xorm) + +# 快速开始 + +* 第一步创建引擎,driverName, dataSourceName和database/sql接口相同 + +```Go +engine, err := xorm.NewEngine(driverName, dataSourceName) +``` + +* 定义一个和表同步的结构体,并且自动同步结构体到数据库 + +```Go +type User struct { + Id int64 + Name string + Salt string + Age int + Passwd string `xorm:"varchar(200)"` + Created time.Time `xorm:"created"` + Updated time.Time `xorm:"updated"` +} + +err := engine.Sync2(new(User)) +``` + +* 创建Engine组 + +```Go +dataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName} +engineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice) +``` + +```Go +masterEngine, err := xorm.NewEngine(driverName, masterDataSourceName) +slave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName) +slave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName) +engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine}) +``` + +所有使用 `engine` 都可以简单的用 `engineGroup` 来替换。 + +* `Query` 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte。`QueryString` 返回 []map[string]string, `QueryInterface` 返回 `[]map[string]interface{}`. + +```Go +results, err := engine.Query("select * from user") +results, err := engine.Where("a = 1").Query() + +results, err := engine.QueryString("select * from user") +results, err := engine.Where("a = 1").QueryString() + +results, err := engine.QueryInterface("select * from user") +results, err := engine.Where("a = 1").QueryInterface() +``` + +* `Exec` 执行一个SQL语句 + +```Go +affected, err := engine.Exec("update user set age = ? where name = ?", age, name) +``` + +* `Insert` 插入一条或者多条记录 + +```Go +affected, err := engine.Insert(&user) +// INSERT INTO struct () values () + +affected, err := engine.Insert(&user1, &user2) +// INSERT INTO struct1 () values () +// INSERT INTO struct2 () values () + +affected, err := engine.Insert(&users) +// INSERT INTO struct () values (),(),() + +affected, err := engine.Insert(&user1, &users) +// INSERT INTO struct1 () values () +// INSERT INTO struct2 () values (),(),() +``` + +* `Get` 查询单条记录 + +```Go +has, err := engine.Get(&user) +// SELECT * FROM user LIMIT 1 + +has, err := engine.Where("name = ?", name).Desc("id").Get(&user) +// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1 + +var name string +has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name) +// SELECT name FROM user WHERE id = ? + +var id int64 +has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id) +has, err := engine.SQL("select id from user").Get(&id) +// SELECT id FROM user WHERE name = ? + +var valuesMap = make(map[string]string) +has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap) +// SELECT * FROM user WHERE id = ? + +var valuesSlice = make([]interface{}, len(cols)) +has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice) +// SELECT col1, col2, col3 FROM user WHERE id = ? +``` + +* `Exist` 检测记录是否存在 + +```Go +has, err := testEngine.Exist(new(RecordExist)) +// SELECT * FROM record_exist LIMIT 1 + +has, err = testEngine.Exist(&RecordExist{ + Name: "test1", + }) +// SELECT * FROM record_exist WHERE name = ? LIMIT 1 + +has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{}) +// SELECT * FROM record_exist WHERE name = ? LIMIT 1 + +has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist() +// select * from record_exist where name = ? + +has, err = testEngine.Table("record_exist").Exist() +// SELECT * FROM record_exist LIMIT 1 + +has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist() +// SELECT * FROM record_exist WHERE name = ? LIMIT 1 +``` + +* `Find` 查询多条记录,当然可以使用Join和extends来组合使用 + +```Go +var users []User +err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users) +// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0 + +type Detail struct { + Id int64 + UserId int64 `xorm:"index"` +} + +type UserDetail struct { + User `xorm:"extends"` + Detail `xorm:"extends"` +} + +var users []UserDetail +err := engine.Table("user").Select("user.*, detail.*") + Join("INNER", "detail", "detail.user_id = user.id"). + Where("user.name = ?", name).Limit(10, 0). + Find(&users) +// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0 +``` + +* `Iterate` 和 `Rows` 根据条件遍历数据库,可以有两种方式: Iterate and Rows + +```Go +err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error { + user := bean.(*User) + return nil +}) +// SELECT * FROM user + +err := engine.BufferSize(100).Iterate(&User{Name:name}, func(idx int, bean interface{}) error { + user := bean.(*User) + return nil +}) +// SELECT * FROM user Limit 0, 100 +// SELECT * FROM user Limit 101, 100 + +rows, err := engine.Rows(&User{Name:name}) +// SELECT * FROM user +defer rows.Close() +bean := new(Struct) +for rows.Next() { + err = rows.Scan(bean) +} +``` + +* `Update` 更新数据,除非使用Cols,AllCols函数指明,默认只更新非空和非0的字段 + +```Go +affected, err := engine.ID(1).Update(&user) +// UPDATE user SET ... Where id = ? + +affected, err := engine.Update(&user, &User{Name:name}) +// UPDATE user SET ... Where name = ? + +var ids = []int64{1, 2, 3} +affected, err := engine.In(ids).Update(&user) +// UPDATE user SET ... Where id IN (?, ?, ?) + +// force update indicated columns by Cols +affected, err := engine.ID(1).Cols("age").Update(&User{Name:name, Age: 12}) +// UPDATE user SET age = ?, updated=? Where id = ? + +// force NOT update indicated columns by Omit +affected, err := engine.ID(1).Omit("name").Update(&User{Name:name, Age: 12}) +// UPDATE user SET age = ?, updated=? Where id = ? + +affected, err := engine.ID(1).AllCols().Update(&user) +// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ? +``` + +* `Delete` 删除记录,需要注意,删除必须至少有一个条件,否则会报错。要清空数据库可以用EmptyTable + +```Go +affected, err := engine.Where(...).Delete(&user) +// DELETE FROM user Where ... + +affected, err := engine.ID(2).Delete(&user) +// DELETE FROM user Where id = ? +``` + +* `Count` 获取记录条数 + +```Go +counts, err := engine.Count(&user) +// SELECT count(*) AS total FROM user +``` + +* `Sum` 求和函数 + +```Go +agesFloat64, err := engine.Sum(&user, "age") +// SELECT sum(age) AS total FROM user + +agesInt64, err := engine.SumInt(&user, "age") +// SELECT sum(age) AS total FROM user + +sumFloat64Slice, err := engine.Sums(&user, "age", "score") +// SELECT sum(age), sum(score) FROM user + +sumInt64Slice, err := engine.SumsInt(&user, "age", "score") +// SELECT sum(age), sum(score) FROM user +``` + +* 条件编辑器 + +```Go +err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users) +// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?) +``` + +* 在一个Go程中多次操作数据库,但没有事务 + +```Go +session := engine.NewSession() +defer session.Close() + +user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} +if _, err := session.Insert(&user1); err != nil { + return err +} + +user2 := Userinfo{Username: "yyy"} +if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { + return err +} + +if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { + return err +} + +return nil +``` + +* 在一个Go程中有事务 + +```Go +session := engine.NewSession() +defer session.Close() + +// add Begin() before any action +if err := session.Begin(); err != nil { + // if returned then will rollback automatically + return err +} + +user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} +if _, err := session.Insert(&user1); err != nil { + return err +} + +user2 := Userinfo{Username: "yyy"} +if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { + return err +} + +if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { + return err +} + +// add Commit() after all actions +return session.Commit() +``` + +* 事务的简写方法 + +```Go +res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) { + user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()} + if _, err := session.Insert(&user1); err != nil { + return nil, err + } + + user2 := Userinfo{Username: "yyy"} + if _, err := session.Where("id = ?", 2).Update(&user2); err != nil { + return nil, err + } + + if _, err := session.Exec("delete from userinfo where username = ?", user2.Username); err != nil { + return nil, err + } + return nil, nil +}) +``` + +* 上下文缓存,如果启用,那么针对单个对象的查询将会被缓存到系统中,可以被下一个查询使用。 + +```Go + sess := engine.NewSession() + defer sess.Close() + + var context = xorm.NewMemoryContextCache() + + var c2 ContextGetStruct + has, err := sess.ID(1).ContextCache(context).Get(&c2) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, c2.Id) + assert.EqualValues(t, "1", c2.Name) + sql, args := sess.LastSQL() + assert.True(t, len(sql) > 0) + assert.True(t, len(args) > 0) + + var c3 ContextGetStruct + has, err = sess.ID(1).ContextCache(context).Get(&c3) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, c3.Id) + assert.EqualValues(t, "1", c3.Name) + sql, args = sess.LastSQL() + assert.True(t, len(sql) == 0) + assert.True(t, len(args) == 0) +``` + +## 贡献 + +如果您也想为Xorm贡献您的力量,请查看 [CONTRIBUTING](https://gitea.com/xorm/xorm/src/branch/master/CONTRIBUTING.md)。您也可以加入QQ群 技术帮助和讨论。 +群一:280360085 (已满) +群二:795010183 + +## Credits + +### Contributors + +感谢所有的贡献者. [[Contribute](CONTRIBUTING.md)]. + + +### Backers + +感谢我们所有的 backers! 🙏 [[成为 backer](https://opencollective.com/xorm#backer)] + + + +### Sponsors + +成为 sponsor 来支持 xorm。您的 logo 将会被显示并被链接到您的网站。 [[成为 sponsor](https://opencollective.com/xorm#sponsor)] + +# 案例 + +* [Go语言中文网](http://studygolang.com/) - [github.com/studygolang/studygolang](https://github.com/studygolang/studygolang) + +* [Gitea](http://gitea.io) - [github.com/go-gitea/gitea](http://github.com/go-gitea/gitea) + +* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs) + +* [grafana](https://grafana.com/) - [github.com/grafana/grafana](http://github.com/grafana/grafana) + +* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader) + +* [Wego](http://github.com/go-tango/wego) + +* [Docker.cn](https://docker.cn/) + +* [Xorm Adapter](https://github.com/casbin/xorm-adapter) for [Casbin](https://github.com/casbin/casbin) - [github.com/casbin/xorm-adapter](https://github.com/casbin/xorm-adapter) + +* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker) + +* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild) + +* [Sudo China](http://sudochina.com) - [github.com/insionng/toropress](http://github.com/insionng/toropress) + +* [Godaily](http://godaily.org) - [github.com/govc/godaily](http://github.com/govc/godaily) + +* [YouGam](http://www.yougam.com/) + +* [GoCMS - github.com/zzboy/GoCMS](https://github.com/zzdboy/GoCMS) + +* [GoBBS - gobbs.domolo.com](http://gobbs.domolo.com/) + +* [go-blog](http://wangcheng.me) - [github.com/easykoo/go-blog](https://github.com/easykoo/go-blog) + + +## 更新日志 + +* **v0.7.0** + * 修正部分Bug + +* **v0.6.6** + * 修正部分Bug + +* **v0.6.5** + * 通过 engine.SetSchema 来支持 schema,当前仅支持Postgres + * vgo 支持 + * 新增 `FindAndCount` 函数 + * 通过 `NewEngineWithParams` 支持数据库特别参数 + * 修正部分Bug + +* **v0.6.4** + * 自动读写分离支持 + * Query/QueryString/QueryInterface 支持与 Where/And 合用 + * `Get` 支持获取非结构体变量 + * `Iterate` 支持 `BufferSize` + * 修正部分Bug + +[更多更新日志...](https://github.com/go-xorm/manual-zh-CN/tree/master/chapter-16) + +## LICENSE + +BSD License +[http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/) diff --git a/vendor/xorm.io/xorm/cache_lru.go b/vendor/xorm.io/xorm/cache_lru.go new file mode 100644 index 0000000000..ab948bd28e --- /dev/null +++ b/vendor/xorm.io/xorm/cache_lru.go @@ -0,0 +1,284 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "container/list" + "fmt" + "sync" + "time" + + "xorm.io/core" +) + +// LRUCacher implments cache object facilities +type LRUCacher struct { + idList *list.List + sqlList *list.List + idIndex map[string]map[string]*list.Element + sqlIndex map[string]map[string]*list.Element + store core.CacheStore + mutex sync.Mutex + MaxElementSize int + Expired time.Duration + GcInterval time.Duration +} + +// NewLRUCacher creates a cacher +func NewLRUCacher(store core.CacheStore, maxElementSize int) *LRUCacher { + return NewLRUCacher2(store, 3600*time.Second, maxElementSize) +} + +// NewLRUCacher2 creates a cache include different params +func NewLRUCacher2(store core.CacheStore, expired time.Duration, maxElementSize int) *LRUCacher { + cacher := &LRUCacher{store: store, idList: list.New(), + sqlList: list.New(), Expired: expired, + GcInterval: core.CacheGcInterval, MaxElementSize: maxElementSize, + sqlIndex: make(map[string]map[string]*list.Element), + idIndex: make(map[string]map[string]*list.Element), + } + cacher.RunGC() + return cacher +} + +// RunGC run once every m.GcInterval +func (m *LRUCacher) RunGC() { + time.AfterFunc(m.GcInterval, func() { + m.RunGC() + m.GC() + }) +} + +// GC check ids lit and sql list to remove all element expired +func (m *LRUCacher) GC() { + m.mutex.Lock() + defer m.mutex.Unlock() + var removedNum int + for e := m.idList.Front(); e != nil; { + if removedNum <= core.CacheGcMaxRemoved && + time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired { + removedNum++ + next := e.Next() + node := e.Value.(*idNode) + m.delBean(node.tbName, node.id) + e = next + } else { + break + } + } + + removedNum = 0 + for e := m.sqlList.Front(); e != nil; { + if removedNum <= core.CacheGcMaxRemoved && + time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired { + removedNum++ + next := e.Next() + node := e.Value.(*sqlNode) + m.delIds(node.tbName, node.sql) + e = next + } else { + break + } + } +} + +// GetIds returns all bean's ids according to sql and parameter from cache +func (m *LRUCacher) GetIds(tableName, sql string) interface{} { + m.mutex.Lock() + defer m.mutex.Unlock() + if _, ok := m.sqlIndex[tableName]; !ok { + m.sqlIndex[tableName] = make(map[string]*list.Element) + } + if v, err := m.store.Get(sql); err == nil { + if el, ok := m.sqlIndex[tableName][sql]; !ok { + el = m.sqlList.PushBack(newSQLNode(tableName, sql)) + m.sqlIndex[tableName][sql] = el + } else { + lastTime := el.Value.(*sqlNode).lastVisit + // if expired, remove the node and return nil + if time.Now().Sub(lastTime) > m.Expired { + m.delIds(tableName, sql) + return nil + } + m.sqlList.MoveToBack(el) + el.Value.(*sqlNode).lastVisit = time.Now() + } + return v + } + + m.delIds(tableName, sql) + return nil +} + +// GetBean returns bean according tableName and id from cache +func (m *LRUCacher) GetBean(tableName string, id string) interface{} { + m.mutex.Lock() + defer m.mutex.Unlock() + if _, ok := m.idIndex[tableName]; !ok { + m.idIndex[tableName] = make(map[string]*list.Element) + } + tid := genID(tableName, id) + if v, err := m.store.Get(tid); err == nil { + if el, ok := m.idIndex[tableName][id]; ok { + lastTime := el.Value.(*idNode).lastVisit + // if expired, remove the node and return nil + if time.Now().Sub(lastTime) > m.Expired { + m.delBean(tableName, id) + return nil + } + m.idList.MoveToBack(el) + el.Value.(*idNode).lastVisit = time.Now() + } else { + el = m.idList.PushBack(newIDNode(tableName, id)) + m.idIndex[tableName][id] = el + } + return v + } + + // store bean is not exist, then remove memory's index + m.delBean(tableName, id) + return nil +} + +// clearIds clears all sql-ids mapping on table tableName from cache +func (m *LRUCacher) clearIds(tableName string) { + if tis, ok := m.sqlIndex[tableName]; ok { + for sql, v := range tis { + m.sqlList.Remove(v) + m.store.Del(sql) + } + } + m.sqlIndex[tableName] = make(map[string]*list.Element) +} + +// ClearIds clears all sql-ids mapping on table tableName from cache +func (m *LRUCacher) ClearIds(tableName string) { + m.mutex.Lock() + m.clearIds(tableName) + m.mutex.Unlock() +} + +func (m *LRUCacher) clearBeans(tableName string) { + if tis, ok := m.idIndex[tableName]; ok { + for id, v := range tis { + m.idList.Remove(v) + tid := genID(tableName, id) + m.store.Del(tid) + } + } + m.idIndex[tableName] = make(map[string]*list.Element) +} + +// ClearBeans clears all beans in some table +func (m *LRUCacher) ClearBeans(tableName string) { + m.mutex.Lock() + m.clearBeans(tableName) + m.mutex.Unlock() +} + +// PutIds pus ids into table +func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) { + m.mutex.Lock() + if _, ok := m.sqlIndex[tableName]; !ok { + m.sqlIndex[tableName] = make(map[string]*list.Element) + } + if el, ok := m.sqlIndex[tableName][sql]; !ok { + el = m.sqlList.PushBack(newSQLNode(tableName, sql)) + m.sqlIndex[tableName][sql] = el + } else { + el.Value.(*sqlNode).lastVisit = time.Now() + } + m.store.Put(sql, ids) + if m.sqlList.Len() > m.MaxElementSize { + e := m.sqlList.Front() + node := e.Value.(*sqlNode) + m.delIds(node.tbName, node.sql) + } + m.mutex.Unlock() +} + +// PutBean puts beans into table +func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) { + m.mutex.Lock() + var el *list.Element + var ok bool + + if el, ok = m.idIndex[tableName][id]; !ok { + el = m.idList.PushBack(newIDNode(tableName, id)) + m.idIndex[tableName][id] = el + } else { + el.Value.(*idNode).lastVisit = time.Now() + } + + m.store.Put(genID(tableName, id), obj) + if m.idList.Len() > m.MaxElementSize { + e := m.idList.Front() + node := e.Value.(*idNode) + m.delBean(node.tbName, node.id) + } + m.mutex.Unlock() +} + +func (m *LRUCacher) delIds(tableName, sql string) { + if _, ok := m.sqlIndex[tableName]; ok { + if el, ok := m.sqlIndex[tableName][sql]; ok { + delete(m.sqlIndex[tableName], sql) + m.sqlList.Remove(el) + } + } + m.store.Del(sql) +} + +// DelIds deletes ids +func (m *LRUCacher) DelIds(tableName, sql string) { + m.mutex.Lock() + m.delIds(tableName, sql) + m.mutex.Unlock() +} + +func (m *LRUCacher) delBean(tableName string, id string) { + tid := genID(tableName, id) + if el, ok := m.idIndex[tableName][id]; ok { + delete(m.idIndex[tableName], id) + m.idList.Remove(el) + m.clearIds(tableName) + } + m.store.Del(tid) +} + +// DelBean deletes beans in some table +func (m *LRUCacher) DelBean(tableName string, id string) { + m.mutex.Lock() + m.delBean(tableName, id) + m.mutex.Unlock() +} + +type idNode struct { + tbName string + id string + lastVisit time.Time +} + +type sqlNode struct { + tbName string + sql string + lastVisit time.Time +} + +func genSQLKey(sql string, args interface{}) string { + return fmt.Sprintf("%v-%v", sql, args) +} + +func genID(prefix string, id string) string { + return fmt.Sprintf("%v-%v", prefix, id) +} + +func newIDNode(tbName string, id string) *idNode { + return &idNode{tbName, id, time.Now()} +} + +func newSQLNode(tbName, sql string) *sqlNode { + return &sqlNode{tbName, sql, time.Now()} +} diff --git a/vendor/xorm.io/xorm/cache_memory_store.go b/vendor/xorm.io/xorm/cache_memory_store.go new file mode 100644 index 0000000000..0c483f4583 --- /dev/null +++ b/vendor/xorm.io/xorm/cache_memory_store.go @@ -0,0 +1,51 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "sync" + + "xorm.io/core" +) + +var _ core.CacheStore = NewMemoryStore() + +// MemoryStore represents in-memory store +type MemoryStore struct { + store map[interface{}]interface{} + mutex sync.RWMutex +} + +// NewMemoryStore creates a new store in memory +func NewMemoryStore() *MemoryStore { + return &MemoryStore{store: make(map[interface{}]interface{})} +} + +// Put puts object into store +func (s *MemoryStore) Put(key string, value interface{}) error { + s.mutex.Lock() + defer s.mutex.Unlock() + s.store[key] = value + return nil +} + +// Get gets object from store +func (s *MemoryStore) Get(key string) (interface{}, error) { + s.mutex.RLock() + defer s.mutex.RUnlock() + if v, ok := s.store[key]; ok { + return v, nil + } + + return nil, ErrNotExist +} + +// Del deletes object +func (s *MemoryStore) Del(key string) error { + s.mutex.Lock() + defer s.mutex.Unlock() + delete(s.store, key) + return nil +} diff --git a/vendor/xorm.io/xorm/context_cache.go b/vendor/xorm.io/xorm/context_cache.go new file mode 100644 index 0000000000..1bc2288496 --- /dev/null +++ b/vendor/xorm.io/xorm/context_cache.go @@ -0,0 +1,30 @@ +// Copyright 2018 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +// ContextCache is the interface that operates the cache data. +type ContextCache interface { + // Put puts value into cache with key. + Put(key string, val interface{}) + // Get gets cached value by given key. + Get(key string) interface{} +} + +type memoryContextCache map[string]interface{} + +// NewMemoryContextCache return memoryContextCache +func NewMemoryContextCache() memoryContextCache { + return make(map[string]interface{}) +} + +// Put puts value into cache with key. +func (m memoryContextCache) Put(key string, val interface{}) { + m[key] = val +} + +// Get gets cached value by given key. +func (m memoryContextCache) Get(key string) interface{} { + return m[key] +} diff --git a/vendor/xorm.io/xorm/convert.go b/vendor/xorm.io/xorm/convert.go new file mode 100644 index 0000000000..2316ca0b4d --- /dev/null +++ b/vendor/xorm.io/xorm/convert.go @@ -0,0 +1,348 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql/driver" + "errors" + "fmt" + "reflect" + "strconv" + "time" +) + +var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error + +func strconvErr(err error) error { + if ne, ok := err.(*strconv.NumError); ok { + return ne.Err + } + return err +} + +func cloneBytes(b []byte) []byte { + if b == nil { + return nil + } else { + c := make([]byte, len(b)) + copy(c, b) + return c + } +} + +func asString(src interface{}) string { + switch v := src.(type) { + case string: + return v + case []byte: + return string(v) + } + rv := reflect.ValueOf(src) + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(rv.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return strconv.FormatUint(rv.Uint(), 10) + case reflect.Float64: + return strconv.FormatFloat(rv.Float(), 'g', -1, 64) + case reflect.Float32: + return strconv.FormatFloat(rv.Float(), 'g', -1, 32) + case reflect.Bool: + return strconv.FormatBool(rv.Bool()) + } + return fmt.Sprintf("%v", src) +} + +func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) { + switch rv.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.AppendInt(buf, rv.Int(), 10), true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return strconv.AppendUint(buf, rv.Uint(), 10), true + case reflect.Float32: + return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true + case reflect.Float64: + return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true + case reflect.Bool: + return strconv.AppendBool(buf, rv.Bool()), true + case reflect.String: + s := rv.String() + return append(buf, s...), true + } + return +} + +// convertAssign copies to dest the value in src, converting it if possible. +// An error is returned if the copy would result in loss of information. +// dest should be a pointer type. +func convertAssign(dest, src interface{}) error { + // Common cases, without reflect. + switch s := src.(type) { + case string: + switch d := dest.(type) { + case *string: + if d == nil { + return errNilPtr + } + *d = s + return nil + case *[]byte: + if d == nil { + return errNilPtr + } + *d = []byte(s) + return nil + } + case []byte: + switch d := dest.(type) { + case *string: + if d == nil { + return errNilPtr + } + *d = string(s) + return nil + case *interface{}: + if d == nil { + return errNilPtr + } + *d = cloneBytes(s) + return nil + case *[]byte: + if d == nil { + return errNilPtr + } + *d = cloneBytes(s) + return nil + } + + case time.Time: + switch d := dest.(type) { + case *string: + *d = s.Format(time.RFC3339Nano) + return nil + case *[]byte: + if d == nil { + return errNilPtr + } + *d = []byte(s.Format(time.RFC3339Nano)) + return nil + } + case nil: + switch d := dest.(type) { + case *interface{}: + if d == nil { + return errNilPtr + } + *d = nil + return nil + case *[]byte: + if d == nil { + return errNilPtr + } + *d = nil + return nil + } + } + + var sv reflect.Value + + switch d := dest.(type) { + case *string: + sv = reflect.ValueOf(src) + switch sv.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64: + *d = asString(src) + return nil + } + case *[]byte: + sv = reflect.ValueOf(src) + if b, ok := asBytes(nil, sv); ok { + *d = b + return nil + } + case *bool: + bv, err := driver.Bool.ConvertValue(src) + if err == nil { + *d = bv.(bool) + } + return err + case *interface{}: + *d = src + return nil + } + + dpv := reflect.ValueOf(dest) + if dpv.Kind() != reflect.Ptr { + return errors.New("destination not a pointer") + } + if dpv.IsNil() { + return errNilPtr + } + + if !sv.IsValid() { + sv = reflect.ValueOf(src) + } + + dv := reflect.Indirect(dpv) + if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) { + switch b := src.(type) { + case []byte: + dv.Set(reflect.ValueOf(cloneBytes(b))) + default: + dv.Set(sv) + } + return nil + } + + if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) { + dv.Set(sv.Convert(dv.Type())) + return nil + } + + switch dv.Kind() { + case reflect.Ptr: + if src == nil { + dv.Set(reflect.Zero(dv.Type())) + return nil + } + + dv.Set(reflect.New(dv.Type().Elem())) + return convertAssign(dv.Interface(), src) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + s := asString(src) + i64, err := strconv.ParseInt(s, 10, dv.Type().Bits()) + if err != nil { + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) + } + dv.SetInt(i64) + return nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + s := asString(src) + u64, err := strconv.ParseUint(s, 10, dv.Type().Bits()) + if err != nil { + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) + } + dv.SetUint(u64) + return nil + case reflect.Float32, reflect.Float64: + s := asString(src) + f64, err := strconv.ParseFloat(s, dv.Type().Bits()) + if err != nil { + err = strconvErr(err) + return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err) + } + dv.SetFloat(f64) + return nil + case reflect.String: + dv.SetString(asString(src)) + return nil + } + + return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest) +} + +func asKind(vv reflect.Value, tp reflect.Type) (interface{}, error) { + switch tp.Kind() { + case reflect.Int64: + return vv.Int(), nil + case reflect.Int: + return int(vv.Int()), nil + case reflect.Int32: + return int32(vv.Int()), nil + case reflect.Int16: + return int16(vv.Int()), nil + case reflect.Int8: + return int8(vv.Int()), nil + case reflect.Uint64: + return vv.Uint(), nil + case reflect.Uint: + return uint(vv.Uint()), nil + case reflect.Uint32: + return uint32(vv.Uint()), nil + case reflect.Uint16: + return uint16(vv.Uint()), nil + case reflect.Uint8: + return uint8(vv.Uint()), nil + case reflect.String: + return vv.String(), nil + case reflect.Slice: + if tp.Elem().Kind() == reflect.Uint8 { + v, err := strconv.ParseInt(string(vv.Interface().([]byte)), 10, 64) + if err != nil { + return nil, err + } + return v, nil + } + + } + return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv) +} + +func convertFloat(v interface{}) (float64, error) { + switch v.(type) { + case float32: + return float64(v.(float32)), nil + case float64: + return v.(float64), nil + case string: + i, err := strconv.ParseFloat(v.(string), 64) + if err != nil { + return 0, err + } + return i, nil + case []byte: + i, err := strconv.ParseFloat(string(v.([]byte)), 64) + if err != nil { + return 0, err + } + return i, nil + } + return 0, fmt.Errorf("unsupported type: %v", v) +} + +func convertInt(v interface{}) (int64, error) { + switch v.(type) { + case int: + return int64(v.(int)), nil + case int8: + return int64(v.(int8)), nil + case int16: + return int64(v.(int16)), nil + case int32: + return int64(v.(int32)), nil + case int64: + return v.(int64), nil + case []byte: + i, err := strconv.ParseInt(string(v.([]byte)), 10, 64) + if err != nil { + return 0, err + } + return i, nil + case string: + i, err := strconv.ParseInt(v.(string), 10, 64) + if err != nil { + return 0, err + } + return i, nil + } + return 0, fmt.Errorf("unsupported type: %v", v) +} + +func asBool(bs []byte) (bool, error) { + if len(bs) == 0 { + return false, nil + } + if bs[0] == 0x00 { + return false, nil + } else if bs[0] == 0x01 { + return true, nil + } + return strconv.ParseBool(string(bs)) +} diff --git a/vendor/xorm.io/xorm/dialect_mssql.go b/vendor/xorm.io/xorm/dialect_mssql.go new file mode 100644 index 0000000000..29070da2fb --- /dev/null +++ b/vendor/xorm.io/xorm/dialect_mssql.go @@ -0,0 +1,567 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "net/url" + "strconv" + "strings" + + "xorm.io/core" +) + +var ( + mssqlReservedWords = map[string]bool{ + "ADD": true, + "EXTERNAL": true, + "PROCEDURE": true, + "ALL": true, + "FETCH": true, + "PUBLIC": true, + "ALTER": true, + "FILE": true, + "RAISERROR": true, + "AND": true, + "FILLFACTOR": true, + "READ": true, + "ANY": true, + "FOR": true, + "READTEXT": true, + "AS": true, + "FOREIGN": true, + "RECONFIGURE": true, + "ASC": true, + "FREETEXT": true, + "REFERENCES": true, + "AUTHORIZATION": true, + "FREETEXTTABLE": true, + "REPLICATION": true, + "BACKUP": true, + "FROM": true, + "RESTORE": true, + "BEGIN": true, + "FULL": true, + "RESTRICT": true, + "BETWEEN": true, + "FUNCTION": true, + "RETURN": true, + "BREAK": true, + "GOTO": true, + "REVERT": true, + "BROWSE": true, + "GRANT": true, + "REVOKE": true, + "BULK": true, + "GROUP": true, + "RIGHT": true, + "BY": true, + "HAVING": true, + "ROLLBACK": true, + "CASCADE": true, + "HOLDLOCK": true, + "ROWCOUNT": true, + "CASE": true, + "IDENTITY": true, + "ROWGUIDCOL": true, + "CHECK": true, + "IDENTITY_INSERT": true, + "RULE": true, + "CHECKPOINT": true, + "IDENTITYCOL": true, + "SAVE": true, + "CLOSE": true, + "IF": true, + "SCHEMA": true, + "CLUSTERED": true, + "IN": true, + "SECURITYAUDIT": true, + "COALESCE": true, + "INDEX": true, + "SELECT": true, + "COLLATE": true, + "INNER": true, + "SEMANTICKEYPHRASETABLE": true, + "COLUMN": true, + "INSERT": true, + "SEMANTICSIMILARITYDETAILSTABLE": true, + "COMMIT": true, + "INTERSECT": true, + "SEMANTICSIMILARITYTABLE": true, + "COMPUTE": true, + "INTO": true, + "SESSION_USER": true, + "CONSTRAINT": true, + "IS": true, + "SET": true, + "CONTAINS": true, + "JOIN": true, + "SETUSER": true, + "CONTAINSTABLE": true, + "KEY": true, + "SHUTDOWN": true, + "CONTINUE": true, + "KILL": true, + "SOME": true, + "CONVERT": true, + "LEFT": true, + "STATISTICS": true, + "CREATE": true, + "LIKE": true, + "SYSTEM_USER": true, + "CROSS": true, + "LINENO": true, + "TABLE": true, + "CURRENT": true, + "LOAD": true, + "TABLESAMPLE": true, + "CURRENT_DATE": true, + "MERGE": true, + "TEXTSIZE": true, + "CURRENT_TIME": true, + "NATIONAL": true, + "THEN": true, + "CURRENT_TIMESTAMP": true, + "NOCHECK": true, + "TO": true, + "CURRENT_USER": true, + "NONCLUSTERED": true, + "TOP": true, + "CURSOR": true, + "NOT": true, + "TRAN": true, + "DATABASE": true, + "NULL": true, + "TRANSACTION": true, + "DBCC": true, + "NULLIF": true, + "TRIGGER": true, + "DEALLOCATE": true, + "OF": true, + "TRUNCATE": true, + "DECLARE": true, + "OFF": true, + "TRY_CONVERT": true, + "DEFAULT": true, + "OFFSETS": true, + "TSEQUAL": true, + "DELETE": true, + "ON": true, + "UNION": true, + "DENY": true, + "OPEN": true, + "UNIQUE": true, + "DESC": true, + "OPENDATASOURCE": true, + "UNPIVOT": true, + "DISK": true, + "OPENQUERY": true, + "UPDATE": true, + "DISTINCT": true, + "OPENROWSET": true, + "UPDATETEXT": true, + "DISTRIBUTED": true, + "OPENXML": true, + "USE": true, + "DOUBLE": true, + "OPTION": true, + "USER": true, + "DROP": true, + "OR": true, + "VALUES": true, + "DUMP": true, + "ORDER": true, + "VARYING": true, + "ELSE": true, + "OUTER": true, + "VIEW": true, + "END": true, + "OVER": true, + "WAITFOR": true, + "ERRLVL": true, + "PERCENT": true, + "WHEN": true, + "ESCAPE": true, + "PIVOT": true, + "WHERE": true, + "EXCEPT": true, + "PLAN": true, + "WHILE": true, + "EXEC": true, + "PRECISION": true, + "WITH": true, + "EXECUTE": true, + "PRIMARY": true, + "WITHIN": true, + "EXISTS": true, + "PRINT": true, + "WRITETEXT": true, + "EXIT": true, + "PROC": true, + } +) + +type mssql struct { + core.Base +} + +func (db *mssql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { + return db.Base.Init(d, db, uri, drivername, dataSourceName) +} + +func (db *mssql) SqlType(c *core.Column) string { + var res string + switch t := c.SQLType.Name; t { + case core.Bool: + res = core.Bit + if strings.EqualFold(c.Default, "true") { + c.Default = "1" + } else if strings.EqualFold(c.Default, "false") { + c.Default = "0" + } + case core.Serial: + c.IsAutoIncrement = true + c.IsPrimaryKey = true + c.Nullable = false + res = core.Int + case core.BigSerial: + c.IsAutoIncrement = true + c.IsPrimaryKey = true + c.Nullable = false + res = core.BigInt + case core.Bytea, core.Blob, core.Binary, core.TinyBlob, core.MediumBlob, core.LongBlob: + res = core.VarBinary + if c.Length == 0 { + c.Length = 50 + } + case core.TimeStamp: + res = core.DateTime + case core.TimeStampz: + res = "DATETIMEOFFSET" + c.Length = 7 + case core.MediumInt: + res = core.Int + case core.Text, core.MediumText, core.TinyText, core.LongText, core.Json: + res = core.Varchar + "(MAX)" + case core.Double: + res = core.Real + case core.Uuid: + res = core.Varchar + c.Length = 40 + case core.TinyInt: + res = core.TinyInt + c.Length = 0 + case core.BigInt: + res = core.BigInt + c.Length = 0 + default: + res = t + } + + if res == core.Int { + return core.Int + } + + hasLen1 := (c.Length > 0) + hasLen2 := (c.Length2 > 0) + + if hasLen2 { + res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" + } + return res +} + +func (db *mssql) SupportInsertMany() bool { + return true +} + +func (db *mssql) IsReserved(name string) bool { + _, ok := mssqlReservedWords[name] + return ok +} + +func (db *mssql) Quote(name string) string { + return "\"" + name + "\"" +} + +func (db *mssql) SupportEngine() bool { + return false +} + +func (db *mssql) AutoIncrStr() string { + return "IDENTITY" +} + +func (db *mssql) DropTableSql(tableName string) string { + return fmt.Sprintf("IF EXISTS (SELECT * FROM sysobjects WHERE id = "+ + "object_id(N'%s') and OBJECTPROPERTY(id, N'IsUserTable') = 1) "+ + "DROP TABLE \"%s\"", tableName, tableName) +} + +func (db *mssql) SupportCharset() bool { + return false +} + +func (db *mssql) IndexOnTable() bool { + return true +} + +func (db *mssql) IndexCheckSql(tableName, idxName string) (string, []interface{}) { + args := []interface{}{idxName} + sql := "select name from sysindexes where id=object_id('" + tableName + "') and name=?" + return sql, args +} + +/*func (db *mssql) ColumnCheckSql(tableName, colName string) (string, []interface{}) { + args := []interface{}{tableName, colName} + sql := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?` + return sql, args +}*/ + +func (db *mssql) IsColumnExist(tableName, colName string) (bool, error) { + query := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?` + + return db.HasRecords(query, tableName, colName) +} + +func (db *mssql) TableCheckSql(tableName string) (string, []interface{}) { + args := []interface{}{} + sql := "select * from sysobjects where id = object_id(N'" + tableName + "') and OBJECTPROPERTY(id, N'IsUserTable') = 1" + return sql, args +} + +func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { + args := []interface{}{} + s := `select a.name as name, b.name as ctype,a.max_length,a.precision,a.scale,a.is_nullable as nullable, + "default_is_null" = (CASE WHEN c.text is null THEN 1 ELSE 0 END), + replace(replace(isnull(c.text,''),'(',''),')','') as vdefault, + ISNULL(i.is_primary_key, 0), a.is_identity as is_identity + from sys.columns a + left join sys.types b on a.user_type_id=b.user_type_id + left join sys.syscomments c on a.default_object_id=c.id + LEFT OUTER JOIN + sys.index_columns ic ON ic.object_id = a.object_id AND ic.column_id = a.column_id + LEFT OUTER JOIN + sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id + where a.object_id=object_id('` + tableName + `')` + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, nil, err + } + defer rows.Close() + + cols := make(map[string]*core.Column) + colSeq := make([]string, 0) + for rows.Next() { + var name, ctype, vdefault string + var maxLen, precision, scale int + var nullable, isPK, defaultIsNull, isIncrement bool + err = rows.Scan(&name, &ctype, &maxLen, &precision, &scale, &nullable, &defaultIsNull, &vdefault, &isPK, &isIncrement) + if err != nil { + return nil, nil, err + } + + col := new(core.Column) + col.Indexes = make(map[string]int) + col.Name = strings.Trim(name, "` ") + col.Nullable = nullable + col.DefaultIsEmpty = defaultIsNull + if !defaultIsNull { + col.Default = vdefault + } + col.IsPrimaryKey = isPK + col.IsAutoIncrement = isIncrement + ct := strings.ToUpper(ctype) + if ct == "DECIMAL" { + col.Length = precision + col.Length2 = scale + } else { + col.Length = maxLen + } + switch ct { + case "DATETIMEOFFSET": + col.SQLType = core.SQLType{Name: core.TimeStampz, DefaultLength: 0, DefaultLength2: 0} + case "NVARCHAR": + col.SQLType = core.SQLType{Name: core.NVarchar, DefaultLength: 0, DefaultLength2: 0} + case "IMAGE": + col.SQLType = core.SQLType{Name: core.VarBinary, DefaultLength: 0, DefaultLength2: 0} + default: + if _, ok := core.SqlTypes[ct]; ok { + col.SQLType = core.SQLType{Name: ct, DefaultLength: 0, DefaultLength2: 0} + } else { + return nil, nil, fmt.Errorf("Unknown colType %v for %v - %v", ct, tableName, col.Name) + } + } + + cols[col.Name] = col + colSeq = append(colSeq, col.Name) + } + return colSeq, cols, nil +} + +func (db *mssql) GetTables() ([]*core.Table, error) { + args := []interface{}{} + s := `select name from sysobjects where xtype ='U'` + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + tables := make([]*core.Table, 0) + for rows.Next() { + table := core.NewEmptyTable() + var name string + err = rows.Scan(&name) + if err != nil { + return nil, err + } + table.Name = strings.Trim(name, "` ") + tables = append(tables, table) + } + return tables, nil +} + +func (db *mssql) GetIndexes(tableName string) (map[string]*core.Index, error) { + args := []interface{}{tableName} + s := `SELECT +IXS.NAME AS [INDEX_NAME], +C.NAME AS [COLUMN_NAME], +IXS.is_unique AS [IS_UNIQUE] +FROM SYS.INDEXES IXS +INNER JOIN SYS.INDEX_COLUMNS IXCS +ON IXS.OBJECT_ID=IXCS.OBJECT_ID AND IXS.INDEX_ID = IXCS.INDEX_ID +INNER JOIN SYS.COLUMNS C ON IXS.OBJECT_ID=C.OBJECT_ID +AND IXCS.COLUMN_ID=C.COLUMN_ID +WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =? +` + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + indexes := make(map[string]*core.Index, 0) + for rows.Next() { + var indexType int + var indexName, colName, isUnique string + + err = rows.Scan(&indexName, &colName, &isUnique) + if err != nil { + return nil, err + } + + i, err := strconv.ParseBool(isUnique) + if err != nil { + return nil, err + } + + if i { + indexType = core.UniqueType + } else { + indexType = core.IndexType + } + + colName = strings.Trim(colName, "` ") + var isRegular bool + if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { + indexName = indexName[5+len(tableName):] + isRegular = true + } + + var index *core.Index + var ok bool + if index, ok = indexes[indexName]; !ok { + index = new(core.Index) + index.Type = indexType + index.Name = indexName + index.IsRegular = isRegular + indexes[indexName] = index + } + index.AddColumn(colName) + } + return indexes, nil +} + +func (db *mssql) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string { + var sql string + if tableName == "" { + tableName = table.Name + } + + sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE " + + sql += db.Quote(tableName) + " (" + + pkList := table.PrimaryKeys + + for _, colName := range table.ColumnsSeq() { + col := table.GetColumn(colName) + if col.IsPrimaryKey && len(pkList) == 1 { + sql += col.String(db) + } else { + sql += col.StringNoPk(db) + } + sql = strings.TrimSpace(sql) + sql += ", " + } + + if len(pkList) > 1 { + sql += "PRIMARY KEY ( " + sql += strings.Join(pkList, ",") + sql += " ), " + } + + sql = sql[:len(sql)-2] + ")" + sql += ";" + return sql +} + +func (db *mssql) ForUpdateSql(query string) string { + return query +} + +func (db *mssql) Filters() []core.Filter { + return []core.Filter{&core.IdFilter{}, &core.QuoteFilter{}} +} + +type odbcDriver struct { +} + +func (p *odbcDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { + var dbName string + + if strings.HasPrefix(dataSourceName, "sqlserver://") { + u, err := url.Parse(dataSourceName) + if err != nil { + return nil, err + } + dbName = u.Query().Get("database") + } else { + kv := strings.Split(dataSourceName, ";") + for _, c := range kv { + vv := strings.Split(strings.TrimSpace(c), "=") + if len(vv) == 2 { + switch strings.ToLower(vv[0]) { + case "database": + dbName = vv[1] + } + } + } + } + if dbName == "" { + return nil, errors.New("no db name provided") + } + return &core.Uri{DbName: dbName, DbType: core.MSSQL}, nil +} diff --git a/vendor/xorm.io/xorm/dialect_mysql.go b/vendor/xorm.io/xorm/dialect_mysql.go new file mode 100644 index 0000000000..cf1dbb6f21 --- /dev/null +++ b/vendor/xorm.io/xorm/dialect_mysql.go @@ -0,0 +1,654 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "crypto/tls" + "errors" + "fmt" + "regexp" + "strconv" + "strings" + "time" + + "xorm.io/core" +) + +var ( + mysqlReservedWords = map[string]bool{ + "ADD": true, + "ALL": true, + "ALTER": true, + "ANALYZE": true, + "AND": true, + "AS": true, + "ASC": true, + "ASENSITIVE": true, + "BEFORE": true, + "BETWEEN": true, + "BIGINT": true, + "BINARY": true, + "BLOB": true, + "BOTH": true, + "BY": true, + "CALL": true, + "CASCADE": true, + "CASE": true, + "CHANGE": true, + "CHAR": true, + "CHARACTER": true, + "CHECK": true, + "COLLATE": true, + "COLUMN": true, + "CONDITION": true, + "CONNECTION": true, + "CONSTRAINT": true, + "CONTINUE": true, + "CONVERT": true, + "CREATE": true, + "CROSS": true, + "CURRENT_DATE": true, + "CURRENT_TIME": true, + "CURRENT_TIMESTAMP": true, + "CURRENT_USER": true, + "CURSOR": true, + "DATABASE": true, + "DATABASES": true, + "DAY_HOUR": true, + "DAY_MICROSECOND": true, + "DAY_MINUTE": true, + "DAY_SECOND": true, + "DEC": true, + "DECIMAL": true, + "DECLARE": true, + "DEFAULT": true, + "DELAYED": true, + "DELETE": true, + "DESC": true, + "DESCRIBE": true, + "DETERMINISTIC": true, + "DISTINCT": true, + "DISTINCTROW": true, + "DIV": true, + "DOUBLE": true, + "DROP": true, + "DUAL": true, + "EACH": true, + "ELSE": true, + "ELSEIF": true, + "ENCLOSED": true, + "ESCAPED": true, + "EXISTS": true, + "EXIT": true, + "EXPLAIN": true, + "FALSE": true, + "FETCH": true, + "FLOAT": true, + "FLOAT4": true, + "FLOAT8": true, + "FOR": true, + "FORCE": true, + "FOREIGN": true, + "FROM": true, + "FULLTEXT": true, + "GOTO": true, + "GRANT": true, + "GROUP": true, + "HAVING": true, + "HIGH_PRIORITY": true, + "HOUR_MICROSECOND": true, + "HOUR_MINUTE": true, + "HOUR_SECOND": true, + "IF": true, + "IGNORE": true, + "IN": true, "INDEX": true, + "INFILE": true, "INNER": true, "INOUT": true, + "INSENSITIVE": true, "INSERT": true, "INT": true, + "INT1": true, "INT2": true, "INT3": true, + "INT4": true, "INT8": true, "INTEGER": true, + "INTERVAL": true, "INTO": true, "IS": true, + "ITERATE": true, "JOIN": true, "KEY": true, + "KEYS": true, "KILL": true, "LABEL": true, + "LEADING": true, "LEAVE": true, "LEFT": true, + "LIKE": true, "LIMIT": true, "LINEAR": true, + "LINES": true, "LOAD": true, "LOCALTIME": true, + "LOCALTIMESTAMP": true, "LOCK": true, "LONG": true, + "LONGBLOB": true, "LONGTEXT": true, "LOOP": true, + "LOW_PRIORITY": true, "MATCH": true, "MEDIUMBLOB": true, + "MEDIUMINT": true, "MEDIUMTEXT": true, "MIDDLEINT": true, + "MINUTE_MICROSECOND": true, "MINUTE_SECOND": true, "MOD": true, + "MODIFIES": true, "NATURAL": true, "NOT": true, + "NO_WRITE_TO_BINLOG": true, "NULL": true, "NUMERIC": true, + "ON OPTIMIZE": true, "OPTION": true, + "OPTIONALLY": true, "OR": true, "ORDER": true, + "OUT": true, "OUTER": true, "OUTFILE": true, + "PRECISION": true, "PRIMARY": true, "PROCEDURE": true, + "PURGE": true, "RAID0": true, "RANGE": true, + "READ": true, "READS": true, "REAL": true, + "REFERENCES": true, "REGEXP": true, "RELEASE": true, + "RENAME": true, "REPEAT": true, "REPLACE": true, + "REQUIRE": true, "RESTRICT": true, "RETURN": true, + "REVOKE": true, "RIGHT": true, "RLIKE": true, + "SCHEMA": true, "SCHEMAS": true, "SECOND_MICROSECOND": true, + "SELECT": true, "SENSITIVE": true, "SEPARATOR": true, + "SET": true, "SHOW": true, "SMALLINT": true, + "SPATIAL": true, "SPECIFIC": true, "SQL": true, + "SQLEXCEPTION": true, "SQLSTATE": true, "SQLWARNING": true, + "SQL_BIG_RESULT": true, "SQL_CALC_FOUND_ROWS": true, "SQL_SMALL_RESULT": true, + "SSL": true, "STARTING": true, "STRAIGHT_JOIN": true, + "TABLE": true, "TERMINATED": true, "THEN": true, + "TINYBLOB": true, "TINYINT": true, "TINYTEXT": true, + "TO": true, "TRAILING": true, "TRIGGER": true, + "TRUE": true, "UNDO": true, "UNION": true, + "UNIQUE": true, "UNLOCK": true, "UNSIGNED": true, + "UPDATE": true, "USAGE": true, "USE": true, + "USING": true, "UTC_DATE": true, "UTC_TIME": true, + "UTC_TIMESTAMP": true, "VALUES": true, "VARBINARY": true, + "VARCHAR": true, + "VARCHARACTER": true, + "VARYING": true, + "WHEN": true, + "WHERE": true, + "WHILE": true, + "WITH": true, + "WRITE": true, + "X509": true, + "XOR": true, + "YEAR_MONTH": true, + "ZEROFILL": true, + } +) + +type mysql struct { + core.Base + net string + addr string + params map[string]string + loc *time.Location + timeout time.Duration + tls *tls.Config + allowAllFiles bool + allowOldPasswords bool + clientFoundRows bool + rowFormat string +} + +func (db *mysql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { + return db.Base.Init(d, db, uri, drivername, dataSourceName) +} + +func (db *mysql) SetParams(params map[string]string) { + rowFormat, ok := params["rowFormat"] + if ok { + var t = strings.ToUpper(rowFormat) + switch t { + case "COMPACT": + fallthrough + case "REDUNDANT": + fallthrough + case "DYNAMIC": + fallthrough + case "COMPRESSED": + db.rowFormat = t + break + default: + break + } + } +} + +func (db *mysql) SqlType(c *core.Column) string { + var res string + switch t := c.SQLType.Name; t { + case core.Bool: + res = core.TinyInt + c.Length = 1 + case core.Serial: + c.IsAutoIncrement = true + c.IsPrimaryKey = true + c.Nullable = false + res = core.Int + case core.BigSerial: + c.IsAutoIncrement = true + c.IsPrimaryKey = true + c.Nullable = false + res = core.BigInt + case core.Bytea: + res = core.Blob + case core.TimeStampz: + res = core.Char + c.Length = 64 + case core.Enum: // mysql enum + res = core.Enum + res += "(" + opts := "" + for v := range c.EnumOptions { + opts += fmt.Sprintf(",'%v'", v) + } + res += strings.TrimLeft(opts, ",") + res += ")" + case core.Set: // mysql set + res = core.Set + res += "(" + opts := "" + for v := range c.SetOptions { + opts += fmt.Sprintf(",'%v'", v) + } + res += strings.TrimLeft(opts, ",") + res += ")" + case core.NVarchar: + res = core.Varchar + case core.Uuid: + res = core.Varchar + c.Length = 40 + case core.Json: + res = core.Text + default: + res = t + } + + hasLen1 := (c.Length > 0) + hasLen2 := (c.Length2 > 0) + + if res == core.BigInt && !hasLen1 && !hasLen2 { + c.Length = 20 + hasLen1 = true + } + + if hasLen2 { + res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" + } + return res +} + +func (db *mysql) SupportInsertMany() bool { + return true +} + +func (db *mysql) IsReserved(name string) bool { + _, ok := mysqlReservedWords[name] + return ok +} + +func (db *mysql) Quote(name string) string { + return "`" + name + "`" +} + +func (db *mysql) SupportEngine() bool { + return true +} + +func (db *mysql) AutoIncrStr() string { + return "AUTO_INCREMENT" +} + +func (db *mysql) SupportCharset() bool { + return true +} + +func (db *mysql) IndexOnTable() bool { + return true +} + +func (db *mysql) IndexCheckSql(tableName, idxName string) (string, []interface{}) { + args := []interface{}{db.DbName, tableName, idxName} + sql := "SELECT `INDEX_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS`" + sql += " WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `INDEX_NAME`=?" + return sql, args +} + +/*func (db *mysql) ColumnCheckSql(tableName, colName string) (string, []interface{}) { + args := []interface{}{db.DbName, tableName, colName} + sql := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?" + return sql, args +}*/ + +func (db *mysql) TableCheckSql(tableName string) (string, []interface{}) { + args := []interface{}{db.DbName, tableName} + sql := "SELECT `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? and `TABLE_NAME`=?" + return sql, args +} + +func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { + args := []interface{}{db.DbName, tableName} + s := "SELECT `COLUMN_NAME`, `IS_NULLABLE`, `COLUMN_DEFAULT`, `COLUMN_TYPE`," + + " `COLUMN_KEY`, `EXTRA`,`COLUMN_COMMENT` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, nil, err + } + defer rows.Close() + + cols := make(map[string]*core.Column) + colSeq := make([]string, 0) + for rows.Next() { + col := new(core.Column) + col.Indexes = make(map[string]int) + + var columnName, isNullable, colType, colKey, extra, comment string + var colDefault *string + err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment) + if err != nil { + return nil, nil, err + } + col.Name = strings.Trim(columnName, "` ") + col.Comment = comment + if "YES" == isNullable { + col.Nullable = true + } + + if colDefault != nil { + col.Default = *colDefault + col.DefaultIsEmpty = false + } else { + col.DefaultIsEmpty = true + } + + cts := strings.Split(colType, "(") + colName := cts[0] + colType = strings.ToUpper(colName) + var len1, len2 int + if len(cts) == 2 { + idx := strings.Index(cts[1], ")") + if colType == core.Enum && cts[1][0] == '\'' { // enum + options := strings.Split(cts[1][0:idx], ",") + col.EnumOptions = make(map[string]int) + for k, v := range options { + v = strings.TrimSpace(v) + v = strings.Trim(v, "'") + col.EnumOptions[v] = k + } + } else if colType == core.Set && cts[1][0] == '\'' { + options := strings.Split(cts[1][0:idx], ",") + col.SetOptions = make(map[string]int) + for k, v := range options { + v = strings.TrimSpace(v) + v = strings.Trim(v, "'") + col.SetOptions[v] = k + } + } else { + lens := strings.Split(cts[1][0:idx], ",") + len1, err = strconv.Atoi(strings.TrimSpace(lens[0])) + if err != nil { + return nil, nil, err + } + if len(lens) == 2 { + len2, err = strconv.Atoi(lens[1]) + if err != nil { + return nil, nil, err + } + } + } + } + if colType == "FLOAT UNSIGNED" { + colType = "FLOAT" + } + if colType == "DOUBLE UNSIGNED" { + colType = "DOUBLE" + } + col.Length = len1 + col.Length2 = len2 + if _, ok := core.SqlTypes[colType]; ok { + col.SQLType = core.SQLType{Name: colType, DefaultLength: len1, DefaultLength2: len2} + } else { + return nil, nil, fmt.Errorf("Unknown colType %v", colType) + } + + if colKey == "PRI" { + col.IsPrimaryKey = true + } + if colKey == "UNI" { + // col.is + } + + if extra == "auto_increment" { + col.IsAutoIncrement = true + } + + if !col.DefaultIsEmpty { + if col.SQLType.IsText() { + col.Default = "'" + col.Default + "'" + } else if col.SQLType.IsTime() && col.Default != "CURRENT_TIMESTAMP" { + col.Default = "'" + col.Default + "'" + } + } + cols[col.Name] = col + colSeq = append(colSeq, col.Name) + } + return colSeq, cols, nil +} + +func (db *mysql) GetTables() ([]*core.Table, error) { + args := []interface{}{db.DbName} + s := "SELECT `TABLE_NAME`, `ENGINE`, `TABLE_ROWS`, `AUTO_INCREMENT`, `TABLE_COMMENT` from " + + "`INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? AND (`ENGINE`='MyISAM' OR `ENGINE` = 'InnoDB' OR `ENGINE` = 'TokuDB')" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + tables := make([]*core.Table, 0) + for rows.Next() { + table := core.NewEmptyTable() + var name, engine, tableRows, comment string + var autoIncr *string + err = rows.Scan(&name, &engine, &tableRows, &autoIncr, &comment) + if err != nil { + return nil, err + } + + table.Name = name + table.Comment = comment + table.StoreEngine = engine + tables = append(tables, table) + } + return tables, nil +} + +func (db *mysql) GetIndexes(tableName string) (map[string]*core.Index, error) { + args := []interface{}{db.DbName, tableName} + s := "SELECT `INDEX_NAME`, `NON_UNIQUE`, `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + indexes := make(map[string]*core.Index, 0) + for rows.Next() { + var indexType int + var indexName, colName, nonUnique string + err = rows.Scan(&indexName, &nonUnique, &colName) + if err != nil { + return nil, err + } + + if indexName == "PRIMARY" { + continue + } + + if "YES" == nonUnique || nonUnique == "1" { + indexType = core.IndexType + } else { + indexType = core.UniqueType + } + + colName = strings.Trim(colName, "` ") + var isRegular bool + if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { + indexName = indexName[5+len(tableName):] + isRegular = true + } + + var index *core.Index + var ok bool + if index, ok = indexes[indexName]; !ok { + index = new(core.Index) + index.IsRegular = isRegular + index.Type = indexType + index.Name = indexName + indexes[indexName] = index + } + index.AddColumn(colName) + } + return indexes, nil +} + +func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string { + var sql string + sql = "CREATE TABLE IF NOT EXISTS " + if tableName == "" { + tableName = table.Name + } + + sql += db.Quote(tableName) + sql += " (" + + if len(table.ColumnsSeq()) > 0 { + pkList := table.PrimaryKeys + + for _, colName := range table.ColumnsSeq() { + col := table.GetColumn(colName) + if col.IsPrimaryKey && len(pkList) == 1 { + sql += col.String(db) + } else { + sql += col.StringNoPk(db) + } + sql = strings.TrimSpace(sql) + if len(col.Comment) > 0 { + sql += " COMMENT '" + col.Comment + "'" + } + sql += ", " + } + + if len(pkList) > 1 { + sql += "PRIMARY KEY ( " + sql += db.Quote(strings.Join(pkList, db.Quote(","))) + sql += " ), " + } + + sql = sql[:len(sql)-2] + } + sql += ")" + + if storeEngine != "" { + sql += " ENGINE=" + storeEngine + } + + if len(charset) == 0 { + charset = db.URI().Charset + } + if len(charset) != 0 { + sql += " DEFAULT CHARSET " + charset + } + + if db.rowFormat != "" { + sql += " ROW_FORMAT=" + db.rowFormat + } + return sql +} + +func (db *mysql) Filters() []core.Filter { + return []core.Filter{&core.IdFilter{}} +} + +type mymysqlDriver struct { +} + +func (p *mymysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { + db := &core.Uri{DbType: core.MYSQL} + + pd := strings.SplitN(dataSourceName, "*", 2) + if len(pd) == 2 { + // Parse protocol part of URI + p := strings.SplitN(pd[0], ":", 2) + if len(p) != 2 { + return nil, errors.New("Wrong protocol part of URI") + } + db.Proto = p[0] + options := strings.Split(p[1], ",") + db.Raddr = options[0] + for _, o := range options[1:] { + kv := strings.SplitN(o, "=", 2) + var k, v string + if len(kv) == 2 { + k, v = kv[0], kv[1] + } else { + k, v = o, "true" + } + switch k { + case "laddr": + db.Laddr = v + case "timeout": + to, err := time.ParseDuration(v) + if err != nil { + return nil, err + } + db.Timeout = to + default: + return nil, errors.New("Unknown option: " + k) + } + } + // Remove protocol part + pd = pd[1:] + } + // Parse database part of URI + dup := strings.SplitN(pd[0], "/", 3) + if len(dup) != 3 { + return nil, errors.New("Wrong database part of URI") + } + db.DbName = dup[0] + db.User = dup[1] + db.Passwd = dup[2] + + return db, nil +} + +type mysqlDriver struct { +} + +func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { + dsnPattern := regexp.MustCompile( + `^(?:(?P.*?)(?::(?P.*))?@)?` + // [user[:password]@] + `(?:(?P[^\(]*)(?:\((?P[^\)]*)\))?)?` + // [net[(addr)]] + `\/(?P.*?)` + // /dbname + `(?:\?(?P[^\?]*))?$`) // [?param1=value1¶mN=valueN] + matches := dsnPattern.FindStringSubmatch(dataSourceName) + // tlsConfigRegister := make(map[string]*tls.Config) + names := dsnPattern.SubexpNames() + + uri := &core.Uri{DbType: core.MYSQL} + + for i, match := range matches { + switch names[i] { + case "dbname": + uri.DbName = match + case "params": + if len(match) > 0 { + kvs := strings.Split(match, "&") + for _, kv := range kvs { + splits := strings.Split(kv, "=") + if len(splits) == 2 { + switch splits[0] { + case "charset": + uri.Charset = splits[1] + } + } + } + } + + } + } + return uri, nil +} diff --git a/vendor/xorm.io/xorm/dialect_oracle.go b/vendor/xorm.io/xorm/dialect_oracle.go new file mode 100644 index 0000000000..15010ca5a3 --- /dev/null +++ b/vendor/xorm.io/xorm/dialect_oracle.go @@ -0,0 +1,902 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "regexp" + "strconv" + "strings" + + "xorm.io/core" +) + +var ( + oracleReservedWords = map[string]bool{ + "ACCESS": true, + "ACCOUNT": true, + "ACTIVATE": true, + "ADD": true, + "ADMIN": true, + "ADVISE": true, + "AFTER": true, + "ALL": true, + "ALL_ROWS": true, + "ALLOCATE": true, + "ALTER": true, + "ANALYZE": true, + "AND": true, + "ANY": true, + "ARCHIVE": true, + "ARCHIVELOG": true, + "ARRAY": true, + "AS": true, + "ASC": true, + "AT": true, + "AUDIT": true, + "AUTHENTICATED": true, + "AUTHORIZATION": true, + "AUTOEXTEND": true, + "AUTOMATIC": true, + "BACKUP": true, + "BECOME": true, + "BEFORE": true, + "BEGIN": true, + "BETWEEN": true, + "BFILE": true, + "BITMAP": true, + "BLOB": true, + "BLOCK": true, + "BODY": true, + "BY": true, + "CACHE": true, + "CACHE_INSTANCES": true, + "CANCEL": true, + "CASCADE": true, + "CAST": true, + "CFILE": true, + "CHAINED": true, + "CHANGE": true, + "CHAR": true, + "CHAR_CS": true, + "CHARACTER": true, + "CHECK": true, + "CHECKPOINT": true, + "CHOOSE": true, + "CHUNK": true, + "CLEAR": true, + "CLOB": true, + "CLONE": true, + "CLOSE": true, + "CLOSE_CACHED_OPEN_CURSORS": true, + "CLUSTER": true, + "COALESCE": true, + "COLUMN": true, + "COLUMNS": true, + "COMMENT": true, + "COMMIT": true, + "COMMITTED": true, + "COMPATIBILITY": true, + "COMPILE": true, + "COMPLETE": true, + "COMPOSITE_LIMIT": true, + "COMPRESS": true, + "COMPUTE": true, + "CONNECT": true, + "CONNECT_TIME": true, + "CONSTRAINT": true, + "CONSTRAINTS": true, + "CONTENTS": true, + "CONTINUE": true, + "CONTROLFILE": true, + "CONVERT": true, + "COST": true, + "CPU_PER_CALL": true, + "CPU_PER_SESSION": true, + "CREATE": true, + "CURRENT": true, + "CURRENT_SCHEMA": true, + "CURREN_USER": true, + "CURSOR": true, + "CYCLE": true, + "DANGLING": true, + "DATABASE": true, + "DATAFILE": true, + "DATAFILES": true, + "DATAOBJNO": true, + "DATE": true, + "DBA": true, + "DBHIGH": true, + "DBLOW": true, + "DBMAC": true, + "DEALLOCATE": true, + "DEBUG": true, + "DEC": true, + "DECIMAL": true, + "DECLARE": true, + "DEFAULT": true, + "DEFERRABLE": true, + "DEFERRED": true, + "DEGREE": true, + "DELETE": true, + "DEREF": true, + "DESC": true, + "DIRECTORY": true, + "DISABLE": true, + "DISCONNECT": true, + "DISMOUNT": true, + "DISTINCT": true, + "DISTRIBUTED": true, + "DML": true, + "DOUBLE": true, + "DROP": true, + "DUMP": true, + "EACH": true, + "ELSE": true, + "ENABLE": true, + "END": true, + "ENFORCE": true, + "ENTRY": true, + "ESCAPE": true, + "EXCEPT": true, + "EXCEPTIONS": true, + "EXCHANGE": true, + "EXCLUDING": true, + "EXCLUSIVE": true, + "EXECUTE": true, + "EXISTS": true, + "EXPIRE": true, + "EXPLAIN": true, + "EXTENT": true, + "EXTENTS": true, + "EXTERNALLY": true, + "FAILED_LOGIN_ATTEMPTS": true, + "FALSE": true, + "FAST": true, + "FILE": true, + "FIRST_ROWS": true, + "FLAGGER": true, + "FLOAT": true, + "FLOB": true, + "FLUSH": true, + "FOR": true, + "FORCE": true, + "FOREIGN": true, + "FREELIST": true, + "FREELISTS": true, + "FROM": true, + "FULL": true, + "FUNCTION": true, + "GLOBAL": true, + "GLOBALLY": true, + "GLOBAL_NAME": true, + "GRANT": true, + "GROUP": true, + "GROUPS": true, + "HASH": true, + "HASHKEYS": true, + "HAVING": true, + "HEADER": true, + "HEAP": true, + "IDENTIFIED": true, + "IDGENERATORS": true, + "IDLE_TIME": true, + "IF": true, + "IMMEDIATE": true, + "IN": true, + "INCLUDING": true, + "INCREMENT": true, + "INDEX": true, + "INDEXED": true, + "INDEXES": true, + "INDICATOR": true, + "IND_PARTITION": true, + "INITIAL": true, + "INITIALLY": true, + "INITRANS": true, + "INSERT": true, + "INSTANCE": true, + "INSTANCES": true, + "INSTEAD": true, + "INT": true, + "INTEGER": true, + "INTERMEDIATE": true, + "INTERSECT": true, + "INTO": true, + "IS": true, + "ISOLATION": true, + "ISOLATION_LEVEL": true, + "KEEP": true, + "KEY": true, + "KILL": true, + "LABEL": true, + "LAYER": true, + "LESS": true, + "LEVEL": true, + "LIBRARY": true, + "LIKE": true, + "LIMIT": true, + "LINK": true, + "LIST": true, + "LOB": true, + "LOCAL": true, + "LOCK": true, + "LOCKED": true, + "LOG": true, + "LOGFILE": true, + "LOGGING": true, + "LOGICAL_READS_PER_CALL": true, + "LOGICAL_READS_PER_SESSION": true, + "LONG": true, + "MANAGE": true, + "MASTER": true, + "MAX": true, + "MAXARCHLOGS": true, + "MAXDATAFILES": true, + "MAXEXTENTS": true, + "MAXINSTANCES": true, + "MAXLOGFILES": true, + "MAXLOGHISTORY": true, + "MAXLOGMEMBERS": true, + "MAXSIZE": true, + "MAXTRANS": true, + "MAXVALUE": true, + "MIN": true, + "MEMBER": true, + "MINIMUM": true, + "MINEXTENTS": true, + "MINUS": true, + "MINVALUE": true, + "MLSLABEL": true, + "MLS_LABEL_FORMAT": true, + "MODE": true, + "MODIFY": true, + "MOUNT": true, + "MOVE": true, + "MTS_DISPATCHERS": true, + "MULTISET": true, + "NATIONAL": true, + "NCHAR": true, + "NCHAR_CS": true, + "NCLOB": true, + "NEEDED": true, + "NESTED": true, + "NETWORK": true, + "NEW": true, + "NEXT": true, + "NOARCHIVELOG": true, + "NOAUDIT": true, + "NOCACHE": true, + "NOCOMPRESS": true, + "NOCYCLE": true, + "NOFORCE": true, + "NOLOGGING": true, + "NOMAXVALUE": true, + "NOMINVALUE": true, + "NONE": true, + "NOORDER": true, + "NOOVERRIDE": true, + "NOPARALLEL": true, + "NOREVERSE": true, + "NORMAL": true, + "NOSORT": true, + "NOT": true, + "NOTHING": true, + "NOWAIT": true, + "NULL": true, + "NUMBER": true, + "NUMERIC": true, + "NVARCHAR2": true, + "OBJECT": true, + "OBJNO": true, + "OBJNO_REUSE": true, + "OF": true, + "OFF": true, + "OFFLINE": true, + "OID": true, + "OIDINDEX": true, + "OLD": true, + "ON": true, + "ONLINE": true, + "ONLY": true, + "OPCODE": true, + "OPEN": true, + "OPTIMAL": true, + "OPTIMIZER_GOAL": true, + "OPTION": true, + "OR": true, + "ORDER": true, + "ORGANIZATION": true, + "OSLABEL": true, + "OVERFLOW": true, + "OWN": true, + "PACKAGE": true, + "PARALLEL": true, + "PARTITION": true, + "PASSWORD": true, + "PASSWORD_GRACE_TIME": true, + "PASSWORD_LIFE_TIME": true, + "PASSWORD_LOCK_TIME": true, + "PASSWORD_REUSE_MAX": true, + "PASSWORD_REUSE_TIME": true, + "PASSWORD_VERIFY_FUNCTION": true, + "PCTFREE": true, + "PCTINCREASE": true, + "PCTTHRESHOLD": true, + "PCTUSED": true, + "PCTVERSION": true, + "PERCENT": true, + "PERMANENT": true, + "PLAN": true, + "PLSQL_DEBUG": true, + "POST_TRANSACTION": true, + "PRECISION": true, + "PRESERVE": true, + "PRIMARY": true, + "PRIOR": true, + "PRIVATE": true, + "PRIVATE_SGA": true, + "PRIVILEGE": true, + "PRIVILEGES": true, + "PROCEDURE": true, + "PROFILE": true, + "PUBLIC": true, + "PURGE": true, + "QUEUE": true, + "QUOTA": true, + "RANGE": true, + "RAW": true, + "RBA": true, + "READ": true, + "READUP": true, + "REAL": true, + "REBUILD": true, + "RECOVER": true, + "RECOVERABLE": true, + "RECOVERY": true, + "REF": true, + "REFERENCES": true, + "REFERENCING": true, + "REFRESH": true, + "RENAME": true, + "REPLACE": true, + "RESET": true, + "RESETLOGS": true, + "RESIZE": true, + "RESOURCE": true, + "RESTRICTED": true, + "RETURN": true, + "RETURNING": true, + "REUSE": true, + "REVERSE": true, + "REVOKE": true, + "ROLE": true, + "ROLES": true, + "ROLLBACK": true, + "ROW": true, + "ROWID": true, + "ROWNUM": true, + "ROWS": true, + "RULE": true, + "SAMPLE": true, + "SAVEPOINT": true, + "SB4": true, + "SCAN_INSTANCES": true, + "SCHEMA": true, + "SCN": true, + "SCOPE": true, + "SD_ALL": true, + "SD_INHIBIT": true, + "SD_SHOW": true, + "SEGMENT": true, + "SEG_BLOCK": true, + "SEG_FILE": true, + "SELECT": true, + "SEQUENCE": true, + "SERIALIZABLE": true, + "SESSION": true, + "SESSION_CACHED_CURSORS": true, + "SESSIONS_PER_USER": true, + "SET": true, + "SHARE": true, + "SHARED": true, + "SHARED_POOL": true, + "SHRINK": true, + "SIZE": true, + "SKIP": true, + "SKIP_UNUSABLE_INDEXES": true, + "SMALLINT": true, + "SNAPSHOT": true, + "SOME": true, + "SORT": true, + "SPECIFICATION": true, + "SPLIT": true, + "SQL_TRACE": true, + "STANDBY": true, + "START": true, + "STATEMENT_ID": true, + "STATISTICS": true, + "STOP": true, + "STORAGE": true, + "STORE": true, + "STRUCTURE": true, + "SUCCESSFUL": true, + "SWITCH": true, + "SYS_OP_ENFORCE_NOT_NULL$": true, + "SYS_OP_NTCIMG$": true, + "SYNONYM": true, + "SYSDATE": true, + "SYSDBA": true, + "SYSOPER": true, + "SYSTEM": true, + "TABLE": true, + "TABLES": true, + "TABLESPACE": true, + "TABLESPACE_NO": true, + "TABNO": true, + "TEMPORARY": true, + "THAN": true, + "THE": true, + "THEN": true, + "THREAD": true, + "TIMESTAMP": true, + "TIME": true, + "TO": true, + "TOPLEVEL": true, + "TRACE": true, + "TRACING": true, + "TRANSACTION": true, + "TRANSITIONAL": true, + "TRIGGER": true, + "TRIGGERS": true, + "TRUE": true, + "TRUNCATE": true, + "TX": true, + "TYPE": true, + "UB2": true, + "UBA": true, + "UID": true, + "UNARCHIVED": true, + "UNDO": true, + "UNION": true, + "UNIQUE": true, + "UNLIMITED": true, + "UNLOCK": true, + "UNRECOVERABLE": true, + "UNTIL": true, + "UNUSABLE": true, + "UNUSED": true, + "UPDATABLE": true, + "UPDATE": true, + "USAGE": true, + "USE": true, + "USER": true, + "USING": true, + "VALIDATE": true, + "VALIDATION": true, + "VALUE": true, + "VALUES": true, + "VARCHAR": true, + "VARCHAR2": true, + "VARYING": true, + "VIEW": true, + "WHEN": true, + "WHENEVER": true, + "WHERE": true, + "WITH": true, + "WITHOUT": true, + "WORK": true, + "WRITE": true, + "WRITEDOWN": true, + "WRITEUP": true, + "XID": true, + "YEAR": true, + "ZONE": true, + } +) + +type oracle struct { + core.Base +} + +func (db *oracle) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { + return db.Base.Init(d, db, uri, drivername, dataSourceName) +} + +func (db *oracle) SqlType(c *core.Column) string { + var res string + switch t := c.SQLType.Name; t { + case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt, core.Bool, core.Serial, core.BigSerial: + res = "NUMBER" + case core.Binary, core.VarBinary, core.Blob, core.TinyBlob, core.MediumBlob, core.LongBlob, core.Bytea: + return core.Blob + case core.Time, core.DateTime, core.TimeStamp: + res = core.TimeStamp + case core.TimeStampz: + res = "TIMESTAMP WITH TIME ZONE" + case core.Float, core.Double, core.Numeric, core.Decimal: + res = "NUMBER" + case core.Text, core.MediumText, core.LongText, core.Json: + res = "CLOB" + case core.Char, core.Varchar, core.TinyText: + res = "VARCHAR2" + default: + res = t + } + + hasLen1 := (c.Length > 0) + hasLen2 := (c.Length2 > 0) + + if hasLen2 { + res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" + } + return res +} + +func (db *oracle) AutoIncrStr() string { + return "AUTO_INCREMENT" +} + +func (db *oracle) SupportInsertMany() bool { + return true +} + +func (db *oracle) IsReserved(name string) bool { + _, ok := oracleReservedWords[name] + return ok +} + +func (db *oracle) Quote(name string) string { + return "[" + name + "]" +} + +func (db *oracle) SupportEngine() bool { + return false +} + +func (db *oracle) SupportCharset() bool { + return false +} + +func (db *oracle) SupportDropIfExists() bool { + return false +} + +func (db *oracle) IndexOnTable() bool { + return false +} + +func (db *oracle) DropTableSql(tableName string) string { + return fmt.Sprintf("DROP TABLE `%s`", tableName) +} + +func (db *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string { + var sql string + sql = "CREATE TABLE " + if tableName == "" { + tableName = table.Name + } + + sql += db.Quote(tableName) + " (" + + pkList := table.PrimaryKeys + + for _, colName := range table.ColumnsSeq() { + col := table.GetColumn(colName) + /*if col.IsPrimaryKey && len(pkList) == 1 { + sql += col.String(b.dialect) + } else {*/ + sql += col.StringNoPk(db) + // } + sql = strings.TrimSpace(sql) + sql += ", " + } + + if len(pkList) > 0 { + sql += "PRIMARY KEY ( " + sql += db.Quote(strings.Join(pkList, db.Quote(","))) + sql += " ), " + } + + sql = sql[:len(sql)-2] + ")" + if db.SupportEngine() && storeEngine != "" { + sql += " ENGINE=" + storeEngine + } + if db.SupportCharset() { + if len(charset) == 0 { + charset = db.URI().Charset + } + if len(charset) > 0 { + sql += " DEFAULT CHARSET " + charset + } + } + return sql +} + +func (db *oracle) IndexCheckSql(tableName, idxName string) (string, []interface{}) { + args := []interface{}{tableName, idxName} + return `SELECT INDEX_NAME FROM USER_INDEXES ` + + `WHERE TABLE_NAME = :1 AND INDEX_NAME = :2`, args +} + +func (db *oracle) TableCheckSql(tableName string) (string, []interface{}) { + args := []interface{}{tableName} + return `SELECT table_name FROM user_tables WHERE table_name = :1`, args +} + +func (db *oracle) MustDropTable(tableName string) error { + sql, args := db.TableCheckSql(tableName) + db.LogSQL(sql, args) + + rows, err := db.DB().Query(sql, args...) + if err != nil { + return err + } + defer rows.Close() + + if !rows.Next() { + return nil + } + + sql = "Drop Table \"" + tableName + "\"" + db.LogSQL(sql, args) + + _, err = db.DB().Exec(sql) + return err +} + +/*func (db *oracle) ColumnCheckSql(tableName, colName string) (string, []interface{}) { + args := []interface{}{strings.ToUpper(tableName), strings.ToUpper(colName)} + return "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = ?" + + " AND column_name = ?", args +}*/ + +func (db *oracle) IsColumnExist(tableName, colName string) (bool, error) { + args := []interface{}{tableName, colName} + query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" + + " AND column_name = :2" + db.LogSQL(query, args) + + rows, err := db.DB().Query(query, args...) + if err != nil { + return false, err + } + defer rows.Close() + + if rows.Next() { + return true, nil + } + return false, nil +} + +func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { + args := []interface{}{tableName} + s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," + + "nullable FROM USER_TAB_COLUMNS WHERE table_name = :1" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, nil, err + } + defer rows.Close() + + cols := make(map[string]*core.Column) + colSeq := make([]string, 0) + for rows.Next() { + col := new(core.Column) + col.Indexes = make(map[string]int) + + var colName, colDefault, nullable, dataType, dataPrecision, dataScale *string + var dataLen int + + err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision, + &dataScale, &nullable) + if err != nil { + return nil, nil, err + } + + col.Name = strings.Trim(*colName, `" `) + if colDefault != nil { + col.Default = *colDefault + col.DefaultIsEmpty = false + } + + if *nullable == "Y" { + col.Nullable = true + } else { + col.Nullable = false + } + + var ignore bool + + var dt string + var len1, len2 int + dts := strings.Split(*dataType, "(") + dt = dts[0] + if len(dts) > 1 { + lens := strings.Split(dts[1][:len(dts[1])-1], ",") + if len(lens) > 1 { + len1, _ = strconv.Atoi(lens[0]) + len2, _ = strconv.Atoi(lens[1]) + } else { + len1, _ = strconv.Atoi(lens[0]) + } + } + + switch dt { + case "VARCHAR2": + col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: len1, DefaultLength2: len2} + case "NVARCHAR2": + col.SQLType = core.SQLType{Name: core.NVarchar, DefaultLength: len1, DefaultLength2: len2} + case "TIMESTAMP WITH TIME ZONE": + col.SQLType = core.SQLType{Name: core.TimeStampz, DefaultLength: 0, DefaultLength2: 0} + case "NUMBER": + col.SQLType = core.SQLType{Name: core.Double, DefaultLength: len1, DefaultLength2: len2} + case "LONG", "LONG RAW": + col.SQLType = core.SQLType{Name: core.Text, DefaultLength: 0, DefaultLength2: 0} + case "RAW": + col.SQLType = core.SQLType{Name: core.Binary, DefaultLength: 0, DefaultLength2: 0} + case "ROWID": + col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: 18, DefaultLength2: 0} + case "AQ$_SUBSCRIBERS": + ignore = true + default: + col.SQLType = core.SQLType{Name: strings.ToUpper(dt), DefaultLength: len1, DefaultLength2: len2} + } + + if ignore { + continue + } + + if _, ok := core.SqlTypes[col.SQLType.Name]; !ok { + return nil, nil, fmt.Errorf("Unknown colType %v %v", *dataType, col.SQLType) + } + + col.Length = dataLen + + if col.SQLType.IsText() || col.SQLType.IsTime() { + if !col.DefaultIsEmpty { + col.Default = "'" + col.Default + "'" + } + } + cols[col.Name] = col + colSeq = append(colSeq, col.Name) + } + + return colSeq, cols, nil +} + +func (db *oracle) GetTables() ([]*core.Table, error) { + args := []interface{}{} + s := "SELECT table_name FROM user_tables" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + tables := make([]*core.Table, 0) + for rows.Next() { + table := core.NewEmptyTable() + err = rows.Scan(&table.Name) + if err != nil { + return nil, err + } + + tables = append(tables, table) + } + return tables, nil +} + +func (db *oracle) GetIndexes(tableName string) (map[string]*core.Index, error) { + args := []interface{}{tableName} + s := "SELECT t.column_name,i.uniqueness,i.index_name FROM user_ind_columns t,user_indexes i " + + "WHERE t.index_name = i.index_name and t.table_name = i.table_name and t.table_name =:1" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + indexes := make(map[string]*core.Index, 0) + for rows.Next() { + var indexType int + var indexName, colName, uniqueness string + + err = rows.Scan(&colName, &uniqueness, &indexName) + if err != nil { + return nil, err + } + + indexName = strings.Trim(indexName, `" `) + + var isRegular bool + if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { + indexName = indexName[5+len(tableName):] + isRegular = true + } + + if uniqueness == "UNIQUE" { + indexType = core.UniqueType + } else { + indexType = core.IndexType + } + + var index *core.Index + var ok bool + if index, ok = indexes[indexName]; !ok { + index = new(core.Index) + index.Type = indexType + index.Name = indexName + index.IsRegular = isRegular + indexes[indexName] = index + } + index.AddColumn(colName) + } + return indexes, nil +} + +func (db *oracle) Filters() []core.Filter { + return []core.Filter{&core.QuoteFilter{}, &core.SeqFilter{Prefix: ":", Start: 1}, &core.IdFilter{}} +} + +type goracleDriver struct { +} + +func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { + db := &core.Uri{DbType: core.ORACLE} + dsnPattern := regexp.MustCompile( + `^(?:(?P.*?)(?::(?P.*))?@)?` + // [user[:password]@] + `(?:(?P[^\(]*)(?:\((?P[^\)]*)\))?)?` + // [net[(addr)]] + `\/(?P.*?)` + // /dbname + `(?:\?(?P[^\?]*))?$`) // [?param1=value1¶mN=valueN] + matches := dsnPattern.FindStringSubmatch(dataSourceName) + // tlsConfigRegister := make(map[string]*tls.Config) + names := dsnPattern.SubexpNames() + + for i, match := range matches { + switch names[i] { + case "dbname": + db.DbName = match + } + } + if db.DbName == "" { + return nil, errors.New("dbname is empty") + } + return db, nil +} + +type oci8Driver struct { +} + +// dataSourceName=user/password@ipv4:port/dbname +// dataSourceName=user/password@[ipv6]:port/dbname +func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) { + db := &core.Uri{DbType: core.ORACLE} + dsnPattern := regexp.MustCompile( + `^(?P.*)\/(?P.*)@` + // user:password@ + `(?P.*)` + // ip:port + `\/(?P.*)`) // dbname + matches := dsnPattern.FindStringSubmatch(dataSourceName) + names := dsnPattern.SubexpNames() + for i, match := range matches { + switch names[i] { + case "dbname": + db.DbName = match + } + } + if db.DbName == "" { + return nil, errors.New("dbname is empty") + } + return db, nil +} diff --git a/vendor/xorm.io/xorm/dialect_postgres.go b/vendor/xorm.io/xorm/dialect_postgres.go new file mode 100644 index 0000000000..ccef3086b2 --- /dev/null +++ b/vendor/xorm.io/xorm/dialect_postgres.go @@ -0,0 +1,1253 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "net/url" + "strconv" + "strings" + + "xorm.io/core" +) + +// from http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html +var ( + postgresReservedWords = map[string]bool{ + "A": true, + "ABORT": true, + "ABS": true, + "ABSENT": true, + "ABSOLUTE": true, + "ACCESS": true, + "ACCORDING": true, + "ACTION": true, + "ADA": true, + "ADD": true, + "ADMIN": true, + "AFTER": true, + "AGGREGATE": true, + "ALL": true, + "ALLOCATE": true, + "ALSO": true, + "ALTER": true, + "ALWAYS": true, + "ANALYSE": true, + "ANALYZE": true, + "AND": true, + "ANY": true, + "ARE": true, + "ARRAY": true, + "ARRAY_AGG": true, + "ARRAY_MAX_CARDINALITY": true, + "AS": true, + "ASC": true, + "ASENSITIVE": true, + "ASSERTION": true, + "ASSIGNMENT": true, + "ASYMMETRIC": true, + "AT": true, + "ATOMIC": true, + "ATTRIBUTE": true, + "ATTRIBUTES": true, + "AUTHORIZATION": true, + "AVG": true, + "BACKWARD": true, + "BASE64": true, + "BEFORE": true, + "BEGIN": true, + "BEGIN_FRAME": true, + "BEGIN_PARTITION": true, + "BERNOULLI": true, + "BETWEEN": true, + "BIGINT": true, + "BINARY": true, + "BIT": true, + "BIT_LENGTH": true, + "BLOB": true, + "BLOCKED": true, + "BOM": true, + "BOOLEAN": true, + "BOTH": true, + "BREADTH": true, + "BY": true, + "C": true, + "CACHE": true, + "CALL": true, + "CALLED": true, + "CARDINALITY": true, + "CASCADE": true, + "CASCADED": true, + "CASE": true, + "CAST": true, + "CATALOG": true, + "CATALOG_NAME": true, + "CEIL": true, + "CEILING": true, + "CHAIN": true, + "CHAR": true, + "CHARACTER": true, + "CHARACTERISTICS": true, + "CHARACTERS": true, + "CHARACTER_LENGTH": true, + "CHARACTER_SET_CATALOG": true, + "CHARACTER_SET_NAME": true, + "CHARACTER_SET_SCHEMA": true, + "CHAR_LENGTH": true, + "CHECK": true, + "CHECKPOINT": true, + "CLASS": true, + "CLASS_ORIGIN": true, + "CLOB": true, + "CLOSE": true, + "CLUSTER": true, + "COALESCE": true, + "COBOL": true, + "COLLATE": true, + "COLLATION": true, + "COLLATION_CATALOG": true, + "COLLATION_NAME": true, + "COLLATION_SCHEMA": true, + "COLLECT": true, + "COLUMN": true, + "COLUMNS": true, + "COLUMN_NAME": true, + "COMMAND_FUNCTION": true, + "COMMAND_FUNCTION_CODE": true, + "COMMENT": true, + "COMMENTS": true, + "COMMIT": true, + "COMMITTED": true, + "CONCURRENTLY": true, + "CONDITION": true, + "CONDITION_NUMBER": true, + "CONFIGURATION": true, + "CONNECT": true, + "CONNECTION": true, + "CONNECTION_NAME": true, + "CONSTRAINT": true, + "CONSTRAINTS": true, + "CONSTRAINT_CATALOG": true, + "CONSTRAINT_NAME": true, + "CONSTRAINT_SCHEMA": true, + "CONSTRUCTOR": true, + "CONTAINS": true, + "CONTENT": true, + "CONTINUE": true, + "CONTROL": true, + "CONVERSION": true, + "CONVERT": true, + "COPY": true, + "CORR": true, + "CORRESPONDING": true, + "COST": true, + "COUNT": true, + "COVAR_POP": true, + "COVAR_SAMP": true, + "CREATE": true, + "CROSS": true, + "CSV": true, + "CUBE": true, + "CUME_DIST": true, + "CURRENT": true, + "CURRENT_CATALOG": true, + "CURRENT_DATE": true, + "CURRENT_DEFAULT_TRANSFORM_GROUP": true, + "CURRENT_PATH": true, + "CURRENT_ROLE": true, + "CURRENT_ROW": true, + "CURRENT_SCHEMA": true, + "CURRENT_TIME": true, + "CURRENT_TIMESTAMP": true, + "CURRENT_TRANSFORM_GROUP_FOR_TYPE": true, + "CURRENT_USER": true, + "CURSOR": true, + "CURSOR_NAME": true, + "CYCLE": true, + "DATA": true, + "DATABASE": true, + "DATALINK": true, + "DATE": true, + "DATETIME_INTERVAL_CODE": true, + "DATETIME_INTERVAL_PRECISION": true, + "DAY": true, + "DB": true, + "DEALLOCATE": true, + "DEC": true, + "DECIMAL": true, + "DECLARE": true, + "DEFAULT": true, + "DEFAULTS": true, + "DEFERRABLE": true, + "DEFERRED": true, + "DEFINED": true, + "DEFINER": true, + "DEGREE": true, + "DELETE": true, + "DELIMITER": true, + "DELIMITERS": true, + "DENSE_RANK": true, + "DEPTH": true, + "DEREF": true, + "DERIVED": true, + "DESC": true, + "DESCRIBE": true, + "DESCRIPTOR": true, + "DETERMINISTIC": true, + "DIAGNOSTICS": true, + "DICTIONARY": true, + "DISABLE": true, + "DISCARD": true, + "DISCONNECT": true, + "DISPATCH": true, + "DISTINCT": true, + "DLNEWCOPY": true, + "DLPREVIOUSCOPY": true, + "DLURLCOMPLETE": true, + "DLURLCOMPLETEONLY": true, + "DLURLCOMPLETEWRITE": true, + "DLURLPATH": true, + "DLURLPATHONLY": true, + "DLURLPATHWRITE": true, + "DLURLSCHEME": true, + "DLURLSERVER": true, + "DLVALUE": true, + "DO": true, + "DOCUMENT": true, + "DOMAIN": true, + "DOUBLE": true, + "DROP": true, + "DYNAMIC": true, + "DYNAMIC_FUNCTION": true, + "DYNAMIC_FUNCTION_CODE": true, + "EACH": true, + "ELEMENT": true, + "ELSE": true, + "EMPTY": true, + "ENABLE": true, + "ENCODING": true, + "ENCRYPTED": true, + "END": true, + "END-EXEC": true, + "END_FRAME": true, + "END_PARTITION": true, + "ENFORCED": true, + "ENUM": true, + "EQUALS": true, + "ESCAPE": true, + "EVENT": true, + "EVERY": true, + "EXCEPT": true, + "EXCEPTION": true, + "EXCLUDE": true, + "EXCLUDING": true, + "EXCLUSIVE": true, + "EXEC": true, + "EXECUTE": true, + "EXISTS": true, + "EXP": true, + "EXPLAIN": true, + "EXPRESSION": true, + "EXTENSION": true, + "EXTERNAL": true, + "EXTRACT": true, + "FALSE": true, + "FAMILY": true, + "FETCH": true, + "FILE": true, + "FILTER": true, + "FINAL": true, + "FIRST": true, + "FIRST_VALUE": true, + "FLAG": true, + "FLOAT": true, + "FLOOR": true, + "FOLLOWING": true, + "FOR": true, + "FORCE": true, + "FOREIGN": true, + "FORTRAN": true, + "FORWARD": true, + "FOUND": true, + "FRAME_ROW": true, + "FREE": true, + "FREEZE": true, + "FROM": true, + "FS": true, + "FULL": true, + "FUNCTION": true, + "FUNCTIONS": true, + "FUSION": true, + "G": true, + "GENERAL": true, + "GENERATED": true, + "GET": true, + "GLOBAL": true, + "GO": true, + "GOTO": true, + "GRANT": true, + "GRANTED": true, + "GREATEST": true, + "GROUP": true, + "GROUPING": true, + "GROUPS": true, + "HANDLER": true, + "HAVING": true, + "HEADER": true, + "HEX": true, + "HIERARCHY": true, + "HOLD": true, + "HOUR": true, + "ID": true, + "IDENTITY": true, + "IF": true, + "IGNORE": true, + "ILIKE": true, + "IMMEDIATE": true, + "IMMEDIATELY": true, + "IMMUTABLE": true, + "IMPLEMENTATION": true, + "IMPLICIT": true, + "IMPORT": true, + "IN": true, + "INCLUDING": true, + "INCREMENT": true, + "INDENT": true, + "INDEX": true, + "INDEXES": true, + "INDICATOR": true, + "INHERIT": true, + "INHERITS": true, + "INITIALLY": true, + "INLINE": true, + "INNER": true, + "INOUT": true, + "INPUT": true, + "INSENSITIVE": true, + "INSERT": true, + "INSTANCE": true, + "INSTANTIABLE": true, + "INSTEAD": true, + "INT": true, + "INTEGER": true, + "INTEGRITY": true, + "INTERSECT": true, + "INTERSECTION": true, + "INTERVAL": true, + "INTO": true, + "INVOKER": true, + "IS": true, + "ISNULL": true, + "ISOLATION": true, + "JOIN": true, + "K": true, + "KEY": true, + "KEY_MEMBER": true, + "KEY_TYPE": true, + "LABEL": true, + "LAG": true, + "LANGUAGE": true, + "LARGE": true, + "LAST": true, + "LAST_VALUE": true, + "LATERAL": true, + "LC_COLLATE": true, + "LC_CTYPE": true, + "LEAD": true, + "LEADING": true, + "LEAKPROOF": true, + "LEAST": true, + "LEFT": true, + "LENGTH": true, + "LEVEL": true, + "LIBRARY": true, + "LIKE": true, + "LIKE_REGEX": true, + "LIMIT": true, + "LINK": true, + "LISTEN": true, + "LN": true, + "LOAD": true, + "LOCAL": true, + "LOCALTIME": true, + "LOCALTIMESTAMP": true, + "LOCATION": true, + "LOCATOR": true, + "LOCK": true, + "LOWER": true, + "M": true, + "MAP": true, + "MAPPING": true, + "MATCH": true, + "MATCHED": true, + "MATERIALIZED": true, + "MAX": true, + "MAXVALUE": true, + "MAX_CARDINALITY": true, + "MEMBER": true, + "MERGE": true, + "MESSAGE_LENGTH": true, + "MESSAGE_OCTET_LENGTH": true, + "MESSAGE_TEXT": true, + "METHOD": true, + "MIN": true, + "MINUTE": true, + "MINVALUE": true, + "MOD": true, + "MODE": true, + "MODIFIES": true, + "MODULE": true, + "MONTH": true, + "MORE": true, + "MOVE": true, + "MULTISET": true, + "MUMPS": true, + "NAME": true, + "NAMES": true, + "NAMESPACE": true, + "NATIONAL": true, + "NATURAL": true, + "NCHAR": true, + "NCLOB": true, + "NESTING": true, + "NEW": true, + "NEXT": true, + "NFC": true, + "NFD": true, + "NFKC": true, + "NFKD": true, + "NIL": true, + "NO": true, + "NONE": true, + "NORMALIZE": true, + "NORMALIZED": true, + "NOT": true, + "NOTHING": true, + "NOTIFY": true, + "NOTNULL": true, + "NOWAIT": true, + "NTH_VALUE": true, + "NTILE": true, + "NULL": true, + "NULLABLE": true, + "NULLIF": true, + "NULLS": true, + "NUMBER": true, + "NUMERIC": true, + "OBJECT": true, + "OCCURRENCES_REGEX": true, + "OCTETS": true, + "OCTET_LENGTH": true, + "OF": true, + "OFF": true, + "OFFSET": true, + "OIDS": true, + "OLD": true, + "ON": true, + "ONLY": true, + "OPEN": true, + "OPERATOR": true, + "OPTION": true, + "OPTIONS": true, + "OR": true, + "ORDER": true, + "ORDERING": true, + "ORDINALITY": true, + "OTHERS": true, + "OUT": true, + "OUTER": true, + "OUTPUT": true, + "OVER": true, + "OVERLAPS": true, + "OVERLAY": true, + "OVERRIDING": true, + "OWNED": true, + "OWNER": true, + "P": true, + "PAD": true, + "PARAMETER": true, + "PARAMETER_MODE": true, + "PARAMETER_NAME": true, + "PARAMETER_ORDINAL_POSITION": true, + "PARAMETER_SPECIFIC_CATALOG": true, + "PARAMETER_SPECIFIC_NAME": true, + "PARAMETER_SPECIFIC_SCHEMA": true, + "PARSER": true, + "PARTIAL": true, + "PARTITION": true, + "PASCAL": true, + "PASSING": true, + "PASSTHROUGH": true, + "PASSWORD": true, + "PATH": true, + "PERCENT": true, + "PERCENTILE_CONT": true, + "PERCENTILE_DISC": true, + "PERCENT_RANK": true, + "PERIOD": true, + "PERMISSION": true, + "PLACING": true, + "PLANS": true, + "PLI": true, + "PORTION": true, + "POSITION": true, + "POSITION_REGEX": true, + "POWER": true, + "PRECEDES": true, + "PRECEDING": true, + "PRECISION": true, + "PREPARE": true, + "PREPARED": true, + "PRESERVE": true, + "PRIMARY": true, + "PRIOR": true, + "PRIVILEGES": true, + "PROCEDURAL": true, + "PROCEDURE": true, + "PROGRAM": true, + "PUBLIC": true, + "QUOTE": true, + "RANGE": true, + "RANK": true, + "READ": true, + "READS": true, + "REAL": true, + "REASSIGN": true, + "RECHECK": true, + "RECOVERY": true, + "RECURSIVE": true, + "REF": true, + "REFERENCES": true, + "REFERENCING": true, + "REFRESH": true, + "REGR_AVGX": true, + "REGR_AVGY": true, + "REGR_COUNT": true, + "REGR_INTERCEPT": true, + "REGR_R2": true, + "REGR_SLOPE": true, + "REGR_SXX": true, + "REGR_SXY": true, + "REGR_SYY": true, + "REINDEX": true, + "RELATIVE": true, + "RELEASE": true, + "RENAME": true, + "REPEATABLE": true, + "REPLACE": true, + "REPLICA": true, + "REQUIRING": true, + "RESET": true, + "RESPECT": true, + "RESTART": true, + "RESTORE": true, + "RESTRICT": true, + "RESULT": true, + "RETURN": true, + "RETURNED_CARDINALITY": true, + "RETURNED_LENGTH": true, + "RETURNED_OCTET_LENGTH": true, + "RETURNED_SQLSTATE": true, + "RETURNING": true, + "RETURNS": true, + "REVOKE": true, + "RIGHT": true, + "ROLE": true, + "ROLLBACK": true, + "ROLLUP": true, + "ROUTINE": true, + "ROUTINE_CATALOG": true, + "ROUTINE_NAME": true, + "ROUTINE_SCHEMA": true, + "ROW": true, + "ROWS": true, + "ROW_COUNT": true, + "ROW_NUMBER": true, + "RULE": true, + "SAVEPOINT": true, + "SCALE": true, + "SCHEMA": true, + "SCHEMA_NAME": true, + "SCOPE": true, + "SCOPE_CATALOG": true, + "SCOPE_NAME": true, + "SCOPE_SCHEMA": true, + "SCROLL": true, + "SEARCH": true, + "SECOND": true, + "SECTION": true, + "SECURITY": true, + "SELECT": true, + "SELECTIVE": true, + "SELF": true, + "SENSITIVE": true, + "SEQUENCE": true, + "SEQUENCES": true, + "SERIALIZABLE": true, + "SERVER": true, + "SERVER_NAME": true, + "SESSION": true, + "SESSION_USER": true, + "SET": true, + "SETOF": true, + "SETS": true, + "SHARE": true, + "SHOW": true, + "SIMILAR": true, + "SIMPLE": true, + "SIZE": true, + "SMALLINT": true, + "SNAPSHOT": true, + "SOME": true, + "SOURCE": true, + "SPACE": true, + "SPECIFIC": true, + "SPECIFICTYPE": true, + "SPECIFIC_NAME": true, + "SQL": true, + "SQLCODE": true, + "SQLERROR": true, + "SQLEXCEPTION": true, + "SQLSTATE": true, + "SQLWARNING": true, + "SQRT": true, + "STABLE": true, + "STANDALONE": true, + "START": true, + "STATE": true, + "STATEMENT": true, + "STATIC": true, + "STATISTICS": true, + "STDDEV_POP": true, + "STDDEV_SAMP": true, + "STDIN": true, + "STDOUT": true, + "STORAGE": true, + "STRICT": true, + "STRIP": true, + "STRUCTURE": true, + "STYLE": true, + "SUBCLASS_ORIGIN": true, + "SUBMULTISET": true, + "SUBSTRING": true, + "SUBSTRING_REGEX": true, + "SUCCEEDS": true, + "SUM": true, + "SYMMETRIC": true, + "SYSID": true, + "SYSTEM": true, + "SYSTEM_TIME": true, + "SYSTEM_USER": true, + "T": true, + "TABLE": true, + "TABLES": true, + "TABLESAMPLE": true, + "TABLESPACE": true, + "TABLE_NAME": true, + "TEMP": true, + "TEMPLATE": true, + "TEMPORARY": true, + "TEXT": true, + "THEN": true, + "TIES": true, + "TIME": true, + "TIMESTAMP": true, + "TIMEZONE_HOUR": true, + "TIMEZONE_MINUTE": true, + "TO": true, + "TOKEN": true, + "TOP_LEVEL_COUNT": true, + "TRAILING": true, + "TRANSACTION": true, + "TRANSACTIONS_COMMITTED": true, + "TRANSACTIONS_ROLLED_BACK": true, + "TRANSACTION_ACTIVE": true, + "TRANSFORM": true, + "TRANSFORMS": true, + "TRANSLATE": true, + "TRANSLATE_REGEX": true, + "TRANSLATION": true, + "TREAT": true, + "TRIGGER": true, + "TRIGGER_CATALOG": true, + "TRIGGER_NAME": true, + "TRIGGER_SCHEMA": true, + "TRIM": true, + "TRIM_ARRAY": true, + "TRUE": true, + "TRUNCATE": true, + "TRUSTED": true, + "TYPE": true, + "TYPES": true, + "UESCAPE": true, + "UNBOUNDED": true, + "UNCOMMITTED": true, + "UNDER": true, + "UNENCRYPTED": true, + "UNION": true, + "UNIQUE": true, + "UNKNOWN": true, + "UNLINK": true, + "UNLISTEN": true, + "UNLOGGED": true, + "UNNAMED": true, + "UNNEST": true, + "UNTIL": true, + "UNTYPED": true, + "UPDATE": true, + "UPPER": true, + "URI": true, + "USAGE": true, + "USER": true, + "USER_DEFINED_TYPE_CATALOG": true, + "USER_DEFINED_TYPE_CODE": true, + "USER_DEFINED_TYPE_NAME": true, + "USER_DEFINED_TYPE_SCHEMA": true, + "USING": true, + "VACUUM": true, + "VALID": true, + "VALIDATE": true, + "VALIDATOR": true, + "VALUE": true, + "VALUES": true, + "VALUE_OF": true, + "VARBINARY": true, + "VARCHAR": true, + "VARIADIC": true, + "VARYING": true, + "VAR_POP": true, + "VAR_SAMP": true, + "VERBOSE": true, + "VERSION": true, + "VERSIONING": true, + "VIEW": true, + "VOLATILE": true, + "WHEN": true, + "WHENEVER": true, + "WHERE": true, + "WHITESPACE": true, + "WIDTH_BUCKET": true, + "WINDOW": true, + "WITH": true, + "WITHIN": true, + "WITHOUT": true, + "WORK": true, + "WRAPPER": true, + "WRITE": true, + "XML": true, + "XMLAGG": true, + "XMLATTRIBUTES": true, + "XMLBINARY": true, + "XMLCAST": true, + "XMLCOMMENT": true, + "XMLCONCAT": true, + "XMLDECLARATION": true, + "XMLDOCUMENT": true, + "XMLELEMENT": true, + "XMLEXISTS": true, + "XMLFOREST": true, + "XMLITERATE": true, + "XMLNAMESPACES": true, + "XMLPARSE": true, + "XMLPI": true, + "XMLQUERY": true, + "XMLROOT": true, + "XMLSCHEMA": true, + "XMLSERIALIZE": true, + "XMLTABLE": true, + "XMLTEXT": true, + "XMLVALIDATE": true, + "YEAR": true, + "YES": true, + "ZONE": true, + } + + // DefaultPostgresSchema default postgres schema + DefaultPostgresSchema = "public" +) + +const postgresPublicSchema = "public" + +type postgres struct { + core.Base +} + +func (db *postgres) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { + err := db.Base.Init(d, db, uri, drivername, dataSourceName) + if err != nil { + return err + } + if db.Schema == "" { + db.Schema = DefaultPostgresSchema + } + return nil +} + +func (db *postgres) SqlType(c *core.Column) string { + var res string + switch t := c.SQLType.Name; t { + case core.TinyInt: + res = core.SmallInt + return res + case core.Bit: + res = core.Boolean + return res + case core.MediumInt, core.Int, core.Integer: + if c.IsAutoIncrement { + return core.Serial + } + return core.Integer + case core.BigInt: + if c.IsAutoIncrement { + return core.BigSerial + } + return core.BigInt + case core.Serial, core.BigSerial: + c.IsAutoIncrement = true + c.Nullable = false + res = t + case core.Binary, core.VarBinary: + return core.Bytea + case core.DateTime: + res = core.TimeStamp + case core.TimeStampz: + return "timestamp with time zone" + case core.Float: + res = core.Real + case core.TinyText, core.MediumText, core.LongText: + res = core.Text + case core.NVarchar: + res = core.Varchar + case core.Uuid: + return core.Uuid + case core.Blob, core.TinyBlob, core.MediumBlob, core.LongBlob: + return core.Bytea + case core.Double: + return "DOUBLE PRECISION" + default: + if c.IsAutoIncrement { + return core.Serial + } + res = t + } + + if strings.EqualFold(res, "bool") { + // for bool, we don't need length information + return res + } + hasLen1 := (c.Length > 0) + hasLen2 := (c.Length2 > 0) + + if hasLen2 { + res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")" + } else if hasLen1 { + res += "(" + strconv.Itoa(c.Length) + ")" + } + return res +} + +func (db *postgres) SupportInsertMany() bool { + return true +} + +func (db *postgres) IsReserved(name string) bool { + _, ok := postgresReservedWords[name] + return ok +} + +func (db *postgres) Quote(name string) string { + name = strings.Replace(name, ".", `"."`, -1) + return "\"" + name + "\"" +} + +func (db *postgres) AutoIncrStr() string { + return "" +} + +func (db *postgres) SupportEngine() bool { + return false +} + +func (db *postgres) SupportCharset() bool { + return false +} + +func (db *postgres) IndexOnTable() bool { + return false +} + +func (db *postgres) IndexCheckSql(tableName, idxName string) (string, []interface{}) { + if len(db.Schema) == 0 { + args := []interface{}{tableName, idxName} + return `SELECT indexname FROM pg_indexes WHERE tablename = ? AND indexname = ?`, args + } + + args := []interface{}{db.Schema, tableName, idxName} + return `SELECT indexname FROM pg_indexes ` + + `WHERE schemaname = ? AND tablename = ? AND indexname = ?`, args +} + +func (db *postgres) TableCheckSql(tableName string) (string, []interface{}) { + if len(db.Schema) == 0 { + args := []interface{}{tableName} + return `SELECT tablename FROM pg_tables WHERE tablename = ?`, args + } + + args := []interface{}{db.Schema, tableName} + return `SELECT tablename FROM pg_tables WHERE schemaname = ? AND tablename = ?`, args +} + +func (db *postgres) ModifyColumnSql(tableName string, col *core.Column) string { + if len(db.Schema) == 0 { + return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s", + tableName, col.Name, db.SqlType(col)) + } + return fmt.Sprintf("alter table %s.%s ALTER COLUMN %s TYPE %s", + db.Schema, tableName, col.Name, db.SqlType(col)) +} + +func (db *postgres) DropIndexSql(tableName string, index *core.Index) string { + quote := db.Quote + idxName := index.Name + + tableName = strings.Replace(tableName, `"`, "", -1) + tableName = strings.Replace(tableName, `.`, "_", -1) + + if !strings.HasPrefix(idxName, "UQE_") && + !strings.HasPrefix(idxName, "IDX_") { + if index.Type == core.UniqueType { + idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name) + } else { + idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) + } + } + if db.Uri.Schema != "" { + idxName = db.Uri.Schema + "." + idxName + } + return fmt.Sprintf("DROP INDEX %v", quote(idxName)) +} + +func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) { + args := []interface{}{db.Schema, tableName, colName} + query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = $1 AND table_name = $2" + + " AND column_name = $3" + if len(db.Schema) == 0 { + args = []interface{}{tableName, colName} + query = "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" + + " AND column_name = $2" + } + db.LogSQL(query, args) + + rows, err := db.DB().Query(query, args...) + if err != nil { + return false, err + } + defer rows.Close() + + return rows.Next(), nil +} + +func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { + args := []interface{}{tableName} + s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, + CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey, + CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey +FROM pg_attribute f + JOIN pg_class c ON c.oid = f.attrelid JOIN pg_type t ON t.oid = f.atttypid + LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey) + LEFT JOIN pg_class AS g ON p.confrelid = g.oid + LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name +WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.attnum;` + + var f string + if len(db.Schema) != 0 { + args = append(args, db.Schema) + f = " AND s.table_schema = $2" + } + s = fmt.Sprintf(s, f) + + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, nil, err + } + defer rows.Close() + + cols := make(map[string]*core.Column) + colSeq := make([]string, 0) + + for rows.Next() { + col := new(core.Column) + col.Indexes = make(map[string]int) + + var colName, isNullable, dataType string + var maxLenStr, colDefault *string + var isPK, isUnique bool + err = rows.Scan(&colName, &colDefault, &isNullable, &dataType, &maxLenStr, &isPK, &isUnique) + if err != nil { + return nil, nil, err + } + + // fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, isPK, isUnique) + var maxLen int + if maxLenStr != nil { + maxLen, err = strconv.Atoi(*maxLenStr) + if err != nil { + return nil, nil, err + } + } + + col.Name = strings.Trim(colName, `" `) + + if colDefault != nil { + col.Default = *colDefault + col.DefaultIsEmpty = false + if strings.HasPrefix(col.Default, "nextval(") { + col.IsAutoIncrement = true + } + } else { + col.DefaultIsEmpty = true + } + + if isPK { + col.IsPrimaryKey = true + } + + col.Nullable = (isNullable == "YES") + + switch dataType { + case "character varying", "character": + col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: 0, DefaultLength2: 0} + case "timestamp without time zone": + col.SQLType = core.SQLType{Name: core.DateTime, DefaultLength: 0, DefaultLength2: 0} + case "timestamp with time zone": + col.SQLType = core.SQLType{Name: core.TimeStampz, DefaultLength: 0, DefaultLength2: 0} + case "double precision": + col.SQLType = core.SQLType{Name: core.Double, DefaultLength: 0, DefaultLength2: 0} + case "boolean": + col.SQLType = core.SQLType{Name: core.Bool, DefaultLength: 0, DefaultLength2: 0} + case "time without time zone": + col.SQLType = core.SQLType{Name: core.Time, DefaultLength: 0, DefaultLength2: 0} + case "oid": + col.SQLType = core.SQLType{Name: core.BigInt, DefaultLength: 0, DefaultLength2: 0} + default: + col.SQLType = core.SQLType{Name: strings.ToUpper(dataType), DefaultLength: 0, DefaultLength2: 0} + } + if _, ok := core.SqlTypes[col.SQLType.Name]; !ok { + return nil, nil, fmt.Errorf("Unknown colType: %v", dataType) + } + + col.Length = maxLen + + if !col.DefaultIsEmpty { + if col.SQLType.IsText() { + if strings.HasSuffix(col.Default, "::character varying") { + col.Default = strings.TrimRight(col.Default, "::character varying") + } else if !strings.HasPrefix(col.Default, "'") { + col.Default = "'" + col.Default + "'" + } + } else if col.SQLType.IsTime() { + if strings.HasSuffix(col.Default, "::timestamp without time zone") { + col.Default = strings.TrimRight(col.Default, "::timestamp without time zone") + } + } + } + cols[col.Name] = col + colSeq = append(colSeq, col.Name) + } + + return colSeq, cols, nil +} + +func (db *postgres) GetTables() ([]*core.Table, error) { + args := []interface{}{} + s := "SELECT tablename FROM pg_tables" + if len(db.Schema) != 0 { + args = append(args, db.Schema) + s = s + " WHERE schemaname = $1" + } + + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + tables := make([]*core.Table, 0) + for rows.Next() { + table := core.NewEmptyTable() + var name string + err = rows.Scan(&name) + if err != nil { + return nil, err + } + table.Name = name + tables = append(tables, table) + } + return tables, nil +} + +func getIndexColName(indexdef string) []string { + var colNames []string + + cs := strings.Split(indexdef, "(") + for _, v := range strings.Split(strings.Split(cs[1], ")")[0], ",") { + colNames = append(colNames, strings.Split(strings.TrimLeft(v, " "), " ")[0]) + } + + return colNames +} + +func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) { + args := []interface{}{tableName} + s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1") + if len(db.Schema) != 0 { + args = append(args, db.Schema) + s = s + " AND schemaname=$2" + } + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + indexes := make(map[string]*core.Index, 0) + for rows.Next() { + var indexType int + var indexName, indexdef string + var colNames []string + err = rows.Scan(&indexName, &indexdef) + if err != nil { + return nil, err + } + indexName = strings.Trim(indexName, `" `) + if strings.HasSuffix(indexName, "_pkey") { + continue + } + if strings.HasPrefix(indexdef, "CREATE UNIQUE INDEX") { + indexType = core.UniqueType + } else { + indexType = core.IndexType + } + colNames = getIndexColName(indexdef) + var isRegular bool + if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { + newIdxName := indexName[5+len(tableName):] + isRegular = true + if newIdxName != "" { + indexName = newIdxName + } + } + + index := &core.Index{Name: indexName, Type: indexType, Cols: make([]string, 0)} + for _, colName := range colNames { + index.Cols = append(index.Cols, strings.Trim(colName, `" `)) + } + index.IsRegular = isRegular + indexes[index.Name] = index + } + return indexes, nil +} + +func (db *postgres) Filters() []core.Filter { + return []core.Filter{&core.IdFilter{}, &core.QuoteFilter{}, &core.SeqFilter{Prefix: "$", Start: 1}} +} + +type pqDriver struct { +} + +type values map[string]string + +func (vs values) Set(k, v string) { + vs[k] = v +} + +func (vs values) Get(k string) (v string) { + return vs[k] +} + +func parseURL(connstr string) (string, error) { + u, err := url.Parse(connstr) + if err != nil { + return "", err + } + + if u.Scheme != "postgresql" && u.Scheme != "postgres" { + return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) + } + + escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`) + + if u.Path != "" { + return escaper.Replace(u.Path[1:]), nil + } + + return "", nil +} + +func parseOpts(name string, o values) error { + if len(name) == 0 { + return fmt.Errorf("invalid options: %s", name) + } + + name = strings.TrimSpace(name) + + ps := strings.Split(name, " ") + for _, p := range ps { + kv := strings.Split(p, "=") + if len(kv) < 2 { + return fmt.Errorf("invalid option: %q", p) + } + o.Set(kv[0], kv[1]) + } + + return nil +} + +func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) { + db := &core.Uri{DbType: core.POSTGRES} + var err error + + if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") { + db.DbName, err = parseURL(dataSourceName) + if err != nil { + return nil, err + } + } else { + o := make(values) + err = parseOpts(dataSourceName, o) + if err != nil { + return nil, err + } + + db.DbName = o.Get("dbname") + } + + if db.DbName == "" { + return nil, errors.New("dbname is empty") + } + + return db, nil +} + +type pqDriverPgx struct { + pqDriver +} + +func (pgx *pqDriverPgx) Parse(driverName, dataSourceName string) (*core.Uri, error) { + // Remove the leading characters for driver to work + if len(dataSourceName) >= 9 && dataSourceName[0] == 0 { + dataSourceName = dataSourceName[9:] + } + return pgx.pqDriver.Parse(driverName, dataSourceName) +} diff --git a/vendor/xorm.io/xorm/dialect_sqlite3.go b/vendor/xorm.io/xorm/dialect_sqlite3.go new file mode 100644 index 0000000000..0a290f3c48 --- /dev/null +++ b/vendor/xorm.io/xorm/dialect_sqlite3.go @@ -0,0 +1,492 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "errors" + "fmt" + "regexp" + "strings" + + "xorm.io/core" +) + +var ( + sqlite3ReservedWords = map[string]bool{ + "ABORT": true, + "ACTION": true, + "ADD": true, + "AFTER": true, + "ALL": true, + "ALTER": true, + "ANALYZE": true, + "AND": true, + "AS": true, + "ASC": true, + "ATTACH": true, + "AUTOINCREMENT": true, + "BEFORE": true, + "BEGIN": true, + "BETWEEN": true, + "BY": true, + "CASCADE": true, + "CASE": true, + "CAST": true, + "CHECK": true, + "COLLATE": true, + "COLUMN": true, + "COMMIT": true, + "CONFLICT": true, + "CONSTRAINT": true, + "CREATE": true, + "CROSS": true, + "CURRENT_DATE": true, + "CURRENT_TIME": true, + "CURRENT_TIMESTAMP": true, + "DATABASE": true, + "DEFAULT": true, + "DEFERRABLE": true, + "DEFERRED": true, + "DELETE": true, + "DESC": true, + "DETACH": true, + "DISTINCT": true, + "DROP": true, + "EACH": true, + "ELSE": true, + "END": true, + "ESCAPE": true, + "EXCEPT": true, + "EXCLUSIVE": true, + "EXISTS": true, + "EXPLAIN": true, + "FAIL": true, + "FOR": true, + "FOREIGN": true, + "FROM": true, + "FULL": true, + "GLOB": true, + "GROUP": true, + "HAVING": true, + "IF": true, + "IGNORE": true, + "IMMEDIATE": true, + "IN": true, + "INDEX": true, + "INDEXED": true, + "INITIALLY": true, + "INNER": true, + "INSERT": true, + "INSTEAD": true, + "INTERSECT": true, + "INTO": true, + "IS": true, + "ISNULL": true, + "JOIN": true, + "KEY": true, + "LEFT": true, + "LIKE": true, + "LIMIT": true, + "MATCH": true, + "NATURAL": true, + "NO": true, + "NOT": true, + "NOTNULL": true, + "NULL": true, + "OF": true, + "OFFSET": true, + "ON": true, + "OR": true, + "ORDER": true, + "OUTER": true, + "PLAN": true, + "PRAGMA": true, + "PRIMARY": true, + "QUERY": true, + "RAISE": true, + "RECURSIVE": true, + "REFERENCES": true, + "REGEXP": true, + "REINDEX": true, + "RELEASE": true, + "RENAME": true, + "REPLACE": true, + "RESTRICT": true, + "RIGHT": true, + "ROLLBACK": true, + "ROW": true, + "SAVEPOINT": true, + "SELECT": true, + "SET": true, + "TABLE": true, + "TEMP": true, + "TEMPORARY": true, + "THEN": true, + "TO": true, + "TRANSACTI": true, + "TRIGGER": true, + "UNION": true, + "UNIQUE": true, + "UPDATE": true, + "USING": true, + "VACUUM": true, + "VALUES": true, + "VIEW": true, + "VIRTUAL": true, + "WHEN": true, + "WHERE": true, + "WITH": true, + "WITHOUT": true, + } +) + +type sqlite3 struct { + core.Base +} + +func (db *sqlite3) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error { + return db.Base.Init(d, db, uri, drivername, dataSourceName) +} + +func (db *sqlite3) SqlType(c *core.Column) string { + switch t := c.SQLType.Name; t { + case core.Bool: + if c.Default == "true" { + c.Default = "1" + } else if c.Default == "false" { + c.Default = "0" + } + return core.Integer + case core.Date, core.DateTime, core.TimeStamp, core.Time: + return core.DateTime + case core.TimeStampz: + return core.Text + case core.Char, core.Varchar, core.NVarchar, core.TinyText, + core.Text, core.MediumText, core.LongText, core.Json: + return core.Text + case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt: + return core.Integer + case core.Float, core.Double, core.Real: + return core.Real + case core.Decimal, core.Numeric: + return core.Numeric + case core.TinyBlob, core.Blob, core.MediumBlob, core.LongBlob, core.Bytea, core.Binary, core.VarBinary: + return core.Blob + case core.Serial, core.BigSerial: + c.IsPrimaryKey = true + c.IsAutoIncrement = true + c.Nullable = false + return core.Integer + default: + return t + } +} + +func (db *sqlite3) FormatBytes(bs []byte) string { + return fmt.Sprintf("X'%x'", bs) +} + +func (db *sqlite3) SupportInsertMany() bool { + return true +} + +func (db *sqlite3) IsReserved(name string) bool { + _, ok := sqlite3ReservedWords[name] + return ok +} + +func (db *sqlite3) Quote(name string) string { + return "`" + name + "`" +} + +func (db *sqlite3) AutoIncrStr() string { + return "AUTOINCREMENT" +} + +func (db *sqlite3) SupportEngine() bool { + return false +} + +func (db *sqlite3) SupportCharset() bool { + return false +} + +func (db *sqlite3) IndexOnTable() bool { + return false +} + +func (db *sqlite3) IndexCheckSql(tableName, idxName string) (string, []interface{}) { + args := []interface{}{idxName} + return "SELECT name FROM sqlite_master WHERE type='index' and name = ?", args +} + +func (db *sqlite3) TableCheckSql(tableName string) (string, []interface{}) { + args := []interface{}{tableName} + return "SELECT name FROM sqlite_master WHERE type='table' and name = ?", args +} + +func (db *sqlite3) DropIndexSql(tableName string, index *core.Index) string { + // var unique string + quote := db.Quote + idxName := index.Name + + if !strings.HasPrefix(idxName, "UQE_") && + !strings.HasPrefix(idxName, "IDX_") { + if index.Type == core.UniqueType { + idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name) + } else { + idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) + } + } + return fmt.Sprintf("DROP INDEX %v", quote(idxName)) +} + +func (db *sqlite3) ForUpdateSql(query string) string { + return query +} + +/*func (db *sqlite3) ColumnCheckSql(tableName, colName string) (string, []interface{}) { + args := []interface{}{tableName} + sql := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))" + return sql, args +}*/ + +func (db *sqlite3) IsColumnExist(tableName, colName string) (bool, error) { + args := []interface{}{tableName} + query := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))" + db.LogSQL(query, args) + rows, err := db.DB().Query(query, args...) + if err != nil { + return false, err + } + defer rows.Close() + + if rows.Next() { + return true, nil + } + return false, nil +} + +// splitColStr splits a sqlite col strings as fields +func splitColStr(colStr string) []string { + colStr = strings.TrimSpace(colStr) + var results = make([]string, 0, 10) + var lastIdx int + var hasC, hasQuote bool + for i, c := range colStr { + if c == ' ' && !hasQuote { + if hasC { + results = append(results, colStr[lastIdx:i]) + hasC = false + } + } else { + if c == '\'' { + hasQuote = !hasQuote + } + if !hasC { + lastIdx = i + } + hasC = true + if i == len(colStr)-1 { + results = append(results, colStr[lastIdx:i+1]) + } + } + } + return results +} + +func parseString(colStr string) (*core.Column, error) { + fields := splitColStr(colStr) + col := new(core.Column) + col.Indexes = make(map[string]int) + col.Nullable = true + col.DefaultIsEmpty = true + + for idx, field := range fields { + if idx == 0 { + col.Name = strings.Trim(strings.Trim(field, "`[] "), `"`) + continue + } else if idx == 1 { + col.SQLType = core.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0} + continue + } + switch field { + case "PRIMARY": + col.IsPrimaryKey = true + case "AUTOINCREMENT": + col.IsAutoIncrement = true + case "NULL": + if fields[idx-1] == "NOT" { + col.Nullable = false + } else { + col.Nullable = true + } + case "DEFAULT": + col.Default = fields[idx+1] + col.DefaultIsEmpty = false + } + } + return col, nil +} + +func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { + args := []interface{}{tableName} + s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?" + db.LogSQL(s, args) + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, nil, err + } + defer rows.Close() + + var name string + for rows.Next() { + err = rows.Scan(&name) + if err != nil { + return nil, nil, err + } + break + } + + if name == "" { + return nil, nil, errors.New("no table named " + tableName) + } + + nStart := strings.Index(name, "(") + nEnd := strings.LastIndex(name, ")") + reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`) + colCreates := reg.FindAllString(name[nStart+1:nEnd], -1) + cols := make(map[string]*core.Column) + colSeq := make([]string, 0) + + for _, colStr := range colCreates { + reg = regexp.MustCompile(`,\s`) + colStr = reg.ReplaceAllString(colStr, ",") + if strings.HasPrefix(strings.TrimSpace(colStr), "PRIMARY KEY") { + parts := strings.Split(strings.TrimSpace(colStr), "(") + if len(parts) == 2 { + pkCols := strings.Split(strings.TrimRight(strings.TrimSpace(parts[1]), ")"), ",") + for _, pk := range pkCols { + if col, ok := cols[strings.Trim(strings.TrimSpace(pk), "`")]; ok { + col.IsPrimaryKey = true + } + } + } + continue + } + + col, err := parseString(colStr) + if err != nil { + return colSeq, cols, err + } + + cols[col.Name] = col + colSeq = append(colSeq, col.Name) + } + return colSeq, cols, nil +} + +func (db *sqlite3) GetTables() ([]*core.Table, error) { + args := []interface{}{} + s := "SELECT name FROM sqlite_master WHERE type='table'" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + tables := make([]*core.Table, 0) + for rows.Next() { + table := core.NewEmptyTable() + err = rows.Scan(&table.Name) + if err != nil { + return nil, err + } + if table.Name == "sqlite_sequence" { + continue + } + tables = append(tables, table) + } + return tables, nil +} + +func (db *sqlite3) GetIndexes(tableName string) (map[string]*core.Index, error) { + args := []interface{}{tableName} + s := "SELECT sql FROM sqlite_master WHERE type='index' and tbl_name = ?" + db.LogSQL(s, args) + + rows, err := db.DB().Query(s, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + indexes := make(map[string]*core.Index, 0) + for rows.Next() { + var tmpSQL sql.NullString + err = rows.Scan(&tmpSQL) + if err != nil { + return nil, err + } + + if !tmpSQL.Valid { + continue + } + sql := tmpSQL.String + + index := new(core.Index) + nNStart := strings.Index(sql, "INDEX") + nNEnd := strings.Index(sql, "ON") + if nNStart == -1 || nNEnd == -1 { + continue + } + + indexName := strings.Trim(sql[nNStart+6:nNEnd], "` []") + var isRegular bool + if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { + index.Name = indexName[5+len(tableName):] + isRegular = true + } else { + index.Name = indexName + } + + if strings.HasPrefix(sql, "CREATE UNIQUE INDEX") { + index.Type = core.UniqueType + } else { + index.Type = core.IndexType + } + + nStart := strings.Index(sql, "(") + nEnd := strings.Index(sql, ")") + colIndexes := strings.Split(sql[nStart+1:nEnd], ",") + + index.Cols = make([]string, 0) + for _, col := range colIndexes { + index.Cols = append(index.Cols, strings.Trim(col, "` []")) + } + index.IsRegular = isRegular + indexes[index.Name] = index + } + + return indexes, nil +} + +func (db *sqlite3) Filters() []core.Filter { + return []core.Filter{&core.IdFilter{}} +} + +type sqlite3Driver struct { +} + +func (p *sqlite3Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) { + if strings.Contains(dataSourceName, "?") { + dataSourceName = dataSourceName[:strings.Index(dataSourceName, "?")] + } + + return &core.Uri{DbType: core.SQLITE, DbName: dataSourceName}, nil +} diff --git a/vendor/xorm.io/xorm/doc.go b/vendor/xorm.io/xorm/doc.go new file mode 100644 index 0000000000..9620bca19f --- /dev/null +++ b/vendor/xorm.io/xorm/doc.go @@ -0,0 +1,184 @@ +// Copyright 2013 - 2016 The XORM Authors. All rights reserved. +// Use of this source code is governed by a BSD +// license that can be found in the LICENSE file. + +/* + +Package xorm is a simple and powerful ORM for Go. + +Installation + +Make sure you have installed Go 1.6+ and then: + + go get xorm.io/xorm + +Create Engine + +Firstly, we should new an engine for a database + + engine, err := xorm.NewEngine(driverName, dataSourceName) + +Method NewEngine's parameters is the same as sql.Open. It depends +drivers' implementation. +Generally, one engine for an application is enough. You can set it as package variable. + +Raw Methods + +XORM also support raw SQL execution: + +1. query a SQL string, the returned results is []map[string][]byte + + results, err := engine.Query("select * from user") + +2. execute a SQL string, the returned results + + affected, err := engine.Exec("update user set .... where ...") + +ORM Methods + +There are 8 major ORM methods and many helpful methods to use to operate database. + +1. Insert one or multiple records to database + + affected, err := engine.Insert(&struct) + // INSERT INTO struct () values () + affected, err := engine.Insert(&struct1, &struct2) + // INSERT INTO struct1 () values () + // INSERT INTO struct2 () values () + affected, err := engine.Insert(&sliceOfStruct) + // INSERT INTO struct () values (),(),() + affected, err := engine.Insert(&struct1, &sliceOfStruct2) + // INSERT INTO struct1 () values () + // INSERT INTO struct2 () values (),(),() + +2. Query one record or one variable from database + + has, err := engine.Get(&user) + // SELECT * FROM user LIMIT 1 + + var id int64 + has, err := engine.Table("user").Where("name = ?", name).Get(&id) + // SELECT id FROM user WHERE name = ? LIMIT 1 + +3. Query multiple records from database + + var sliceOfStructs []Struct + err := engine.Find(&sliceOfStructs) + // SELECT * FROM user + + var mapOfStructs = make(map[int64]Struct) + err := engine.Find(&mapOfStructs) + // SELECT * FROM user + + var int64s []int64 + err := engine.Table("user").Cols("id").Find(&int64s) + // SELECT id FROM user + +4. Query multiple records and record by record handle, there two methods, one is Iterate, +another is Rows + + err := engine.Iterate(...) + // SELECT * FROM user + + rows, err := engine.Rows(...) + // SELECT * FROM user + defer rows.Close() + bean := new(Struct) + for rows.Next() { + err = rows.Scan(bean) + } + +5. Update one or more records + + affected, err := engine.ID(...).Update(&user) + // UPDATE user SET ... + +6. Delete one or more records, Delete MUST has condition + + affected, err := engine.Where(...).Delete(&user) + // DELETE FROM user Where ... + +7. Count records + + counts, err := engine.Count(&user) + // SELECT count(*) AS total FROM user + + counts, err := engine.SQL("select count(*) FROM user").Count() + // select count(*) FROM user + +8. Sum records + + sumFloat64, err := engine.Sum(&user, "id") + // SELECT sum(id) from user + + sumFloat64s, err := engine.Sums(&user, "id1", "id2") + // SELECT sum(id1), sum(id2) from user + + sumInt64s, err := engine.SumsInt(&user, "id1", "id2") + // SELECT sum(id1), sum(id2) from user + +Conditions + +The above 8 methods could use with condition methods chainable. +Attention: the above 8 methods should be the last chainable method. + +1. ID, In + + engine.ID(1).Get(&user) // for single primary key + // SELECT * FROM user WHERE id = 1 + engine.ID(core.PK{1, 2}).Get(&user) // for composite primary keys + // SELECT * FROM user WHERE id1 = 1 AND id2 = 2 + engine.In("id", 1, 2, 3).Find(&users) + // SELECT * FROM user WHERE id IN (1, 2, 3) + engine.In("id", []int{1, 2, 3}).Find(&users) + // SELECT * FROM user WHERE id IN (1, 2, 3) + +2. Where, And, Or + + engine.Where().And().Or().Find() + // SELECT * FROM user WHERE (.. AND ..) OR ... + +3. OrderBy, Asc, Desc + + engine.Asc().Desc().Find() + // SELECT * FROM user ORDER BY .. ASC, .. DESC + engine.OrderBy().Find() + // SELECT * FROM user ORDER BY .. + +4. Limit, Top + + engine.Limit().Find() + // SELECT * FROM user LIMIT .. OFFSET .. + engine.Top(5).Find() + // SELECT TOP 5 * FROM user // for mssql + // SELECT * FROM user LIMIT .. OFFSET 0 //for other databases + +5. SQL, let you custom SQL + + var users []User + engine.SQL("select * from user").Find(&users) + +6. Cols, Omit, Distinct + + var users []*User + engine.Cols("col1, col2").Find(&users) + // SELECT col1, col2 FROM user + engine.Cols("col1", "col2").Where().Update(user) + // UPDATE user set col1 = ?, col2 = ? Where ... + engine.Omit("col1").Find(&users) + // SELECT col2, col3 FROM user + engine.Omit("col1").Insert(&user) + // INSERT INTO table (non-col1) VALUES () + engine.Distinct("col1").Find(&users) + // SELECT DISTINCT col1 FROM user + +7. Join, GroupBy, Having + + engine.GroupBy("name").Having("name='xlw'").Find(&users) + //SELECT * FROM user GROUP BY name HAVING name='xlw' + engine.Join("LEFT", "userdetail", "user.id=userdetail.id").Find(&users) + //SELECT * FROM user LEFT JOIN userdetail ON user.id=userdetail.id + +More usage, please visit http://xorm.io/docs +*/ +package xorm diff --git a/vendor/xorm.io/xorm/engine.go b/vendor/xorm.io/xorm/engine.go new file mode 100644 index 0000000000..4ed0f77a92 --- /dev/null +++ b/vendor/xorm.io/xorm/engine.go @@ -0,0 +1,1659 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "bufio" + "bytes" + "context" + "database/sql" + "encoding/gob" + "errors" + "fmt" + "io" + "os" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "xorm.io/builder" + "xorm.io/core" +) + +// Engine is the major struct of xorm, it means a database manager. +// Commonly, an application only need one engine +type Engine struct { + db *core.DB + dialect core.Dialect + + ColumnMapper core.IMapper + TableMapper core.IMapper + TagIdentifier string + Tables map[reflect.Type]*core.Table + + mutex *sync.RWMutex + Cacher core.Cacher + + showSQL bool + showExecTime bool + + logger core.ILogger + TZLocation *time.Location // The timezone of the application + DatabaseTZ *time.Location // The timezone of the database + + disableGlobalCache bool + + tagHandlers map[string]tagHandler + + engineGroup *EngineGroup + + cachers map[string]core.Cacher + cacherLock sync.RWMutex + + defaultContext context.Context +} + +func (engine *Engine) setCacher(tableName string, cacher core.Cacher) { + engine.cacherLock.Lock() + engine.cachers[tableName] = cacher + engine.cacherLock.Unlock() +} + +func (engine *Engine) SetCacher(tableName string, cacher core.Cacher) { + engine.setCacher(tableName, cacher) +} + +func (engine *Engine) getCacher(tableName string) core.Cacher { + var cacher core.Cacher + var ok bool + engine.cacherLock.RLock() + cacher, ok = engine.cachers[tableName] + engine.cacherLock.RUnlock() + if !ok && !engine.disableGlobalCache { + cacher = engine.Cacher + } + return cacher +} + +func (engine *Engine) GetCacher(tableName string) core.Cacher { + return engine.getCacher(tableName) +} + +// BufferSize sets buffer size for iterate +func (engine *Engine) BufferSize(size int) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.BufferSize(size) +} + +// CondDeleted returns the conditions whether a record is soft deleted. +func (engine *Engine) CondDeleted(colName string) builder.Cond { + if engine.dialect.DBType() == core.MSSQL { + return builder.IsNull{colName} + } + return builder.IsNull{colName}.Or(builder.Eq{colName: zeroTime1}) +} + +// ShowSQL show SQL statement or not on logger if log level is great than INFO +func (engine *Engine) ShowSQL(show ...bool) { + engine.logger.ShowSQL(show...) + if len(show) == 0 { + engine.showSQL = true + } else { + engine.showSQL = show[0] + } +} + +// ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO +func (engine *Engine) ShowExecTime(show ...bool) { + if len(show) == 0 { + engine.showExecTime = true + } else { + engine.showExecTime = show[0] + } +} + +// Logger return the logger interface +func (engine *Engine) Logger() core.ILogger { + return engine.logger +} + +// SetLogger set the new logger +func (engine *Engine) SetLogger(logger core.ILogger) { + engine.logger = logger + engine.showSQL = logger.IsShowSQL() + engine.dialect.SetLogger(logger) +} + +// SetLogLevel sets the logger level +func (engine *Engine) SetLogLevel(level core.LogLevel) { + engine.logger.SetLevel(level) +} + +// SetDisableGlobalCache disable global cache or not +func (engine *Engine) SetDisableGlobalCache(disable bool) { + if engine.disableGlobalCache != disable { + engine.disableGlobalCache = disable + } +} + +// DriverName return the current sql driver's name +func (engine *Engine) DriverName() string { + return engine.dialect.DriverName() +} + +// DataSourceName return the current connection string +func (engine *Engine) DataSourceName() string { + return engine.dialect.DataSourceName() +} + +// SetMapper set the name mapping rules +func (engine *Engine) SetMapper(mapper core.IMapper) { + engine.SetTableMapper(mapper) + engine.SetColumnMapper(mapper) +} + +// SetTableMapper set the table name mapping rule +func (engine *Engine) SetTableMapper(mapper core.IMapper) { + engine.TableMapper = mapper +} + +// SetColumnMapper set the column name mapping rule +func (engine *Engine) SetColumnMapper(mapper core.IMapper) { + engine.ColumnMapper = mapper +} + +// SupportInsertMany If engine's database support batch insert records like +// "insert into user values (name, age), (name, age)". +// When the return is ture, then engine.Insert(&users) will +// generate batch sql and exeute. +func (engine *Engine) SupportInsertMany() bool { + return engine.dialect.SupportInsertMany() +} + +func (engine *Engine) quoteColumns(columnStr string) string { + columns := strings.Split(columnStr, ",") + for i := 0; i < len(columns); i++ { + columns[i] = engine.Quote(strings.TrimSpace(columns[i])) + } + return strings.Join(columns, ",") +} + +// Quote Use QuoteStr quote the string sql +func (engine *Engine) Quote(value string) string { + value = strings.TrimSpace(value) + if len(value) == 0 { + return value + } + + buf := strings.Builder{} + engine.QuoteTo(&buf, value) + + return buf.String() +} + +// QuoteTo quotes string and writes into the buffer +func (engine *Engine) QuoteTo(buf *strings.Builder, value string) { + if buf == nil { + return + } + + value = strings.TrimSpace(value) + if value == "" { + return + } + + quotePair := engine.dialect.Quote("") + + if value[0] == '`' || len(quotePair) < 2 || value[0] == quotePair[0] { // no quote + _, _ = buf.WriteString(value) + return + } else { + prefix, suffix := quotePair[0], quotePair[1] + + _ = buf.WriteByte(prefix) + for i := 0; i < len(value); i++ { + if value[i] == '.' { + _ = buf.WriteByte(suffix) + _ = buf.WriteByte('.') + _ = buf.WriteByte(prefix) + } else { + _ = buf.WriteByte(value[i]) + } + } + _ = buf.WriteByte(suffix) + } +} + +func (engine *Engine) quote(sql string) string { + return engine.dialect.Quote(sql) +} + +// SqlType will be deprecated, please use SQLType instead +// +// Deprecated: use SQLType instead +func (engine *Engine) SqlType(c *core.Column) string { + return engine.SQLType(c) +} + +// SQLType A simple wrapper to dialect's core.SqlType method +func (engine *Engine) SQLType(c *core.Column) string { + return engine.dialect.SqlType(c) +} + +// AutoIncrStr Database's autoincrement statement +func (engine *Engine) AutoIncrStr() string { + return engine.dialect.AutoIncrStr() +} + +// SetConnMaxLifetime sets the maximum amount of time a connection may be reused. +func (engine *Engine) SetConnMaxLifetime(d time.Duration) { + engine.db.SetConnMaxLifetime(d) +} + +// SetMaxOpenConns is only available for go 1.2+ +func (engine *Engine) SetMaxOpenConns(conns int) { + engine.db.SetMaxOpenConns(conns) +} + +// SetMaxIdleConns set the max idle connections on pool, default is 2 +func (engine *Engine) SetMaxIdleConns(conns int) { + engine.db.SetMaxIdleConns(conns) +} + +// SetDefaultCacher set the default cacher. Xorm's default not enable cacher. +func (engine *Engine) SetDefaultCacher(cacher core.Cacher) { + engine.Cacher = cacher +} + +// GetDefaultCacher returns the default cacher +func (engine *Engine) GetDefaultCacher() core.Cacher { + return engine.Cacher +} + +// NoCache If you has set default cacher, and you want temporilly stop use cache, +// you can use NoCache() +func (engine *Engine) NoCache() *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.NoCache() +} + +// NoCascade If you do not want to auto cascade load object +func (engine *Engine) NoCascade() *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.NoCascade() +} + +// MapCacher Set a table use a special cacher +func (engine *Engine) MapCacher(bean interface{}, cacher core.Cacher) error { + engine.setCacher(engine.TableName(bean, true), cacher) + return nil +} + +// NewDB provides an interface to operate database directly +func (engine *Engine) NewDB() (*core.DB, error) { + return core.OpenDialect(engine.dialect) +} + +// DB return the wrapper of sql.DB +func (engine *Engine) DB() *core.DB { + return engine.db +} + +// Dialect return database dialect +func (engine *Engine) Dialect() core.Dialect { + return engine.dialect +} + +// NewSession New a session +func (engine *Engine) NewSession() *Session { + session := &Session{engine: engine} + session.Init() + return session +} + +// Close the engine +func (engine *Engine) Close() error { + return engine.db.Close() +} + +// Ping tests if database is alive +func (engine *Engine) Ping() error { + session := engine.NewSession() + defer session.Close() + return session.Ping() +} + +// logging sql +func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) { + if engine.showSQL && !engine.showExecTime { + if len(sqlArgs) > 0 { + engine.logger.Infof("[SQL] %v %#v", sqlStr, sqlArgs) + } else { + engine.logger.Infof("[SQL] %v", sqlStr) + } + } +} + +// Sql provides raw sql input parameter. When you have a complex SQL statement +// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL. +// +// Deprecated: use SQL instead. +func (engine *Engine) Sql(querystring string, args ...interface{}) *Session { + return engine.SQL(querystring, args...) +} + +// SQL method let's you manually write raw SQL and operate +// For example: +// +// engine.SQL("select * from user").Find(&users) +// +// This code will execute "select * from user" and set the records to users +func (engine *Engine) SQL(query interface{}, args ...interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.SQL(query, args...) +} + +// NoAutoTime Default if your struct has "created" or "updated" filed tag, the fields +// will automatically be filled with current time when Insert or Update +// invoked. Call NoAutoTime if you dont' want to fill automatically. +func (engine *Engine) NoAutoTime() *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.NoAutoTime() +} + +// NoAutoCondition disable auto generate Where condition from bean or not +func (engine *Engine) NoAutoCondition(no ...bool) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.NoAutoCondition(no...) +} + +func (engine *Engine) loadTableInfo(table *core.Table) error { + colSeq, cols, err := engine.dialect.GetColumns(table.Name) + if err != nil { + return err + } + for _, name := range colSeq { + table.AddColumn(cols[name]) + } + indexes, err := engine.dialect.GetIndexes(table.Name) + if err != nil { + return err + } + table.Indexes = indexes + + for _, index := range indexes { + for _, name := range index.Cols { + if col := table.GetColumn(name); col != nil { + col.Indexes[index.Name] = index.Type + } else { + return fmt.Errorf("Unknown col %s in index %v of table %v, columns %v", name, index.Name, table.Name, table.ColumnsSeq()) + } + } + } + return nil +} + +// DBMetas Retrieve all tables, columns, indexes' informations from database. +func (engine *Engine) DBMetas() ([]*core.Table, error) { + tables, err := engine.dialect.GetTables() + if err != nil { + return nil, err + } + + for _, table := range tables { + if err = engine.loadTableInfo(table); err != nil { + return nil, err + } + } + return tables, nil +} + +// DumpAllToFile dump database all table structs and data to a file +func (engine *Engine) DumpAllToFile(fp string, tp ...core.DbType) error { + f, err := os.Create(fp) + if err != nil { + return err + } + defer f.Close() + return engine.DumpAll(f, tp...) +} + +// DumpAll dump database all table structs and data to w +func (engine *Engine) DumpAll(w io.Writer, tp ...core.DbType) error { + tables, err := engine.DBMetas() + if err != nil { + return err + } + return engine.DumpTables(tables, w, tp...) +} + +// DumpTablesToFile dump specified tables to SQL file. +func (engine *Engine) DumpTablesToFile(tables []*core.Table, fp string, tp ...core.DbType) error { + f, err := os.Create(fp) + if err != nil { + return err + } + defer f.Close() + return engine.DumpTables(tables, f, tp...) +} + +// DumpTables dump specify tables to io.Writer +func (engine *Engine) DumpTables(tables []*core.Table, w io.Writer, tp ...core.DbType) error { + return engine.dumpTables(tables, w, tp...) +} + +// dumpTables dump database all table structs and data to w with specify db type +func (engine *Engine) dumpTables(tables []*core.Table, w io.Writer, tp ...core.DbType) error { + var dialect core.Dialect + var distDBName string + if len(tp) == 0 { + dialect = engine.dialect + distDBName = string(engine.dialect.DBType()) + } else { + dialect = core.QueryDialect(tp[0]) + if dialect == nil { + return errors.New("Unsupported database type") + } + dialect.Init(nil, engine.dialect.URI(), "", "") + distDBName = string(tp[0]) + } + + _, err := io.WriteString(w, fmt.Sprintf("/*Generated by xorm v%s %s, from %s to %s*/\n\n", + Version, time.Now().In(engine.TZLocation).Format("2006-01-02 15:04:05"), engine.dialect.DBType(), strings.ToUpper(distDBName))) + if err != nil { + return err + } + + for i, table := range tables { + if i > 0 { + _, err = io.WriteString(w, "\n") + if err != nil { + return err + } + } + _, err = io.WriteString(w, dialect.CreateTableSql(table, "", table.StoreEngine, "")+";\n") + if err != nil { + return err + } + for _, index := range table.Indexes { + _, err = io.WriteString(w, dialect.CreateIndexSql(table.Name, index)+";\n") + if err != nil { + return err + } + } + + cols := table.ColumnsSeq() + colNames := engine.dialect.Quote(strings.Join(cols, engine.dialect.Quote(", "))) + destColNames := dialect.Quote(strings.Join(cols, dialect.Quote(", "))) + + rows, err := engine.DB().Query("SELECT " + colNames + " FROM " + engine.Quote(table.Name)) + if err != nil { + return err + } + defer rows.Close() + + for rows.Next() { + dest := make([]interface{}, len(cols)) + err = rows.ScanSlice(&dest) + if err != nil { + return err + } + + _, err = io.WriteString(w, "INSERT INTO "+dialect.Quote(table.Name)+" ("+destColNames+") VALUES (") + if err != nil { + return err + } + + var temp string + for i, d := range dest { + col := table.GetColumn(cols[i]) + if col == nil { + return errors.New("unknow column error") + } + + if d == nil { + temp += ", NULL" + } else if col.SQLType.IsText() || col.SQLType.IsTime() { + var v = fmt.Sprintf("%s", d) + if strings.HasSuffix(v, " +0000 UTC") { + temp += fmt.Sprintf(", '%s'", v[0:len(v)-len(" +0000 UTC")]) + } else { + temp += ", '" + strings.Replace(v, "'", "''", -1) + "'" + } + } else if col.SQLType.IsBlob() { + if reflect.TypeOf(d).Kind() == reflect.Slice { + temp += fmt.Sprintf(", %s", dialect.FormatBytes(d.([]byte))) + } else if reflect.TypeOf(d).Kind() == reflect.String { + temp += fmt.Sprintf(", '%s'", d.(string)) + } + } else if col.SQLType.IsNumeric() { + switch reflect.TypeOf(d).Kind() { + case reflect.Slice: + if col.SQLType.Name == core.Bool { + temp += fmt.Sprintf(", %v", strconv.FormatBool(d.([]byte)[0] != byte('0'))) + } else { + temp += fmt.Sprintf(", %s", string(d.([]byte))) + } + case reflect.Int16, reflect.Int8, reflect.Int32, reflect.Int64, reflect.Int: + if col.SQLType.Name == core.Bool { + temp += fmt.Sprintf(", %v", strconv.FormatBool(reflect.ValueOf(d).Int() > 0)) + } else { + temp += fmt.Sprintf(", %v", d) + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + if col.SQLType.Name == core.Bool { + temp += fmt.Sprintf(", %v", strconv.FormatBool(reflect.ValueOf(d).Uint() > 0)) + } else { + temp += fmt.Sprintf(", %v", d) + } + default: + temp += fmt.Sprintf(", %v", d) + } + } else { + s := fmt.Sprintf("%v", d) + if strings.Contains(s, ":") || strings.Contains(s, "-") { + if strings.HasSuffix(s, " +0000 UTC") { + temp += fmt.Sprintf(", '%s'", s[0:len(s)-len(" +0000 UTC")]) + } else { + temp += fmt.Sprintf(", '%s'", s) + } + } else { + temp += fmt.Sprintf(", %s", s) + } + } + } + _, err = io.WriteString(w, temp[2:]+");\n") + if err != nil { + return err + } + } + + // FIXME: Hack for postgres + if string(dialect.DBType()) == core.POSTGRES && table.AutoIncrColumn() != nil { + _, err = io.WriteString(w, "SELECT setval('"+table.Name+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dialect.Quote(table.Name)+"), 1), false);\n") + if err != nil { + return err + } + } + } + return nil +} + +// Cascade use cascade or not +func (engine *Engine) Cascade(trueOrFalse ...bool) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Cascade(trueOrFalse...) +} + +// Where method provide a condition query +func (engine *Engine) Where(query interface{}, args ...interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Where(query, args...) +} + +// Id will be deprecated, please use ID instead +func (engine *Engine) Id(id interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Id(id) +} + +// ID method provoide a condition as (id) = ? +func (engine *Engine) ID(id interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.ID(id) +} + +// Before apply before Processor, affected bean is passed to closure arg +func (engine *Engine) Before(closures func(interface{})) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Before(closures) +} + +// After apply after insert Processor, affected bean is passed to closure arg +func (engine *Engine) After(closures func(interface{})) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.After(closures) +} + +// Charset set charset when create table, only support mysql now +func (engine *Engine) Charset(charset string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Charset(charset) +} + +// StoreEngine set store engine when create table, only support mysql now +func (engine *Engine) StoreEngine(storeEngine string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.StoreEngine(storeEngine) +} + +// Distinct use for distinct columns. Caution: when you are using cache, +// distinct will not be cached because cache system need id, +// but distinct will not provide id +func (engine *Engine) Distinct(columns ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Distinct(columns...) +} + +// Select customerize your select columns or contents +func (engine *Engine) Select(str string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Select(str) +} + +// Cols only use the parameters as select or update columns +func (engine *Engine) Cols(columns ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Cols(columns...) +} + +// AllCols indicates that all columns should be use +func (engine *Engine) AllCols() *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.AllCols() +} + +// MustCols specify some columns must use even if they are empty +func (engine *Engine) MustCols(columns ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.MustCols(columns...) +} + +// UseBool xorm automatically retrieve condition according struct, but +// if struct has bool field, it will ignore them. So use UseBool +// to tell system to do not ignore them. +// If no parameters, it will use all the bool field of struct, or +// it will use parameters's columns +func (engine *Engine) UseBool(columns ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.UseBool(columns...) +} + +// Omit only not use the parameters as select or update columns +func (engine *Engine) Omit(columns ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Omit(columns...) +} + +// Nullable set null when column is zero-value and nullable for update +func (engine *Engine) Nullable(columns ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Nullable(columns...) +} + +// In will generate "column IN (?, ?)" +func (engine *Engine) In(column string, args ...interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.In(column, args...) +} + +// NotIn will generate "column NOT IN (?, ?)" +func (engine *Engine) NotIn(column string, args ...interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.NotIn(column, args...) +} + +// Incr provides a update string like "column = column + ?" +func (engine *Engine) Incr(column string, arg ...interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Incr(column, arg...) +} + +// Decr provides a update string like "column = column - ?" +func (engine *Engine) Decr(column string, arg ...interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Decr(column, arg...) +} + +// SetExpr provides a update string like "column = {expression}" +func (engine *Engine) SetExpr(column string, expression interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.SetExpr(column, expression) +} + +// Table temporarily change the Get, Find, Update's table +func (engine *Engine) Table(tableNameOrBean interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Table(tableNameOrBean) +} + +// Alias set the table alias +func (engine *Engine) Alias(alias string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Alias(alias) +} + +// Limit will generate "LIMIT start, limit" +func (engine *Engine) Limit(limit int, start ...int) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Limit(limit, start...) +} + +// Desc will generate "ORDER BY column1 DESC, column2 DESC" +func (engine *Engine) Desc(colNames ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Desc(colNames...) +} + +// Asc will generate "ORDER BY column1,column2 Asc" +// This method can chainable use. +// +// engine.Desc("name").Asc("age").Find(&users) +// // SELECT * FROM user ORDER BY name DESC, age ASC +// +func (engine *Engine) Asc(colNames ...string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Asc(colNames...) +} + +// OrderBy will generate "ORDER BY order" +func (engine *Engine) OrderBy(order string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.OrderBy(order) +} + +// Prepare enables prepare statement +func (engine *Engine) Prepare() *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Prepare() +} + +// Join the join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN +func (engine *Engine) Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Join(joinOperator, tablename, condition, args...) +} + +// GroupBy generate group by statement +func (engine *Engine) GroupBy(keys string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.GroupBy(keys) +} + +// Having generate having statement +func (engine *Engine) Having(conditions string) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Having(conditions) +} + +// UnMapType removes the datbase mapper of a type +func (engine *Engine) UnMapType(t reflect.Type) { + engine.mutex.Lock() + defer engine.mutex.Unlock() + delete(engine.Tables, t) +} + +func (engine *Engine) autoMapType(v reflect.Value) (*core.Table, error) { + t := v.Type() + engine.mutex.Lock() + defer engine.mutex.Unlock() + table, ok := engine.Tables[t] + if !ok { + var err error + table, err = engine.mapType(v) + if err != nil { + return nil, err + } + + engine.Tables[t] = table + if engine.Cacher != nil { + if v.CanAddr() { + engine.GobRegister(v.Addr().Interface()) + } else { + engine.GobRegister(v.Interface()) + } + } + } + return table, nil +} + +// GobRegister register one struct to gob for cache use +func (engine *Engine) GobRegister(v interface{}) *Engine { + gob.Register(v) + return engine +} + +// Table table struct +type Table struct { + *core.Table + Name string +} + +// IsValid if table is valid +func (t *Table) IsValid() bool { + return t.Table != nil && len(t.Name) > 0 +} + +// TableInfo get table info according to bean's content +func (engine *Engine) TableInfo(bean interface{}) *Table { + v := rValue(bean) + tb, err := engine.autoMapType(v) + if err != nil { + engine.logger.Error(err) + } + return &Table{tb, engine.TableName(bean)} +} + +func addIndex(indexName string, table *core.Table, col *core.Column, indexType int) { + if index, ok := table.Indexes[indexName]; ok { + index.AddColumn(col.Name) + col.Indexes[index.Name] = indexType + } else { + index := core.NewIndex(indexName, indexType) + index.AddColumn(col.Name) + table.AddIndex(index) + col.Indexes[index.Name] = indexType + } +} + +// TableName table name interface to define customerize table name +type TableName interface { + TableName() string +} + +var ( + tpTableName = reflect.TypeOf((*TableName)(nil)).Elem() +) + +func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) { + t := v.Type() + table := core.NewEmptyTable() + table.Type = t + table.Name = engine.tbNameForMap(v) + + var idFieldColName string + var hasCacheTag, hasNoCacheTag bool + + for i := 0; i < t.NumField(); i++ { + tag := t.Field(i).Tag + + ormTagStr := tag.Get(engine.TagIdentifier) + var col *core.Column + fieldValue := v.Field(i) + fieldType := fieldValue.Type() + + if ormTagStr != "" { + col = &core.Column{ + FieldName: t.Field(i).Name, + Nullable: true, + IsPrimaryKey: false, + IsAutoIncrement: false, + MapType: core.TWOSIDES, + Indexes: make(map[string]int), + DefaultIsEmpty: true, + } + tags := splitTag(ormTagStr) + + if len(tags) > 0 { + if tags[0] == "-" { + continue + } + + var ctx = tagContext{ + table: table, + col: col, + fieldValue: fieldValue, + indexNames: make(map[string]int), + engine: engine, + } + + if strings.HasPrefix(strings.ToUpper(tags[0]), "EXTENDS") { + pStart := strings.Index(tags[0], "(") + if pStart > -1 && strings.HasSuffix(tags[0], ")") { + var tagPrefix = strings.TrimFunc(tags[0][pStart+1:len(tags[0])-1], func(r rune) bool { + return r == '\'' || r == '"' + }) + + ctx.params = []string{tagPrefix} + } + + if err := ExtendsTagHandler(&ctx); err != nil { + return nil, err + } + continue + } + + for j, key := range tags { + if ctx.ignoreNext { + ctx.ignoreNext = false + continue + } + + k := strings.ToUpper(key) + ctx.tagName = k + ctx.params = []string{} + + pStart := strings.Index(k, "(") + if pStart == 0 { + return nil, errors.New("( could not be the first charactor") + } + if pStart > -1 { + if !strings.HasSuffix(k, ")") { + return nil, fmt.Errorf("field %s tag %s cannot match ) charactor", col.FieldName, key) + } + + ctx.tagName = k[:pStart] + ctx.params = strings.Split(key[pStart+1:len(k)-1], ",") + } + + if j > 0 { + ctx.preTag = strings.ToUpper(tags[j-1]) + } + if j < len(tags)-1 { + ctx.nextTag = tags[j+1] + } else { + ctx.nextTag = "" + } + + if h, ok := engine.tagHandlers[ctx.tagName]; ok { + if err := h(&ctx); err != nil { + return nil, err + } + } else { + if strings.HasPrefix(key, "'") && strings.HasSuffix(key, "'") { + col.Name = key[1 : len(key)-1] + } else { + col.Name = key + } + } + + if ctx.hasCacheTag { + hasCacheTag = true + } + if ctx.hasNoCacheTag { + hasNoCacheTag = true + } + } + + if col.SQLType.Name == "" { + col.SQLType = core.Type2SQLType(fieldType) + } + engine.dialect.SqlType(col) + if col.Length == 0 { + col.Length = col.SQLType.DefaultLength + } + if col.Length2 == 0 { + col.Length2 = col.SQLType.DefaultLength2 + } + if col.Name == "" { + col.Name = engine.ColumnMapper.Obj2Table(t.Field(i).Name) + } + + if ctx.isUnique { + ctx.indexNames[col.Name] = core.UniqueType + } else if ctx.isIndex { + ctx.indexNames[col.Name] = core.IndexType + } + + for indexName, indexType := range ctx.indexNames { + addIndex(indexName, table, col, indexType) + } + } + } else { + var sqlType core.SQLType + if fieldValue.CanAddr() { + if _, ok := fieldValue.Addr().Interface().(core.Conversion); ok { + sqlType = core.SQLType{Name: core.Text} + } + } + if _, ok := fieldValue.Interface().(core.Conversion); ok { + sqlType = core.SQLType{Name: core.Text} + } else { + sqlType = core.Type2SQLType(fieldType) + } + col = core.NewColumn(engine.ColumnMapper.Obj2Table(t.Field(i).Name), + t.Field(i).Name, sqlType, sqlType.DefaultLength, + sqlType.DefaultLength2, true) + + if fieldType.Kind() == reflect.Int64 && (strings.ToUpper(col.FieldName) == "ID" || strings.HasSuffix(strings.ToUpper(col.FieldName), ".ID")) { + idFieldColName = col.Name + } + } + if col.IsAutoIncrement { + col.Nullable = false + } + + table.AddColumn(col) + + } // end for + + if idFieldColName != "" && len(table.PrimaryKeys) == 0 { + col := table.GetColumn(idFieldColName) + col.IsPrimaryKey = true + col.IsAutoIncrement = true + col.Nullable = false + table.PrimaryKeys = append(table.PrimaryKeys, col.Name) + table.AutoIncrement = col.Name + } + + if hasCacheTag { + if engine.Cacher != nil { // !nash! use engine's cacher if provided + engine.logger.Info("enable cache on table:", table.Name) + engine.setCacher(table.Name, engine.Cacher) + } else { + engine.logger.Info("enable LRU cache on table:", table.Name) + engine.setCacher(table.Name, NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)) + } + } + if hasNoCacheTag { + engine.logger.Info("disable cache on table:", table.Name) + engine.setCacher(table.Name, nil) + } + + return table, nil +} + +// IsTableEmpty if a table has any reocrd +func (engine *Engine) IsTableEmpty(bean interface{}) (bool, error) { + session := engine.NewSession() + defer session.Close() + return session.IsTableEmpty(bean) +} + +// IsTableExist if a table is exist +func (engine *Engine) IsTableExist(beanOrTableName interface{}) (bool, error) { + session := engine.NewSession() + defer session.Close() + return session.IsTableExist(beanOrTableName) +} + +// IdOf get id from one struct +// +// Deprecated: use IDOf instead. +func (engine *Engine) IdOf(bean interface{}) core.PK { + return engine.IDOf(bean) +} + +// IDOf get id from one struct +func (engine *Engine) IDOf(bean interface{}) core.PK { + return engine.IdOfV(reflect.ValueOf(bean)) +} + +// IdOfV get id from one value of struct +// +// Deprecated: use IDOfV instead. +func (engine *Engine) IdOfV(rv reflect.Value) core.PK { + return engine.IDOfV(rv) +} + +// IDOfV get id from one value of struct +func (engine *Engine) IDOfV(rv reflect.Value) core.PK { + pk, err := engine.idOfV(rv) + if err != nil { + engine.logger.Error(err) + return nil + } + return pk +} + +func (engine *Engine) idOfV(rv reflect.Value) (core.PK, error) { + v := reflect.Indirect(rv) + table, err := engine.autoMapType(v) + if err != nil { + return nil, err + } + + pk := make([]interface{}, len(table.PrimaryKeys)) + for i, col := range table.PKColumns() { + var err error + + fieldName := col.FieldName + for { + parts := strings.SplitN(fieldName, ".", 2) + if len(parts) == 1 { + break + } + + v = v.FieldByName(parts[0]) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if v.Kind() != reflect.Struct { + return nil, ErrUnSupportedType + } + fieldName = parts[1] + } + + pkField := v.FieldByName(fieldName) + switch pkField.Kind() { + case reflect.String: + pk[i], err = engine.idTypeAssertion(col, pkField.String()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + pk[i], err = engine.idTypeAssertion(col, strconv.FormatInt(pkField.Int(), 10)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + // id of uint will be converted to int64 + pk[i], err = engine.idTypeAssertion(col, strconv.FormatUint(pkField.Uint(), 10)) + } + + if err != nil { + return nil, err + } + } + return core.PK(pk), nil +} + +func (engine *Engine) idTypeAssertion(col *core.Column, sid string) (interface{}, error) { + if col.SQLType.IsNumeric() { + n, err := strconv.ParseInt(sid, 10, 64) + if err != nil { + return nil, err + } + return n, nil + } else if col.SQLType.IsText() { + return sid, nil + } else { + return nil, errors.New("not supported") + } +} + +// CreateIndexes create indexes +func (engine *Engine) CreateIndexes(bean interface{}) error { + session := engine.NewSession() + defer session.Close() + return session.CreateIndexes(bean) +} + +// CreateUniques create uniques +func (engine *Engine) CreateUniques(bean interface{}) error { + session := engine.NewSession() + defer session.Close() + return session.CreateUniques(bean) +} + +// ClearCacheBean if enabled cache, clear the cache bean +func (engine *Engine) ClearCacheBean(bean interface{}, id string) error { + tableName := engine.TableName(bean) + cacher := engine.getCacher(tableName) + if cacher != nil { + cacher.ClearIds(tableName) + cacher.DelBean(tableName, id) + } + return nil +} + +// ClearCache if enabled cache, clear some tables' cache +func (engine *Engine) ClearCache(beans ...interface{}) error { + for _, bean := range beans { + tableName := engine.TableName(bean) + cacher := engine.getCacher(tableName) + if cacher != nil { + cacher.ClearIds(tableName) + cacher.ClearBeans(tableName) + } + } + return nil +} + +// Sync the new struct changes to database, this method will automatically add +// table, column, index, unique. but will not delete or change anything. +// If you change some field, you should change the database manually. +func (engine *Engine) Sync(beans ...interface{}) error { + session := engine.NewSession() + defer session.Close() + + for _, bean := range beans { + v := rValue(bean) + tableNameNoSchema := engine.TableName(bean) + table, err := engine.autoMapType(v) + if err != nil { + return err + } + + isExist, err := session.Table(bean).isTableExist(tableNameNoSchema) + if err != nil { + return err + } + if !isExist { + err = session.createTable(bean) + if err != nil { + return err + } + } + /*isEmpty, err := engine.IsEmptyTable(bean) + if err != nil { + return err + }*/ + var isEmpty bool + if isEmpty { + err = session.dropTable(bean) + if err != nil { + return err + } + err = session.createTable(bean) + if err != nil { + return err + } + } else { + for _, col := range table.Columns() { + isExist, err := engine.dialect.IsColumnExist(tableNameNoSchema, col.Name) + if err != nil { + return err + } + if !isExist { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + err = session.addColumn(col.Name) + if err != nil { + return err + } + } + } + + for name, index := range table.Indexes { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + if index.Type == core.UniqueType { + isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, true) + if err != nil { + return err + } + if !isExist { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + + err = session.addUnique(tableNameNoSchema, name) + if err != nil { + return err + } + } + } else if index.Type == core.IndexType { + isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, false) + if err != nil { + return err + } + if !isExist { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + + err = session.addIndex(tableNameNoSchema, name) + if err != nil { + return err + } + } + } else { + return errors.New("unknow index type") + } + } + } + } + return nil +} + +// Sync2 synchronize structs to database tables +func (engine *Engine) Sync2(beans ...interface{}) error { + s := engine.NewSession() + defer s.Close() + return s.Sync2(beans...) +} + +// CreateTables create tabls according bean +func (engine *Engine) CreateTables(beans ...interface{}) error { + session := engine.NewSession() + defer session.Close() + + err := session.Begin() + if err != nil { + return err + } + + for _, bean := range beans { + err = session.createTable(bean) + if err != nil { + session.Rollback() + return err + } + } + return session.Commit() +} + +// DropTables drop specify tables +func (engine *Engine) DropTables(beans ...interface{}) error { + session := engine.NewSession() + defer session.Close() + + err := session.Begin() + if err != nil { + return err + } + + for _, bean := range beans { + err = session.dropTable(bean) + if err != nil { + session.Rollback() + return err + } + } + return session.Commit() +} + +// DropIndexes drop indexes of a table +func (engine *Engine) DropIndexes(bean interface{}) error { + session := engine.NewSession() + defer session.Close() + return session.DropIndexes(bean) +} + +// Exec raw sql +func (engine *Engine) Exec(sqlOrArgs ...interface{}) (sql.Result, error) { + session := engine.NewSession() + defer session.Close() + return session.Exec(sqlOrArgs...) +} + +// Query a raw sql and return records as []map[string][]byte +func (engine *Engine) Query(sqlOrArgs ...interface{}) (resultsSlice []map[string][]byte, err error) { + session := engine.NewSession() + defer session.Close() + return session.Query(sqlOrArgs...) +} + +// QueryString runs a raw sql and return records as []map[string]string +func (engine *Engine) QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) { + session := engine.NewSession() + defer session.Close() + return session.QueryString(sqlOrArgs...) +} + +// QueryInterface runs a raw sql and return records as []map[string]interface{} +func (engine *Engine) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) { + session := engine.NewSession() + defer session.Close() + return session.QueryInterface(sqlOrArgs...) +} + +// Insert one or more records +func (engine *Engine) Insert(beans ...interface{}) (int64, error) { + session := engine.NewSession() + defer session.Close() + return session.Insert(beans...) +} + +// InsertOne insert only one record +func (engine *Engine) InsertOne(bean interface{}) (int64, error) { + session := engine.NewSession() + defer session.Close() + return session.InsertOne(bean) +} + +// Update records, bean's non-empty fields are updated contents, +// condiBean' non-empty filds are conditions +// CAUTION: +// 1.bool will defaultly be updated content nor conditions +// You should call UseBool if you have bool to use. +// 2.float32 & float64 may be not inexact as conditions +func (engine *Engine) Update(bean interface{}, condiBeans ...interface{}) (int64, error) { + session := engine.NewSession() + defer session.Close() + return session.Update(bean, condiBeans...) +} + +// Delete records, bean's non-empty fields are conditions +func (engine *Engine) Delete(bean interface{}) (int64, error) { + session := engine.NewSession() + defer session.Close() + return session.Delete(bean) +} + +// Get retrieve one record from table, bean's non-empty fields +// are conditions +func (engine *Engine) Get(bean interface{}) (bool, error) { + session := engine.NewSession() + defer session.Close() + return session.Get(bean) +} + +// Exist returns true if the record exist otherwise return false +func (engine *Engine) Exist(bean ...interface{}) (bool, error) { + session := engine.NewSession() + defer session.Close() + return session.Exist(bean...) +} + +// Find retrieve records from table, condiBeans's non-empty fields +// are conditions. beans could be []Struct, []*Struct, map[int64]Struct +// map[int64]*Struct +func (engine *Engine) Find(beans interface{}, condiBeans ...interface{}) error { + session := engine.NewSession() + defer session.Close() + return session.Find(beans, condiBeans...) +} + +// FindAndCount find the results and also return the counts +func (engine *Engine) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { + session := engine.NewSession() + defer session.Close() + return session.FindAndCount(rowsSlicePtr, condiBean...) +} + +// Iterate record by record handle records from table, bean's non-empty fields +// are conditions. +func (engine *Engine) Iterate(bean interface{}, fun IterFunc) error { + session := engine.NewSession() + defer session.Close() + return session.Iterate(bean, fun) +} + +// Rows return sql.Rows compatible Rows obj, as a forward Iterator object for iterating record by record, bean's non-empty fields +// are conditions. +func (engine *Engine) Rows(bean interface{}) (*Rows, error) { + session := engine.NewSession() + return session.Rows(bean) +} + +// Count counts the records. bean's non-empty fields are conditions. +func (engine *Engine) Count(bean ...interface{}) (int64, error) { + session := engine.NewSession() + defer session.Close() + return session.Count(bean...) +} + +// Sum sum the records by some column. bean's non-empty fields are conditions. +func (engine *Engine) Sum(bean interface{}, colName string) (float64, error) { + session := engine.NewSession() + defer session.Close() + return session.Sum(bean, colName) +} + +// SumInt sum the records by some column. bean's non-empty fields are conditions. +func (engine *Engine) SumInt(bean interface{}, colName string) (int64, error) { + session := engine.NewSession() + defer session.Close() + return session.SumInt(bean, colName) +} + +// Sums sum the records by some columns. bean's non-empty fields are conditions. +func (engine *Engine) Sums(bean interface{}, colNames ...string) ([]float64, error) { + session := engine.NewSession() + defer session.Close() + return session.Sums(bean, colNames...) +} + +// SumsInt like Sums but return slice of int64 instead of float64. +func (engine *Engine) SumsInt(bean interface{}, colNames ...string) ([]int64, error) { + session := engine.NewSession() + defer session.Close() + return session.SumsInt(bean, colNames...) +} + +// ImportFile SQL DDL file +func (engine *Engine) ImportFile(ddlPath string) ([]sql.Result, error) { + file, err := os.Open(ddlPath) + if err != nil { + return nil, err + } + defer file.Close() + return engine.Import(file) +} + +// Import SQL DDL from io.Reader +func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) { + var results []sql.Result + var lastError error + scanner := bufio.NewScanner(r) + + semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + if i := bytes.IndexByte(data, ';'); i >= 0 { + return i + 1, data[0:i], nil + } + // If we're at EOF, we have a final, non-terminated line. Return it. + if atEOF { + return len(data), data, nil + } + // Request more data. + return 0, nil, nil + } + + scanner.Split(semiColSpliter) + + for scanner.Scan() { + query := strings.Trim(scanner.Text(), " \t\n\r") + if len(query) > 0 { + engine.logSQL(query) + result, err := engine.DB().Exec(query) + results = append(results, result) + if err != nil { + return nil, err + } + } + } + + return results, lastError +} + +// nowTime return current time +func (engine *Engine) nowTime(col *core.Column) (interface{}, time.Time) { + t := time.Now() + var tz = engine.DatabaseTZ + if !col.DisableTimeZone && col.TimeZone != nil { + tz = col.TimeZone + } + return engine.formatTime(col.SQLType.Name, t.In(tz)), t.In(engine.TZLocation) +} + +func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{}) { + if t.IsZero() { + if col.Nullable { + return nil + } + return "" + } + + if col.TimeZone != nil { + return engine.formatTime(col.SQLType.Name, t.In(col.TimeZone)) + } + return engine.formatTime(col.SQLType.Name, t.In(engine.DatabaseTZ)) +} + +// formatTime format time as column type +func (engine *Engine) formatTime(sqlTypeName string, t time.Time) (v interface{}) { + switch sqlTypeName { + case core.Time: + s := t.Format("2006-01-02 15:04:05") // time.RFC3339 + v = s[11:19] + case core.Date: + v = t.Format("2006-01-02") + case core.DateTime, core.TimeStamp: + v = t.Format("2006-01-02 15:04:05") + case core.TimeStampz: + if engine.dialect.DBType() == core.MSSQL { + v = t.Format("2006-01-02T15:04:05.9999999Z07:00") + } else { + v = t.Format(time.RFC3339Nano) + } + case core.BigInt, core.Int: + v = t.Unix() + default: + v = t + } + return +} + +// GetColumnMapper returns the column name mapper +func (engine *Engine) GetColumnMapper() core.IMapper { + return engine.ColumnMapper +} + +// GetTableMapper returns the table name mapper +func (engine *Engine) GetTableMapper() core.IMapper { + return engine.TableMapper +} + +// GetTZLocation returns time zone of the application +func (engine *Engine) GetTZLocation() *time.Location { + return engine.TZLocation +} + +// SetTZLocation sets time zone of the application +func (engine *Engine) SetTZLocation(tz *time.Location) { + engine.TZLocation = tz +} + +// GetTZDatabase returns time zone of the database +func (engine *Engine) GetTZDatabase() *time.Location { + return engine.DatabaseTZ +} + +// SetTZDatabase sets time zone of the database +func (engine *Engine) SetTZDatabase(tz *time.Location) { + engine.DatabaseTZ = tz +} + +// SetSchema sets the schema of database +func (engine *Engine) SetSchema(schema string) { + engine.dialect.URI().Schema = schema +} + +// Unscoped always disable struct tag "deleted" +func (engine *Engine) Unscoped() *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Unscoped() +} diff --git a/vendor/xorm.io/xorm/engine_cond.go b/vendor/xorm.io/xorm/engine_cond.go new file mode 100644 index 0000000000..702ac80434 --- /dev/null +++ b/vendor/xorm.io/xorm/engine_cond.go @@ -0,0 +1,232 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql/driver" + "fmt" + "reflect" + "strings" + "time" + + "xorm.io/builder" + "xorm.io/core" +) + +func (engine *Engine) buildConds(table *core.Table, bean interface{}, + includeVersion bool, includeUpdated bool, includeNil bool, + includeAutoIncr bool, allUseBool bool, useAllCols bool, unscoped bool, + mustColumnMap map[string]bool, tableName, aliasName string, addedTableName bool) (builder.Cond, error) { + var conds []builder.Cond + for _, col := range table.Columns() { + if !includeVersion && col.IsVersion { + continue + } + if !includeUpdated && col.IsUpdated { + continue + } + if !includeAutoIncr && col.IsAutoIncrement { + continue + } + + if engine.dialect.DBType() == core.MSSQL && (col.SQLType.Name == core.Text || col.SQLType.IsBlob() || col.SQLType.Name == core.TimeStampz) { + continue + } + if col.SQLType.IsJson() { + continue + } + + var colName string + if addedTableName { + var nm = tableName + if len(aliasName) > 0 { + nm = aliasName + } + colName = engine.Quote(nm) + "." + engine.Quote(col.Name) + } else { + colName = engine.Quote(col.Name) + } + + fieldValuePtr, err := col.ValueOf(bean) + if err != nil { + if !strings.Contains(err.Error(), "is not valid") { + engine.logger.Warn(err) + } + continue + } + + if col.IsDeleted && !unscoped { // tag "deleted" is enabled + conds = append(conds, engine.CondDeleted(colName)) + } + + fieldValue := *fieldValuePtr + if fieldValue.Interface() == nil { + continue + } + + fieldType := reflect.TypeOf(fieldValue.Interface()) + requiredField := useAllCols + + if b, ok := getFlagForColumn(mustColumnMap, col); ok { + if b { + requiredField = true + } else { + continue + } + } + + if fieldType.Kind() == reflect.Ptr { + if fieldValue.IsNil() { + if includeNil { + conds = append(conds, builder.Eq{colName: nil}) + } + continue + } else if !fieldValue.IsValid() { + continue + } else { + // dereference ptr type to instance type + fieldValue = fieldValue.Elem() + fieldType = reflect.TypeOf(fieldValue.Interface()) + requiredField = true + } + } + + var val interface{} + switch fieldType.Kind() { + case reflect.Bool: + if allUseBool || requiredField { + val = fieldValue.Interface() + } else { + // if a bool in a struct, it will not be as a condition because it default is false, + // please use Where() instead + continue + } + case reflect.String: + if !requiredField && fieldValue.String() == "" { + continue + } + // for MyString, should convert to string or panic + if fieldType.String() != reflect.String.String() { + val = fieldValue.String() + } else { + val = fieldValue.Interface() + } + case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64: + if !requiredField && fieldValue.Int() == 0 { + continue + } + val = fieldValue.Interface() + case reflect.Float32, reflect.Float64: + if !requiredField && fieldValue.Float() == 0.0 { + continue + } + val = fieldValue.Interface() + case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64: + if !requiredField && fieldValue.Uint() == 0 { + continue + } + t := int64(fieldValue.Uint()) + val = reflect.ValueOf(&t).Interface() + case reflect.Struct: + if fieldType.ConvertibleTo(core.TimeType) { + t := fieldValue.Convert(core.TimeType).Interface().(time.Time) + if !requiredField && (t.IsZero() || !fieldValue.IsValid()) { + continue + } + val = engine.formatColTime(col, t) + } else if _, ok := reflect.New(fieldType).Interface().(core.Conversion); ok { + continue + } else if valNul, ok := fieldValue.Interface().(driver.Valuer); ok { + val, _ = valNul.Value() + if val == nil { + continue + } + } else { + if col.SQLType.IsJson() { + if col.SQLType.IsText() { + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + engine.logger.Error(err) + continue + } + val = string(bytes) + } else if col.SQLType.IsBlob() { + var bytes []byte + var err error + bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + engine.logger.Error(err) + continue + } + val = bytes + } + } else { + engine.autoMapType(fieldValue) + if table, ok := engine.Tables[fieldValue.Type()]; ok { + if len(table.PrimaryKeys) == 1 { + pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName) + // fix non-int pk issues + //if pkField.Int() != 0 { + if pkField.IsValid() && !isZero(pkField.Interface()) { + val = pkField.Interface() + } else { + continue + } + } else { + //TODO: how to handler? + return nil, fmt.Errorf("not supported %v as %v", fieldValue.Interface(), table.PrimaryKeys) + } + } else { + val = fieldValue.Interface() + } + } + } + case reflect.Array: + continue + case reflect.Slice, reflect.Map: + if fieldValue == reflect.Zero(fieldType) { + continue + } + if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 { + continue + } + + if col.SQLType.IsText() { + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + engine.logger.Error(err) + continue + } + val = string(bytes) + } else if col.SQLType.IsBlob() { + var bytes []byte + var err error + if (fieldType.Kind() == reflect.Array || fieldType.Kind() == reflect.Slice) && + fieldType.Elem().Kind() == reflect.Uint8 { + if fieldValue.Len() > 0 { + val = fieldValue.Bytes() + } else { + continue + } + } else { + bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + engine.logger.Error(err) + continue + } + val = bytes + } + } else { + continue + } + default: + val = fieldValue.Interface() + } + + conds = append(conds, builder.Eq{colName: val}) + } + + return builder.And(conds...), nil +} diff --git a/vendor/xorm.io/xorm/engine_context.go b/vendor/xorm.io/xorm/engine_context.go new file mode 100644 index 0000000000..c6cbb76c1d --- /dev/null +++ b/vendor/xorm.io/xorm/engine_context.go @@ -0,0 +1,28 @@ +// Copyright 2019 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package xorm + +import "context" + +// Context creates a session with the context +func (engine *Engine) Context(ctx context.Context) *Session { + session := engine.NewSession() + session.isAutoClose = true + return session.Context(ctx) +} + +// SetDefaultContext set the default context +func (engine *Engine) SetDefaultContext(ctx context.Context) { + engine.defaultContext = ctx +} + +// PingContext tests if database is alive +func (engine *Engine) PingContext(ctx context.Context) error { + session := engine.NewSession() + defer session.Close() + return session.PingContext(ctx) +} diff --git a/vendor/xorm.io/xorm/engine_group.go b/vendor/xorm.io/xorm/engine_group.go new file mode 100644 index 0000000000..42d49eca93 --- /dev/null +++ b/vendor/xorm.io/xorm/engine_group.go @@ -0,0 +1,219 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "context" + "time" + + "xorm.io/core" +) + +// EngineGroup defines an engine group +type EngineGroup struct { + *Engine + slaves []*Engine + policy GroupPolicy +} + +// NewEngineGroup creates a new engine group +func NewEngineGroup(args1 interface{}, args2 interface{}, policies ...GroupPolicy) (*EngineGroup, error) { + var eg EngineGroup + if len(policies) > 0 { + eg.policy = policies[0] + } else { + eg.policy = RoundRobinPolicy() + } + + driverName, ok1 := args1.(string) + conns, ok2 := args2.([]string) + if ok1 && ok2 { + engines := make([]*Engine, len(conns)) + for i, conn := range conns { + engine, err := NewEngine(driverName, conn) + if err != nil { + return nil, err + } + engine.engineGroup = &eg + engines[i] = engine + } + + eg.Engine = engines[0] + eg.slaves = engines[1:] + return &eg, nil + } + + master, ok3 := args1.(*Engine) + slaves, ok4 := args2.([]*Engine) + if ok3 && ok4 { + master.engineGroup = &eg + for i := 0; i < len(slaves); i++ { + slaves[i].engineGroup = &eg + } + eg.Engine = master + eg.slaves = slaves + return &eg, nil + } + return nil, ErrParamsType +} + +// Close the engine +func (eg *EngineGroup) Close() error { + err := eg.Engine.Close() + if err != nil { + return err + } + + for i := 0; i < len(eg.slaves); i++ { + err := eg.slaves[i].Close() + if err != nil { + return err + } + } + return nil +} + +// Context returned a group session +func (eg *EngineGroup) Context(ctx context.Context) *Session { + sess := eg.NewSession() + sess.isAutoClose = true + return sess.Context(ctx) +} + +// NewSession returned a group session +func (eg *EngineGroup) NewSession() *Session { + sess := eg.Engine.NewSession() + sess.sessionType = groupSession + return sess +} + +// Master returns the master engine +func (eg *EngineGroup) Master() *Engine { + return eg.Engine +} + +// Ping tests if database is alive +func (eg *EngineGroup) Ping() error { + if err := eg.Engine.Ping(); err != nil { + return err + } + + for _, slave := range eg.slaves { + if err := slave.Ping(); err != nil { + return err + } + } + return nil +} + +// SetColumnMapper set the column name mapping rule +func (eg *EngineGroup) SetColumnMapper(mapper core.IMapper) { + eg.Engine.ColumnMapper = mapper + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].ColumnMapper = mapper + } +} + +// SetConnMaxLifetime sets the maximum amount of time a connection may be reused. +func (eg *EngineGroup) SetConnMaxLifetime(d time.Duration) { + eg.Engine.SetConnMaxLifetime(d) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].SetConnMaxLifetime(d) + } +} + +// SetDefaultCacher set the default cacher +func (eg *EngineGroup) SetDefaultCacher(cacher core.Cacher) { + eg.Engine.SetDefaultCacher(cacher) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].SetDefaultCacher(cacher) + } +} + +// SetLogger set the new logger +func (eg *EngineGroup) SetLogger(logger core.ILogger) { + eg.Engine.SetLogger(logger) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].SetLogger(logger) + } +} + +// SetLogLevel sets the logger level +func (eg *EngineGroup) SetLogLevel(level core.LogLevel) { + eg.Engine.SetLogLevel(level) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].SetLogLevel(level) + } +} + +// SetMapper set the name mapping rules +func (eg *EngineGroup) SetMapper(mapper core.IMapper) { + eg.Engine.SetMapper(mapper) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].SetMapper(mapper) + } +} + +// SetMaxIdleConns set the max idle connections on pool, default is 2 +func (eg *EngineGroup) SetMaxIdleConns(conns int) { + eg.Engine.db.SetMaxIdleConns(conns) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].db.SetMaxIdleConns(conns) + } +} + +// SetMaxOpenConns is only available for go 1.2+ +func (eg *EngineGroup) SetMaxOpenConns(conns int) { + eg.Engine.db.SetMaxOpenConns(conns) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].db.SetMaxOpenConns(conns) + } +} + +// SetPolicy set the group policy +func (eg *EngineGroup) SetPolicy(policy GroupPolicy) *EngineGroup { + eg.policy = policy + return eg +} + +// SetTableMapper set the table name mapping rule +func (eg *EngineGroup) SetTableMapper(mapper core.IMapper) { + eg.Engine.TableMapper = mapper + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].TableMapper = mapper + } +} + +// ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO +func (eg *EngineGroup) ShowExecTime(show ...bool) { + eg.Engine.ShowExecTime(show...) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].ShowExecTime(show...) + } +} + +// ShowSQL show SQL statement or not on logger if log level is great than INFO +func (eg *EngineGroup) ShowSQL(show ...bool) { + eg.Engine.ShowSQL(show...) + for i := 0; i < len(eg.slaves); i++ { + eg.slaves[i].ShowSQL(show...) + } +} + +// Slave returns one of the physical databases which is a slave according the policy +func (eg *EngineGroup) Slave() *Engine { + switch len(eg.slaves) { + case 0: + return eg.Engine + case 1: + return eg.slaves[0] + } + return eg.policy.Slave(eg) +} + +// Slaves returns all the slaves +func (eg *EngineGroup) Slaves() []*Engine { + return eg.slaves +} diff --git a/vendor/xorm.io/xorm/engine_group_policy.go b/vendor/xorm.io/xorm/engine_group_policy.go new file mode 100644 index 0000000000..5b56e8995f --- /dev/null +++ b/vendor/xorm.io/xorm/engine_group_policy.go @@ -0,0 +1,116 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "math/rand" + "sync" + "time" +) + +// GroupPolicy is be used by chosing the current slave from slaves +type GroupPolicy interface { + Slave(*EngineGroup) *Engine +} + +// GroupPolicyHandler should be used when a function is a GroupPolicy +type GroupPolicyHandler func(*EngineGroup) *Engine + +// Slave implements the chosen of slaves +func (h GroupPolicyHandler) Slave(eg *EngineGroup) *Engine { + return h(eg) +} + +// RandomPolicy implmentes randomly chose the slave of slaves +func RandomPolicy() GroupPolicyHandler { + var r = rand.New(rand.NewSource(time.Now().UnixNano())) + return func(g *EngineGroup) *Engine { + return g.Slaves()[r.Intn(len(g.Slaves()))] + } +} + +// WeightRandomPolicy implmentes randomly chose the slave of slaves +func WeightRandomPolicy(weights []int) GroupPolicyHandler { + var rands = make([]int, 0, len(weights)) + for i := 0; i < len(weights); i++ { + for n := 0; n < weights[i]; n++ { + rands = append(rands, i) + } + } + var r = rand.New(rand.NewSource(time.Now().UnixNano())) + + return func(g *EngineGroup) *Engine { + var slaves = g.Slaves() + idx := rands[r.Intn(len(rands))] + if idx >= len(slaves) { + idx = len(slaves) - 1 + } + return slaves[idx] + } +} + +func RoundRobinPolicy() GroupPolicyHandler { + var pos = -1 + var lock sync.Mutex + return func(g *EngineGroup) *Engine { + var slaves = g.Slaves() + + lock.Lock() + defer lock.Unlock() + pos++ + if pos >= len(slaves) { + pos = 0 + } + + return slaves[pos] + } +} + +func WeightRoundRobinPolicy(weights []int) GroupPolicyHandler { + var rands = make([]int, 0, len(weights)) + for i := 0; i < len(weights); i++ { + for n := 0; n < weights[i]; n++ { + rands = append(rands, i) + } + } + var pos = -1 + var lock sync.Mutex + + return func(g *EngineGroup) *Engine { + var slaves = g.Slaves() + lock.Lock() + defer lock.Unlock() + pos++ + if pos >= len(rands) { + pos = 0 + } + + idx := rands[pos] + if idx >= len(slaves) { + idx = len(slaves) - 1 + } + return slaves[idx] + } +} + +// LeastConnPolicy implements GroupPolicy, every time will get the least connections slave +func LeastConnPolicy() GroupPolicyHandler { + return func(g *EngineGroup) *Engine { + var slaves = g.Slaves() + connections := 0 + idx := 0 + for i := 0; i < len(slaves); i++ { + openConnections := slaves[i].DB().Stats().OpenConnections + if i == 0 { + connections = openConnections + idx = i + } else if openConnections <= connections { + connections = openConnections + idx = i + } + } + return slaves[idx] + } +} diff --git a/vendor/xorm.io/xorm/engine_table.go b/vendor/xorm.io/xorm/engine_table.go new file mode 100644 index 0000000000..eb5aa850af --- /dev/null +++ b/vendor/xorm.io/xorm/engine_table.go @@ -0,0 +1,113 @@ +// Copyright 2018 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "fmt" + "reflect" + "strings" + + "xorm.io/core" +) + +// tbNameWithSchema will automatically add schema prefix on table name +func (engine *Engine) tbNameWithSchema(v string) string { + // Add schema name as prefix of table name. + // Only for postgres database. + if engine.dialect.DBType() == core.POSTGRES && + engine.dialect.URI().Schema != "" && + engine.dialect.URI().Schema != postgresPublicSchema && + strings.Index(v, ".") == -1 { + return engine.dialect.URI().Schema + "." + v + } + return v +} + +// TableName returns table name with schema prefix if has +func (engine *Engine) TableName(bean interface{}, includeSchema ...bool) string { + tbName := engine.tbNameNoSchema(bean) + if len(includeSchema) > 0 && includeSchema[0] { + tbName = engine.tbNameWithSchema(tbName) + } + + return tbName +} + +// tbName get some table's table name +func (session *Session) tbNameNoSchema(table *core.Table) string { + if len(session.statement.AltTableName) > 0 { + return session.statement.AltTableName + } + + return table.Name +} + +func (engine *Engine) tbNameForMap(v reflect.Value) string { + if v.Type().Implements(tpTableName) { + return v.Interface().(TableName).TableName() + } + if v.Kind() == reflect.Ptr { + v = v.Elem() + if v.Type().Implements(tpTableName) { + return v.Interface().(TableName).TableName() + } + } + + return engine.TableMapper.Obj2Table(v.Type().Name()) +} + +func (engine *Engine) tbNameNoSchema(tablename interface{}) string { + switch tablename.(type) { + case []string: + t := tablename.([]string) + if len(t) > 1 { + return fmt.Sprintf("%v AS %v", engine.Quote(t[0]), engine.Quote(t[1])) + } else if len(t) == 1 { + return engine.Quote(t[0]) + } + case []interface{}: + t := tablename.([]interface{}) + l := len(t) + var table string + if l > 0 { + f := t[0] + switch f.(type) { + case string: + table = f.(string) + case TableName: + table = f.(TableName).TableName() + default: + v := rValue(f) + t := v.Type() + if t.Kind() == reflect.Struct { + table = engine.tbNameForMap(v) + } else { + table = engine.Quote(fmt.Sprintf("%v", f)) + } + } + } + if l > 1 { + return fmt.Sprintf("%v AS %v", engine.Quote(table), + engine.Quote(fmt.Sprintf("%v", t[1]))) + } else if l == 1 { + return engine.Quote(table) + } + case TableName: + return tablename.(TableName).TableName() + case string: + return tablename.(string) + case reflect.Value: + v := tablename.(reflect.Value) + return engine.tbNameForMap(v) + default: + v := rValue(tablename) + t := v.Type() + if t.Kind() == reflect.Struct { + return engine.tbNameForMap(v) + } + return engine.Quote(fmt.Sprintf("%v", tablename)) + } + return "" +} diff --git a/vendor/xorm.io/xorm/error.go b/vendor/xorm.io/xorm/error.go new file mode 100644 index 0000000000..a67527acda --- /dev/null +++ b/vendor/xorm.io/xorm/error.go @@ -0,0 +1,51 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" +) + +var ( + // ErrParamsType params error + ErrParamsType = errors.New("Params type error") + // ErrTableNotFound table not found error + ErrTableNotFound = errors.New("Table not found") + // ErrUnSupportedType unsupported error + ErrUnSupportedType = errors.New("Unsupported type error") + // ErrNotExist record does not exist error + ErrNotExist = errors.New("Record does not exist") + // ErrCacheFailed cache failed error + ErrCacheFailed = errors.New("Cache failed") + // ErrNeedDeletedCond delete needs less one condition error + ErrNeedDeletedCond = errors.New("Delete action needs at least one condition") + // ErrNotImplemented not implemented + ErrNotImplemented = errors.New("Not implemented") + // ErrConditionType condition type unsupported + ErrConditionType = errors.New("Unsupported condition type") + // ErrUnSupportedSQLType parameter of SQL is not supported + ErrUnSupportedSQLType = errors.New("unsupported sql type") +) + +// ErrFieldIsNotExist columns does not exist +type ErrFieldIsNotExist struct { + FieldName string + TableName string +} + +func (e ErrFieldIsNotExist) Error() string { + return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName) +} + +// ErrFieldIsNotValid is not valid +type ErrFieldIsNotValid struct { + FieldName string + TableName string +} + +func (e ErrFieldIsNotValid) Error() string { + return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName) +} diff --git a/vendor/xorm.io/xorm/gen_reserved.sh b/vendor/xorm.io/xorm/gen_reserved.sh new file mode 100644 index 0000000000..434a1bfcb0 --- /dev/null +++ b/vendor/xorm.io/xorm/gen_reserved.sh @@ -0,0 +1,6 @@ +#!/bin/bash +if [ -f $1 ];then + cat $1| awk '{printf("\""$1"\":true,\n")}' +else + echo "argument $1 if not a file!" +fi diff --git a/vendor/xorm.io/xorm/go.mod b/vendor/xorm.io/xorm/go.mod new file mode 100644 index 0000000000..6d8b58f41a --- /dev/null +++ b/vendor/xorm.io/xorm/go.mod @@ -0,0 +1,15 @@ +module xorm.io/xorm + +go 1.11 + +require ( + github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 + github.com/go-sql-driver/mysql v1.4.1 + github.com/kr/pretty v0.1.0 // indirect + github.com/lib/pq v1.0.0 + github.com/mattn/go-sqlite3 v1.10.0 + github.com/stretchr/testify v1.4.0 + github.com/ziutek/mymysql v1.5.4 + xorm.io/builder v0.3.6 + xorm.io/core v0.7.2 +) diff --git a/vendor/xorm.io/xorm/go.sum b/vendor/xorm.io/xorm/go.sum new file mode 100644 index 0000000000..2102cc5b7a --- /dev/null +++ b/vendor/xorm.io/xorm/go.sum @@ -0,0 +1,149 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= +cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o= +github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= +github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw= +google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= +xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= +xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw= +xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= diff --git a/vendor/xorm.io/xorm/helpers.go b/vendor/xorm.io/xorm/helpers.go new file mode 100644 index 0000000000..a31e922c0b --- /dev/null +++ b/vendor/xorm.io/xorm/helpers.go @@ -0,0 +1,332 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "reflect" + "sort" + "strconv" + "strings" + + "xorm.io/core" +) + +// str2PK convert string value to primary key value according to tp +func str2PKValue(s string, tp reflect.Type) (reflect.Value, error) { + var err error + var result interface{} + var defReturn = reflect.Zero(tp) + + switch tp.Kind() { + case reflect.Int: + result, err = strconv.Atoi(s) + if err != nil { + return defReturn, fmt.Errorf("convert %s as int: %s", s, err.Error()) + } + case reflect.Int8: + x, err := strconv.Atoi(s) + if err != nil { + return defReturn, fmt.Errorf("convert %s as int8: %s", s, err.Error()) + } + result = int8(x) + case reflect.Int16: + x, err := strconv.Atoi(s) + if err != nil { + return defReturn, fmt.Errorf("convert %s as int16: %s", s, err.Error()) + } + result = int16(x) + case reflect.Int32: + x, err := strconv.Atoi(s) + if err != nil { + return defReturn, fmt.Errorf("convert %s as int32: %s", s, err.Error()) + } + result = int32(x) + case reflect.Int64: + result, err = strconv.ParseInt(s, 10, 64) + if err != nil { + return defReturn, fmt.Errorf("convert %s as int64: %s", s, err.Error()) + } + case reflect.Uint: + x, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return defReturn, fmt.Errorf("convert %s as uint: %s", s, err.Error()) + } + result = uint(x) + case reflect.Uint8: + x, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return defReturn, fmt.Errorf("convert %s as uint8: %s", s, err.Error()) + } + result = uint8(x) + case reflect.Uint16: + x, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return defReturn, fmt.Errorf("convert %s as uint16: %s", s, err.Error()) + } + result = uint16(x) + case reflect.Uint32: + x, err := strconv.ParseUint(s, 10, 64) + if err != nil { + return defReturn, fmt.Errorf("convert %s as uint32: %s", s, err.Error()) + } + result = uint32(x) + case reflect.Uint64: + result, err = strconv.ParseUint(s, 10, 64) + if err != nil { + return defReturn, fmt.Errorf("convert %s as uint64: %s", s, err.Error()) + } + case reflect.String: + result = s + default: + return defReturn, errors.New("unsupported convert type") + } + return reflect.ValueOf(result).Convert(tp), nil +} + +func str2PK(s string, tp reflect.Type) (interface{}, error) { + v, err := str2PKValue(s, tp) + if err != nil { + return nil, err + } + return v.Interface(), nil +} + +func splitTag(tag string) (tags []string) { + tag = strings.TrimSpace(tag) + var hasQuote = false + var lastIdx = 0 + for i, t := range tag { + if t == '\'' { + hasQuote = !hasQuote + } else if t == ' ' { + if lastIdx < i && !hasQuote { + tags = append(tags, strings.TrimSpace(tag[lastIdx:i])) + lastIdx = i + 1 + } + } + } + if lastIdx < len(tag) { + tags = append(tags, strings.TrimSpace(tag[lastIdx:])) + } + return +} + +type zeroable interface { + IsZero() bool +} + +func isZero(k interface{}) bool { + switch k.(type) { + case int: + return k.(int) == 0 + case int8: + return k.(int8) == 0 + case int16: + return k.(int16) == 0 + case int32: + return k.(int32) == 0 + case int64: + return k.(int64) == 0 + case uint: + return k.(uint) == 0 + case uint8: + return k.(uint8) == 0 + case uint16: + return k.(uint16) == 0 + case uint32: + return k.(uint32) == 0 + case uint64: + return k.(uint64) == 0 + case float32: + return k.(float32) == 0 + case float64: + return k.(float64) == 0 + case bool: + return k.(bool) == false + case string: + return k.(string) == "" + case zeroable: + return k.(zeroable).IsZero() + } + return false +} + +func isStructZero(v reflect.Value) bool { + if !v.IsValid() { + return true + } + + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + switch field.Kind() { + case reflect.Ptr: + field = field.Elem() + fallthrough + case reflect.Struct: + if !isStructZero(field) { + return false + } + default: + if field.CanInterface() && !isZero(field.Interface()) { + return false + } + } + } + return true +} + +func isArrayValueZero(v reflect.Value) bool { + if !v.IsValid() || v.Len() == 0 { + return true + } + + for i := 0; i < v.Len(); i++ { + if !isZero(v.Index(i).Interface()) { + return false + } + } + + return true +} + +func int64ToIntValue(id int64, tp reflect.Type) reflect.Value { + var v interface{} + kind := tp.Kind() + + if kind == reflect.Ptr { + kind = tp.Elem().Kind() + } + + switch kind { + case reflect.Int16: + temp := int16(id) + v = &temp + case reflect.Int32: + temp := int32(id) + v = &temp + case reflect.Int: + temp := int(id) + v = &temp + case reflect.Int64: + temp := id + v = &temp + case reflect.Uint16: + temp := uint16(id) + v = &temp + case reflect.Uint32: + temp := uint32(id) + v = &temp + case reflect.Uint64: + temp := uint64(id) + v = &temp + case reflect.Uint: + temp := uint(id) + v = &temp + } + + if tp.Kind() == reflect.Ptr { + return reflect.ValueOf(v).Convert(tp) + } + return reflect.ValueOf(v).Elem().Convert(tp) +} + +func int64ToInt(id int64, tp reflect.Type) interface{} { + return int64ToIntValue(id, tp).Interface() +} + +func isPKZero(pk core.PK) bool { + for _, k := range pk { + if isZero(k) { + return true + } + } + return false +} + +func indexNoCase(s, sep string) int { + return strings.Index(strings.ToLower(s), strings.ToLower(sep)) +} + +func splitNoCase(s, sep string) []string { + idx := indexNoCase(s, sep) + if idx < 0 { + return []string{s} + } + return strings.Split(s, s[idx:idx+len(sep)]) +} + +func splitNNoCase(s, sep string, n int) []string { + idx := indexNoCase(s, sep) + if idx < 0 { + return []string{s} + } + return strings.SplitN(s, s[idx:idx+len(sep)], n) +} + +func makeArray(elem string, count int) []string { + res := make([]string, count) + for i := 0; i < count; i++ { + res[i] = elem + } + return res +} + +func rValue(bean interface{}) reflect.Value { + return reflect.Indirect(reflect.ValueOf(bean)) +} + +func rType(bean interface{}) reflect.Type { + sliceValue := reflect.Indirect(reflect.ValueOf(bean)) + // return reflect.TypeOf(sliceValue.Interface()) + return sliceValue.Type() +} + +func structName(v reflect.Type) string { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + return v.Name() +} + +func sliceEq(left, right []string) bool { + if len(left) != len(right) { + return false + } + sort.Sort(sort.StringSlice(left)) + sort.Sort(sort.StringSlice(right)) + for i := 0; i < len(left); i++ { + if left[i] != right[i] { + return false + } + } + return true +} + +func indexName(tableName, idxName string) string { + return fmt.Sprintf("IDX_%v_%v", tableName, idxName) +} + +func eraseAny(value string, strToErase ...string) string { + if len(strToErase) == 0 { + return value + } + var replaceSeq []string + for _, s := range strToErase { + replaceSeq = append(replaceSeq, s, "") + } + + replacer := strings.NewReplacer(replaceSeq...) + + return replacer.Replace(value) +} + +func quoteColumns(cols []string, quoteFunc func(string) string, sep string) string { + for i := range cols { + cols[i] = quoteFunc(cols[i]) + } + return strings.Join(cols, sep+" ") +} diff --git a/vendor/xorm.io/xorm/helpler_time.go b/vendor/xorm.io/xorm/helpler_time.go new file mode 100644 index 0000000000..f4013e27e1 --- /dev/null +++ b/vendor/xorm.io/xorm/helpler_time.go @@ -0,0 +1,21 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import "time" + +const ( + zeroTime0 = "0000-00-00 00:00:00" + zeroTime1 = "0001-01-01 00:00:00" +) + +func formatTime(t time.Time) string { + return t.Format("2006-01-02 15:04:05") +} + +func isTimeZero(t time.Time) bool { + return t.IsZero() || formatTime(t) == zeroTime0 || + formatTime(t) == zeroTime1 +} diff --git a/vendor/xorm.io/xorm/interface.go b/vendor/xorm.io/xorm/interface.go new file mode 100644 index 0000000000..a564db1260 --- /dev/null +++ b/vendor/xorm.io/xorm/interface.go @@ -0,0 +1,118 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "context" + "database/sql" + "reflect" + "time" + + "xorm.io/core" +) + +// Interface defines the interface which Engine, EngineGroup and Session will implementate. +type Interface interface { + AllCols() *Session + Alias(alias string) *Session + Asc(colNames ...string) *Session + BufferSize(size int) *Session + Cols(columns ...string) *Session + Count(...interface{}) (int64, error) + CreateIndexes(bean interface{}) error + CreateUniques(bean interface{}) error + Decr(column string, arg ...interface{}) *Session + Desc(...string) *Session + Delete(interface{}) (int64, error) + Distinct(columns ...string) *Session + DropIndexes(bean interface{}) error + Exec(sqlOrArgs ...interface{}) (sql.Result, error) + Exist(bean ...interface{}) (bool, error) + Find(interface{}, ...interface{}) error + FindAndCount(interface{}, ...interface{}) (int64, error) + Get(interface{}) (bool, error) + GroupBy(keys string) *Session + ID(interface{}) *Session + In(string, ...interface{}) *Session + Incr(column string, arg ...interface{}) *Session + Insert(...interface{}) (int64, error) + InsertOne(interface{}) (int64, error) + IsTableEmpty(bean interface{}) (bool, error) + IsTableExist(beanOrTableName interface{}) (bool, error) + Iterate(interface{}, IterFunc) error + Limit(int, ...int) *Session + MustCols(columns ...string) *Session + NoAutoCondition(...bool) *Session + NotIn(string, ...interface{}) *Session + Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session + Omit(columns ...string) *Session + OrderBy(order string) *Session + Ping() error + Query(sqlOrArgs ...interface{}) (resultsSlice []map[string][]byte, err error) + QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) + QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) + Rows(bean interface{}) (*Rows, error) + SetExpr(string, interface{}) *Session + SQL(interface{}, ...interface{}) *Session + Sum(bean interface{}, colName string) (float64, error) + SumInt(bean interface{}, colName string) (int64, error) + Sums(bean interface{}, colNames ...string) ([]float64, error) + SumsInt(bean interface{}, colNames ...string) ([]int64, error) + Table(tableNameOrBean interface{}) *Session + Unscoped() *Session + Update(bean interface{}, condiBeans ...interface{}) (int64, error) + UseBool(...string) *Session + Where(interface{}, ...interface{}) *Session +} + +// EngineInterface defines the interface which Engine, EngineGroup will implementate. +type EngineInterface interface { + Interface + + Before(func(interface{})) *Session + Charset(charset string) *Session + ClearCache(...interface{}) error + Context(context.Context) *Session + CreateTables(...interface{}) error + DBMetas() ([]*core.Table, error) + Dialect() core.Dialect + DropTables(...interface{}) error + DumpAllToFile(fp string, tp ...core.DbType) error + GetCacher(string) core.Cacher + GetColumnMapper() core.IMapper + GetDefaultCacher() core.Cacher + GetTableMapper() core.IMapper + GetTZDatabase() *time.Location + GetTZLocation() *time.Location + MapCacher(interface{}, core.Cacher) error + NewSession() *Session + NoAutoTime() *Session + Quote(string) string + SetCacher(string, core.Cacher) + SetConnMaxLifetime(time.Duration) + SetDefaultCacher(core.Cacher) + SetLogger(logger core.ILogger) + SetLogLevel(core.LogLevel) + SetMapper(core.IMapper) + SetMaxOpenConns(int) + SetMaxIdleConns(int) + SetSchema(string) + SetTZDatabase(tz *time.Location) + SetTZLocation(tz *time.Location) + ShowExecTime(...bool) + ShowSQL(show ...bool) + Sync(...interface{}) error + Sync2(...interface{}) error + StoreEngine(storeEngine string) *Session + TableInfo(bean interface{}) *Table + TableName(interface{}, ...bool) string + UnMapType(reflect.Type) +} + +var ( + _ Interface = &Session{} + _ EngineInterface = &Engine{} + _ EngineInterface = &EngineGroup{} +) diff --git a/vendor/xorm.io/xorm/json.go b/vendor/xorm.io/xorm/json.go new file mode 100644 index 0000000000..fdb6ce5654 --- /dev/null +++ b/vendor/xorm.io/xorm/json.go @@ -0,0 +1,31 @@ +// Copyright 2019 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import "encoding/json" + +// JSONInterface represents an interface to handle json data +type JSONInterface interface { + Marshal(v interface{}) ([]byte, error) + Unmarshal(data []byte, v interface{}) error +} + +var ( + // DefaultJSONHandler default json handler + DefaultJSONHandler JSONInterface = StdJSON{} +) + +// StdJSON implements JSONInterface via encoding/json +type StdJSON struct{} + +// Marshal implements JSONInterface +func (StdJSON) Marshal(v interface{}) ([]byte, error) { + return json.Marshal(v) +} + +// Unmarshal implements JSONInterface +func (StdJSON) Unmarshal(data []byte, v interface{}) error { + return json.Unmarshal(data, v) +} diff --git a/vendor/xorm.io/xorm/logger.go b/vendor/xorm.io/xorm/logger.go new file mode 100644 index 0000000000..7b26e77f3b --- /dev/null +++ b/vendor/xorm.io/xorm/logger.go @@ -0,0 +1,187 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "fmt" + "io" + "log" + + "xorm.io/core" +) + +// default log options +const ( + DEFAULT_LOG_PREFIX = "[xorm]" + DEFAULT_LOG_FLAG = log.Ldate | log.Lmicroseconds + DEFAULT_LOG_LEVEL = core.LOG_DEBUG +) + +var _ core.ILogger = DiscardLogger{} + +// DiscardLogger don't log implementation for core.ILogger +type DiscardLogger struct{} + +// Debug empty implementation +func (DiscardLogger) Debug(v ...interface{}) {} + +// Debugf empty implementation +func (DiscardLogger) Debugf(format string, v ...interface{}) {} + +// Error empty implementation +func (DiscardLogger) Error(v ...interface{}) {} + +// Errorf empty implementation +func (DiscardLogger) Errorf(format string, v ...interface{}) {} + +// Info empty implementation +func (DiscardLogger) Info(v ...interface{}) {} + +// Infof empty implementation +func (DiscardLogger) Infof(format string, v ...interface{}) {} + +// Warn empty implementation +func (DiscardLogger) Warn(v ...interface{}) {} + +// Warnf empty implementation +func (DiscardLogger) Warnf(format string, v ...interface{}) {} + +// Level empty implementation +func (DiscardLogger) Level() core.LogLevel { + return core.LOG_UNKNOWN +} + +// SetLevel empty implementation +func (DiscardLogger) SetLevel(l core.LogLevel) {} + +// ShowSQL empty implementation +func (DiscardLogger) ShowSQL(show ...bool) {} + +// IsShowSQL empty implementation +func (DiscardLogger) IsShowSQL() bool { + return false +} + +// SimpleLogger is the default implment of core.ILogger +type SimpleLogger struct { + DEBUG *log.Logger + ERR *log.Logger + INFO *log.Logger + WARN *log.Logger + level core.LogLevel + showSQL bool +} + +var _ core.ILogger = &SimpleLogger{} + +// NewSimpleLogger use a special io.Writer as logger output +func NewSimpleLogger(out io.Writer) *SimpleLogger { + return NewSimpleLogger2(out, DEFAULT_LOG_PREFIX, DEFAULT_LOG_FLAG) +} + +// NewSimpleLogger2 let you customrize your logger prefix and flag +func NewSimpleLogger2(out io.Writer, prefix string, flag int) *SimpleLogger { + return NewSimpleLogger3(out, prefix, flag, DEFAULT_LOG_LEVEL) +} + +// NewSimpleLogger3 let you customrize your logger prefix and flag and logLevel +func NewSimpleLogger3(out io.Writer, prefix string, flag int, l core.LogLevel) *SimpleLogger { + return &SimpleLogger{ + DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), flag), + ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag), + INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag), + WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag), + level: l, + } +} + +// Error implement core.ILogger +func (s *SimpleLogger) Error(v ...interface{}) { + if s.level <= core.LOG_ERR { + s.ERR.Output(2, fmt.Sprint(v...)) + } + return +} + +// Errorf implement core.ILogger +func (s *SimpleLogger) Errorf(format string, v ...interface{}) { + if s.level <= core.LOG_ERR { + s.ERR.Output(2, fmt.Sprintf(format, v...)) + } + return +} + +// Debug implement core.ILogger +func (s *SimpleLogger) Debug(v ...interface{}) { + if s.level <= core.LOG_DEBUG { + s.DEBUG.Output(2, fmt.Sprint(v...)) + } + return +} + +// Debugf implement core.ILogger +func (s *SimpleLogger) Debugf(format string, v ...interface{}) { + if s.level <= core.LOG_DEBUG { + s.DEBUG.Output(2, fmt.Sprintf(format, v...)) + } + return +} + +// Info implement core.ILogger +func (s *SimpleLogger) Info(v ...interface{}) { + if s.level <= core.LOG_INFO { + s.INFO.Output(2, fmt.Sprint(v...)) + } + return +} + +// Infof implement core.ILogger +func (s *SimpleLogger) Infof(format string, v ...interface{}) { + if s.level <= core.LOG_INFO { + s.INFO.Output(2, fmt.Sprintf(format, v...)) + } + return +} + +// Warn implement core.ILogger +func (s *SimpleLogger) Warn(v ...interface{}) { + if s.level <= core.LOG_WARNING { + s.WARN.Output(2, fmt.Sprint(v...)) + } + return +} + +// Warnf implement core.ILogger +func (s *SimpleLogger) Warnf(format string, v ...interface{}) { + if s.level <= core.LOG_WARNING { + s.WARN.Output(2, fmt.Sprintf(format, v...)) + } + return +} + +// Level implement core.ILogger +func (s *SimpleLogger) Level() core.LogLevel { + return s.level +} + +// SetLevel implement core.ILogger +func (s *SimpleLogger) SetLevel(l core.LogLevel) { + s.level = l + return +} + +// ShowSQL implement core.ILogger +func (s *SimpleLogger) ShowSQL(show ...bool) { + if len(show) == 0 { + s.showSQL = true + return + } + s.showSQL = show[0] +} + +// IsShowSQL implement core.ILogger +func (s *SimpleLogger) IsShowSQL() bool { + return s.showSQL +} diff --git a/vendor/xorm.io/xorm/pg_reserved.txt b/vendor/xorm.io/xorm/pg_reserved.txt new file mode 100644 index 0000000000..720ed377ba --- /dev/null +++ b/vendor/xorm.io/xorm/pg_reserved.txt @@ -0,0 +1,746 @@ +A non-reserved non-reserved +ABORT non-reserved +ABS reserved reserved +ABSENT non-reserved non-reserved +ABSOLUTE non-reserved non-reserved non-reserved reserved +ACCESS non-reserved +ACCORDING non-reserved non-reserved +ACTION non-reserved non-reserved non-reserved reserved +ADA non-reserved non-reserved non-reserved +ADD non-reserved non-reserved non-reserved reserved +ADMIN non-reserved non-reserved non-reserved +AFTER non-reserved non-reserved non-reserved +AGGREGATE non-reserved +ALL reserved reserved reserved reserved +ALLOCATE reserved reserved reserved +ALSO non-reserved +ALTER non-reserved reserved reserved reserved +ALWAYS non-reserved non-reserved non-reserved +ANALYSE reserved +ANALYZE reserved +AND reserved reserved reserved reserved +ANY reserved reserved reserved reserved +ARE reserved reserved reserved +ARRAY reserved reserved reserved +ARRAY_AGG reserved reserved +ARRAY_MAX_CARDINALITY reserved +AS reserved reserved reserved reserved +ASC reserved non-reserved non-reserved reserved +ASENSITIVE reserved reserved +ASSERTION non-reserved non-reserved non-reserved reserved +ASSIGNMENT non-reserved non-reserved non-reserved +ASYMMETRIC reserved reserved reserved +AT non-reserved reserved reserved reserved +ATOMIC reserved reserved +ATTRIBUTE non-reserved non-reserved non-reserved +ATTRIBUTES non-reserved non-reserved +AUTHORIZATION reserved (can be function or type) reserved reserved reserved +AVG reserved reserved reserved +BACKWARD non-reserved +BASE64 non-reserved non-reserved +BEFORE non-reserved non-reserved non-reserved +BEGIN non-reserved reserved reserved reserved +BEGIN_FRAME reserved +BEGIN_PARTITION reserved +BERNOULLI non-reserved non-reserved +BETWEEN non-reserved (cannot be function or type) reserved reserved reserved +BIGINT non-reserved (cannot be function or type) reserved reserved +BINARY reserved (can be function or type) reserved reserved +BIT non-reserved (cannot be function or type) reserved +BIT_LENGTH reserved +BLOB reserved reserved +BLOCKED non-reserved non-reserved +BOM non-reserved non-reserved +BOOLEAN non-reserved (cannot be function or type) reserved reserved +BOTH reserved reserved reserved reserved +BREADTH non-reserved non-reserved +BY non-reserved reserved reserved reserved +C non-reserved non-reserved non-reserved +CACHE non-reserved +CALL reserved reserved +CALLED non-reserved reserved reserved +CARDINALITY reserved reserved +CASCADE non-reserved non-reserved non-reserved reserved +CASCADED non-reserved reserved reserved reserved +CASE reserved reserved reserved reserved +CAST reserved reserved reserved reserved +CATALOG non-reserved non-reserved non-reserved reserved +CATALOG_NAME non-reserved non-reserved non-reserved +CEIL reserved reserved +CEILING reserved reserved +CHAIN non-reserved non-reserved non-reserved +CHAR non-reserved (cannot be function or type) reserved reserved reserved +CHARACTER non-reserved (cannot be function or type) reserved reserved reserved +CHARACTERISTICS non-reserved non-reserved non-reserved +CHARACTERS non-reserved non-reserved +CHARACTER_LENGTH reserved reserved reserved +CHARACTER_SET_CATALOG non-reserved non-reserved non-reserved +CHARACTER_SET_NAME non-reserved non-reserved non-reserved +CHARACTER_SET_SCHEMA non-reserved non-reserved non-reserved +CHAR_LENGTH reserved reserved reserved +CHECK reserved reserved reserved reserved +CHECKPOINT non-reserved +CLASS non-reserved +CLASS_ORIGIN non-reserved non-reserved non-reserved +CLOB reserved reserved +CLOSE non-reserved reserved reserved reserved +CLUSTER non-reserved +COALESCE non-reserved (cannot be function or type) reserved reserved reserved +COBOL non-reserved non-reserved non-reserved +COLLATE reserved reserved reserved reserved +COLLATION reserved (can be function or type) non-reserved non-reserved reserved +COLLATION_CATALOG non-reserved non-reserved non-reserved +COLLATION_NAME non-reserved non-reserved non-reserved +COLLATION_SCHEMA non-reserved non-reserved non-reserved +COLLECT reserved reserved +COLUMN reserved reserved reserved reserved +COLUMNS non-reserved non-reserved +COLUMN_NAME non-reserved non-reserved non-reserved +COMMAND_FUNCTION non-reserved non-reserved non-reserved +COMMAND_FUNCTION_CODE non-reserved non-reserved +COMMENT non-reserved +COMMENTS non-reserved +COMMIT non-reserved reserved reserved reserved +COMMITTED non-reserved non-reserved non-reserved non-reserved +CONCURRENTLY reserved (can be function or type) +CONDITION reserved reserved +CONDITION_NUMBER non-reserved non-reserved non-reserved +CONFIGURATION non-reserved +CONNECT reserved reserved reserved +CONNECTION non-reserved non-reserved non-reserved reserved +CONNECTION_NAME non-reserved non-reserved non-reserved +CONSTRAINT reserved reserved reserved reserved +CONSTRAINTS non-reserved non-reserved non-reserved reserved +CONSTRAINT_CATALOG non-reserved non-reserved non-reserved +CONSTRAINT_NAME non-reserved non-reserved non-reserved +CONSTRAINT_SCHEMA non-reserved non-reserved non-reserved +CONSTRUCTOR non-reserved non-reserved +CONTAINS reserved non-reserved +CONTENT non-reserved non-reserved non-reserved +CONTINUE non-reserved non-reserved non-reserved reserved +CONTROL non-reserved non-reserved +CONVERSION non-reserved +CONVERT reserved reserved reserved +COPY non-reserved +CORR reserved reserved +CORRESPONDING reserved reserved reserved +COST non-reserved +COUNT reserved reserved reserved +COVAR_POP reserved reserved +COVAR_SAMP reserved reserved +CREATE reserved reserved reserved reserved +CROSS reserved (can be function or type) reserved reserved reserved +CSV non-reserved +CUBE reserved reserved +CUME_DIST reserved reserved +CURRENT non-reserved reserved reserved reserved +CURRENT_CATALOG reserved reserved reserved +CURRENT_DATE reserved reserved reserved reserved +CURRENT_DEFAULT_TRANSFORM_GROUP reserved reserved +CURRENT_PATH reserved reserved +CURRENT_ROLE reserved reserved reserved +CURRENT_ROW reserved +CURRENT_SCHEMA reserved (can be function or type) reserved reserved +CURRENT_TIME reserved reserved reserved reserved +CURRENT_TIMESTAMP reserved reserved reserved reserved +CURRENT_TRANSFORM_GROUP_FOR_TYPE reserved reserved +CURRENT_USER reserved reserved reserved reserved +CURSOR non-reserved reserved reserved reserved +CURSOR_NAME non-reserved non-reserved non-reserved +CYCLE non-reserved reserved reserved +DATA non-reserved non-reserved non-reserved non-reserved +DATABASE non-reserved +DATALINK reserved reserved +DATE reserved reserved reserved +DATETIME_INTERVAL_CODE non-reserved non-reserved non-reserved +DATETIME_INTERVAL_PRECISION non-reserved non-reserved non-reserved +DAY non-reserved reserved reserved reserved +DB non-reserved non-reserved +DEALLOCATE non-reserved reserved reserved reserved +DEC non-reserved (cannot be function or type) reserved reserved reserved +DECIMAL non-reserved (cannot be function or type) reserved reserved reserved +DECLARE non-reserved reserved reserved reserved +DEFAULT reserved reserved reserved reserved +DEFAULTS non-reserved non-reserved non-reserved +DEFERRABLE reserved non-reserved non-reserved reserved +DEFERRED non-reserved non-reserved non-reserved reserved +DEFINED non-reserved non-reserved +DEFINER non-reserved non-reserved non-reserved +DEGREE non-reserved non-reserved +DELETE non-reserved reserved reserved reserved +DELIMITER non-reserved +DELIMITERS non-reserved +DENSE_RANK reserved reserved +DEPTH non-reserved non-reserved +DEREF reserved reserved +DERIVED non-reserved non-reserved +DESC reserved non-reserved non-reserved reserved +DESCRIBE reserved reserved reserved +DESCRIPTOR non-reserved non-reserved reserved +DETERMINISTIC reserved reserved +DIAGNOSTICS non-reserved non-reserved reserved +DICTIONARY non-reserved +DISABLE non-reserved +DISCARD non-reserved +DISCONNECT reserved reserved reserved +DISPATCH non-reserved non-reserved +DISTINCT reserved reserved reserved reserved +DLNEWCOPY reserved reserved +DLPREVIOUSCOPY reserved reserved +DLURLCOMPLETE reserved reserved +DLURLCOMPLETEONLY reserved reserved +DLURLCOMPLETEWRITE reserved reserved +DLURLPATH reserved reserved +DLURLPATHONLY reserved reserved +DLURLPATHWRITE reserved reserved +DLURLSCHEME reserved reserved +DLURLSERVER reserved reserved +DLVALUE reserved reserved +DO reserved +DOCUMENT non-reserved non-reserved non-reserved +DOMAIN non-reserved non-reserved non-reserved reserved +DOUBLE non-reserved reserved reserved reserved +DROP non-reserved reserved reserved reserved +DYNAMIC reserved reserved +DYNAMIC_FUNCTION non-reserved non-reserved non-reserved +DYNAMIC_FUNCTION_CODE non-reserved non-reserved +EACH non-reserved reserved reserved +ELEMENT reserved reserved +ELSE reserved reserved reserved reserved +EMPTY non-reserved non-reserved +ENABLE non-reserved +ENCODING non-reserved non-reserved non-reserved +ENCRYPTED non-reserved +END reserved reserved reserved reserved +END-EXEC reserved reserved reserved +END_FRAME reserved +END_PARTITION reserved +ENFORCED non-reserved +ENUM non-reserved +EQUALS reserved non-reserved +ESCAPE non-reserved reserved reserved reserved +EVENT non-reserved +EVERY reserved reserved +EXCEPT reserved reserved reserved reserved +EXCEPTION reserved +EXCLUDE non-reserved non-reserved non-reserved +EXCLUDING non-reserved non-reserved non-reserved +EXCLUSIVE non-reserved +EXEC reserved reserved reserved +EXECUTE non-reserved reserved reserved reserved +EXISTS non-reserved (cannot be function or type) reserved reserved reserved +EXP reserved reserved +EXPLAIN non-reserved +EXPRESSION non-reserved +EXTENSION non-reserved +EXTERNAL non-reserved reserved reserved reserved +EXTRACT non-reserved (cannot be function or type) reserved reserved reserved +FALSE reserved reserved reserved reserved +FAMILY non-reserved +FETCH reserved reserved reserved reserved +FILE non-reserved non-reserved +FILTER reserved reserved +FINAL non-reserved non-reserved +FIRST non-reserved non-reserved non-reserved reserved +FIRST_VALUE reserved reserved +FLAG non-reserved non-reserved +FLOAT non-reserved (cannot be function or type) reserved reserved reserved +FLOOR reserved reserved +FOLLOWING non-reserved non-reserved non-reserved +FOR reserved reserved reserved reserved +FORCE non-reserved +FOREIGN reserved reserved reserved reserved +FORTRAN non-reserved non-reserved non-reserved +FORWARD non-reserved +FOUND non-reserved non-reserved reserved +FRAME_ROW reserved +FREE reserved reserved +FREEZE reserved (can be function or type) +FROM reserved reserved reserved reserved +FS non-reserved non-reserved +FULL reserved (can be function or type) reserved reserved reserved +FUNCTION non-reserved reserved reserved +FUNCTIONS non-reserved +FUSION reserved reserved +G non-reserved non-reserved +GENERAL non-reserved non-reserved +GENERATED non-reserved non-reserved +GET reserved reserved reserved +GLOBAL non-reserved reserved reserved reserved +GO non-reserved non-reserved reserved +GOTO non-reserved non-reserved reserved +GRANT reserved reserved reserved reserved +GRANTED non-reserved non-reserved non-reserved +GREATEST non-reserved (cannot be function or type) +GROUP reserved reserved reserved reserved +GROUPING reserved reserved +GROUPS reserved +HANDLER non-reserved +HAVING reserved reserved reserved reserved +HEADER non-reserved +HEX non-reserved non-reserved +HIERARCHY non-reserved non-reserved +HOLD non-reserved reserved reserved +HOUR non-reserved reserved reserved reserved +ID non-reserved non-reserved +IDENTITY non-reserved reserved reserved reserved +IF non-reserved +IGNORE non-reserved non-reserved +ILIKE reserved (can be function or type) +IMMEDIATE non-reserved non-reserved non-reserved reserved +IMMEDIATELY non-reserved +IMMUTABLE non-reserved +IMPLEMENTATION non-reserved non-reserved +IMPLICIT non-reserved +IMPORT reserved reserved +IN reserved reserved reserved reserved +INCLUDING non-reserved non-reserved non-reserved +INCREMENT non-reserved non-reserved non-reserved +INDENT non-reserved non-reserved +INDEX non-reserved +INDEXES non-reserved +INDICATOR reserved reserved reserved +INHERIT non-reserved +INHERITS non-reserved +INITIALLY reserved non-reserved non-reserved reserved +INLINE non-reserved +INNER reserved (can be function or type) reserved reserved reserved +INOUT non-reserved (cannot be function or type) reserved reserved +INPUT non-reserved non-reserved non-reserved reserved +INSENSITIVE non-reserved reserved reserved reserved +INSERT non-reserved reserved reserved reserved +INSTANCE non-reserved non-reserved +INSTANTIABLE non-reserved non-reserved +INSTEAD non-reserved non-reserved non-reserved +INT non-reserved (cannot be function or type) reserved reserved reserved +INTEGER non-reserved (cannot be function or type) reserved reserved reserved +INTEGRITY non-reserved non-reserved +INTERSECT reserved reserved reserved reserved +INTERSECTION reserved reserved +INTERVAL non-reserved (cannot be function or type) reserved reserved reserved +INTO reserved reserved reserved reserved +INVOKER non-reserved non-reserved non-reserved +IS reserved (can be function or type) reserved reserved reserved +ISNULL reserved (can be function or type) +ISOLATION non-reserved non-reserved non-reserved reserved +JOIN reserved (can be function or type) reserved reserved reserved +K non-reserved non-reserved +KEY non-reserved non-reserved non-reserved reserved +KEY_MEMBER non-reserved non-reserved +KEY_TYPE non-reserved non-reserved +LABEL non-reserved +LAG reserved reserved +LANGUAGE non-reserved reserved reserved reserved +LARGE non-reserved reserved reserved +LAST non-reserved non-reserved non-reserved reserved +LAST_VALUE reserved reserved +LATERAL reserved reserved reserved +LC_COLLATE non-reserved +LC_CTYPE non-reserved +LEAD reserved reserved +LEADING reserved reserved reserved reserved +LEAKPROOF non-reserved +LEAST non-reserved (cannot be function or type) +LEFT reserved (can be function or type) reserved reserved reserved +LENGTH non-reserved non-reserved non-reserved +LEVEL non-reserved non-reserved non-reserved reserved +LIBRARY non-reserved non-reserved +LIKE reserved (can be function or type) reserved reserved reserved +LIKE_REGEX reserved reserved +LIMIT reserved non-reserved non-reserved +LINK non-reserved non-reserved +LISTEN non-reserved +LN reserved reserved +LOAD non-reserved +LOCAL non-reserved reserved reserved reserved +LOCALTIME reserved reserved reserved +LOCALTIMESTAMP reserved reserved reserved +LOCATION non-reserved non-reserved non-reserved +LOCATOR non-reserved non-reserved +LOCK non-reserved +LOWER reserved reserved reserved +M non-reserved non-reserved +MAP non-reserved non-reserved +MAPPING non-reserved non-reserved non-reserved +MATCH non-reserved reserved reserved reserved +MATCHED non-reserved non-reserved +MATERIALIZED non-reserved +MAX reserved reserved reserved +MAXVALUE non-reserved non-reserved non-reserved +MAX_CARDINALITY reserved +MEMBER reserved reserved +MERGE reserved reserved +MESSAGE_LENGTH non-reserved non-reserved non-reserved +MESSAGE_OCTET_LENGTH non-reserved non-reserved non-reserved +MESSAGE_TEXT non-reserved non-reserved non-reserved +METHOD reserved reserved +MIN reserved reserved reserved +MINUTE non-reserved reserved reserved reserved +MINVALUE non-reserved non-reserved non-reserved +MOD reserved reserved +MODE non-reserved +MODIFIES reserved reserved +MODULE reserved reserved reserved +MONTH non-reserved reserved reserved reserved +MORE non-reserved non-reserved non-reserved +MOVE non-reserved +MULTISET reserved reserved +MUMPS non-reserved non-reserved non-reserved +NAME non-reserved non-reserved non-reserved non-reserved +NAMES non-reserved non-reserved non-reserved reserved +NAMESPACE non-reserved non-reserved +NATIONAL non-reserved (cannot be function or type) reserved reserved reserved +NATURAL reserved (can be function or type) reserved reserved reserved +NCHAR non-reserved (cannot be function or type) reserved reserved reserved +NCLOB reserved reserved +NESTING non-reserved non-reserved +NEW reserved reserved +NEXT non-reserved non-reserved non-reserved reserved +NFC non-reserved non-reserved +NFD non-reserved non-reserved +NFKC non-reserved non-reserved +NFKD non-reserved non-reserved +NIL non-reserved non-reserved +NO non-reserved reserved reserved reserved +NONE non-reserved (cannot be function or type) reserved reserved +NORMALIZE reserved reserved +NORMALIZED non-reserved non-reserved +NOT reserved reserved reserved reserved +NOTHING non-reserved +NOTIFY non-reserved +NOTNULL reserved (can be function or type) +NOWAIT non-reserved +NTH_VALUE reserved reserved +NTILE reserved reserved +NULL reserved reserved reserved reserved +NULLABLE non-reserved non-reserved non-reserved +NULLIF non-reserved (cannot be function or type) reserved reserved reserved +NULLS non-reserved non-reserved non-reserved +NUMBER non-reserved non-reserved non-reserved +NUMERIC non-reserved (cannot be function or type) reserved reserved reserved +OBJECT non-reserved non-reserved non-reserved +OCCURRENCES_REGEX reserved reserved +OCTETS non-reserved non-reserved +OCTET_LENGTH reserved reserved reserved +OF non-reserved reserved reserved reserved +OFF non-reserved non-reserved non-reserved +OFFSET reserved reserved reserved +OIDS non-reserved +OLD reserved reserved +ON reserved reserved reserved reserved +ONLY reserved reserved reserved reserved +OPEN reserved reserved reserved +OPERATOR non-reserved +OPTION non-reserved non-reserved non-reserved reserved +OPTIONS non-reserved non-reserved non-reserved +OR reserved reserved reserved reserved +ORDER reserved reserved reserved reserved +ORDERING non-reserved non-reserved +ORDINALITY non-reserved non-reserved +OTHERS non-reserved non-reserved +OUT non-reserved (cannot be function or type) reserved reserved +OUTER reserved (can be function or type) reserved reserved reserved +OUTPUT non-reserved non-reserved reserved +OVER reserved (can be function or type) reserved reserved +OVERLAPS reserved (can be function or type) reserved reserved reserved +OVERLAY non-reserved (cannot be function or type) reserved reserved +OVERRIDING non-reserved non-reserved +OWNED non-reserved +OWNER non-reserved +P non-reserved non-reserved +PAD non-reserved non-reserved reserved +PARAMETER reserved reserved +PARAMETER_MODE non-reserved non-reserved +PARAMETER_NAME non-reserved non-reserved +PARAMETER_ORDINAL_POSITION non-reserved non-reserved +PARAMETER_SPECIFIC_CATALOG non-reserved non-reserved +PARAMETER_SPECIFIC_NAME non-reserved non-reserved +PARAMETER_SPECIFIC_SCHEMA non-reserved non-reserved +PARSER non-reserved +PARTIAL non-reserved non-reserved non-reserved reserved +PARTITION non-reserved reserved reserved +PASCAL non-reserved non-reserved non-reserved +PASSING non-reserved non-reserved non-reserved +PASSTHROUGH non-reserved non-reserved +PASSWORD non-reserved +PATH non-reserved non-reserved +PERCENT reserved +PERCENTILE_CONT reserved reserved +PERCENTILE_DISC reserved reserved +PERCENT_RANK reserved reserved +PERIOD reserved +PERMISSION non-reserved non-reserved +PLACING reserved non-reserved non-reserved +PLANS non-reserved +PLI non-reserved non-reserved non-reserved +PORTION reserved +POSITION non-reserved (cannot be function or type) reserved reserved reserved +POSITION_REGEX reserved reserved +POWER reserved reserved +PRECEDES reserved +PRECEDING non-reserved non-reserved non-reserved +PRECISION non-reserved (cannot be function or type) reserved reserved reserved +PREPARE non-reserved reserved reserved reserved +PREPARED non-reserved +PRESERVE non-reserved non-reserved non-reserved reserved +PRIMARY reserved reserved reserved reserved +PRIOR non-reserved non-reserved non-reserved reserved +PRIVILEGES non-reserved non-reserved non-reserved reserved +PROCEDURAL non-reserved +PROCEDURE non-reserved reserved reserved reserved +PROGRAM non-reserved +PUBLIC non-reserved non-reserved reserved +QUOTE non-reserved +RANGE non-reserved reserved reserved +RANK reserved reserved +READ non-reserved non-reserved non-reserved reserved +READS reserved reserved +REAL non-reserved (cannot be function or type) reserved reserved reserved +REASSIGN non-reserved +RECHECK non-reserved +RECOVERY non-reserved non-reserved +RECURSIVE non-reserved reserved reserved +REF non-reserved reserved reserved +REFERENCES reserved reserved reserved reserved +REFERENCING reserved reserved +REFRESH non-reserved +REGR_AVGX reserved reserved +REGR_AVGY reserved reserved +REGR_COUNT reserved reserved +REGR_INTERCEPT reserved reserved +REGR_R2 reserved reserved +REGR_SLOPE reserved reserved +REGR_SXX reserved reserved +REGR_SXY reserved reserved +REGR_SYY reserved reserved +REINDEX non-reserved +RELATIVE non-reserved non-reserved non-reserved reserved +RELEASE non-reserved reserved reserved +RENAME non-reserved +REPEATABLE non-reserved non-reserved non-reserved non-reserved +REPLACE non-reserved +REPLICA non-reserved +REQUIRING non-reserved non-reserved +RESET non-reserved +RESPECT non-reserved non-reserved +RESTART non-reserved non-reserved non-reserved +RESTORE non-reserved non-reserved +RESTRICT non-reserved non-reserved non-reserved reserved +RESULT reserved reserved +RETURN reserved reserved +RETURNED_CARDINALITY non-reserved non-reserved +RETURNED_LENGTH non-reserved non-reserved non-reserved +RETURNED_OCTET_LENGTH non-reserved non-reserved non-reserved +RETURNED_SQLSTATE non-reserved non-reserved non-reserved +RETURNING reserved non-reserved non-reserved +RETURNS non-reserved reserved reserved +REVOKE non-reserved reserved reserved reserved +RIGHT reserved (can be function or type) reserved reserved reserved +ROLE non-reserved non-reserved non-reserved +ROLLBACK non-reserved reserved reserved reserved +ROLLUP reserved reserved +ROUTINE non-reserved non-reserved +ROUTINE_CATALOG non-reserved non-reserved +ROUTINE_NAME non-reserved non-reserved +ROUTINE_SCHEMA non-reserved non-reserved +ROW non-reserved (cannot be function or type) reserved reserved +ROWS non-reserved reserved reserved reserved +ROW_COUNT non-reserved non-reserved non-reserved +ROW_NUMBER reserved reserved +RULE non-reserved +SAVEPOINT non-reserved reserved reserved +SCALE non-reserved non-reserved non-reserved +SCHEMA non-reserved non-reserved non-reserved reserved +SCHEMA_NAME non-reserved non-reserved non-reserved +SCOPE reserved reserved +SCOPE_CATALOG non-reserved non-reserved +SCOPE_NAME non-reserved non-reserved +SCOPE_SCHEMA non-reserved non-reserved +SCROLL non-reserved reserved reserved reserved +SEARCH non-reserved reserved reserved +SECOND non-reserved reserved reserved reserved +SECTION non-reserved non-reserved reserved +SECURITY non-reserved non-reserved non-reserved +SELECT reserved reserved reserved reserved +SELECTIVE non-reserved non-reserved +SELF non-reserved non-reserved +SENSITIVE reserved reserved +SEQUENCE non-reserved non-reserved non-reserved +SEQUENCES non-reserved +SERIALIZABLE non-reserved non-reserved non-reserved non-reserved +SERVER non-reserved non-reserved non-reserved +SERVER_NAME non-reserved non-reserved non-reserved +SESSION non-reserved non-reserved non-reserved reserved +SESSION_USER reserved reserved reserved reserved +SET non-reserved reserved reserved reserved +SETOF non-reserved (cannot be function or type) +SETS non-reserved non-reserved +SHARE non-reserved +SHOW non-reserved +SIMILAR reserved (can be function or type) reserved reserved +SIMPLE non-reserved non-reserved non-reserved +SIZE non-reserved non-reserved reserved +SMALLINT non-reserved (cannot be function or type) reserved reserved reserved +SNAPSHOT non-reserved +SOME reserved reserved reserved reserved +SOURCE non-reserved non-reserved +SPACE non-reserved non-reserved reserved +SPECIFIC reserved reserved +SPECIFICTYPE reserved reserved +SPECIFIC_NAME non-reserved non-reserved +SQL reserved reserved reserved +SQLCODE reserved +SQLERROR reserved +SQLEXCEPTION reserved reserved +SQLSTATE reserved reserved reserved +SQLWARNING reserved reserved +SQRT reserved reserved +STABLE non-reserved +STANDALONE non-reserved non-reserved non-reserved +START non-reserved reserved reserved +STATE non-reserved non-reserved +STATEMENT non-reserved non-reserved non-reserved +STATIC reserved reserved +STATISTICS non-reserved +STDDEV_POP reserved reserved +STDDEV_SAMP reserved reserved +STDIN non-reserved +STDOUT non-reserved +STORAGE non-reserved +STRICT non-reserved +STRIP non-reserved non-reserved non-reserved +STRUCTURE non-reserved non-reserved +STYLE non-reserved non-reserved +SUBCLASS_ORIGIN non-reserved non-reserved non-reserved +SUBMULTISET reserved reserved +SUBSTRING non-reserved (cannot be function or type) reserved reserved reserved +SUBSTRING_REGEX reserved reserved +SUCCEEDS reserved +SUM reserved reserved reserved +SYMMETRIC reserved reserved reserved +SYSID non-reserved +SYSTEM non-reserved reserved reserved +SYSTEM_TIME reserved +SYSTEM_USER reserved reserved reserved +T non-reserved non-reserved +TABLE reserved reserved reserved reserved +TABLES non-reserved +TABLESAMPLE reserved reserved +TABLESPACE non-reserved +TABLE_NAME non-reserved non-reserved non-reserved +TEMP non-reserved +TEMPLATE non-reserved +TEMPORARY non-reserved non-reserved non-reserved reserved +TEXT non-reserved +THEN reserved reserved reserved reserved +TIES non-reserved non-reserved +TIME non-reserved (cannot be function or type) reserved reserved reserved +TIMESTAMP non-reserved (cannot be function or type) reserved reserved reserved +TIMEZONE_HOUR reserved reserved reserved +TIMEZONE_MINUTE reserved reserved reserved +TO reserved reserved reserved reserved +TOKEN non-reserved non-reserved +TOP_LEVEL_COUNT non-reserved non-reserved +TRAILING reserved reserved reserved reserved +TRANSACTION non-reserved non-reserved non-reserved reserved +TRANSACTIONS_COMMITTED non-reserved non-reserved +TRANSACTIONS_ROLLED_BACK non-reserved non-reserved +TRANSACTION_ACTIVE non-reserved non-reserved +TRANSFORM non-reserved non-reserved +TRANSFORMS non-reserved non-reserved +TRANSLATE reserved reserved reserved +TRANSLATE_REGEX reserved reserved +TRANSLATION reserved reserved reserved +TREAT non-reserved (cannot be function or type) reserved reserved +TRIGGER non-reserved reserved reserved +TRIGGER_CATALOG non-reserved non-reserved +TRIGGER_NAME non-reserved non-reserved +TRIGGER_SCHEMA non-reserved non-reserved +TRIM non-reserved (cannot be function or type) reserved reserved reserved +TRIM_ARRAY reserved reserved +TRUE reserved reserved reserved reserved +TRUNCATE non-reserved reserved reserved +TRUSTED non-reserved +TYPE non-reserved non-reserved non-reserved non-reserved +TYPES non-reserved +UESCAPE reserved reserved +UNBOUNDED non-reserved non-reserved non-reserved +UNCOMMITTED non-reserved non-reserved non-reserved non-reserved +UNDER non-reserved non-reserved +UNENCRYPTED non-reserved +UNION reserved reserved reserved reserved +UNIQUE reserved reserved reserved reserved +UNKNOWN non-reserved reserved reserved reserved +UNLINK non-reserved non-reserved +UNLISTEN non-reserved +UNLOGGED non-reserved +UNNAMED non-reserved non-reserved non-reserved +UNNEST reserved reserved +UNTIL non-reserved +UNTYPED non-reserved non-reserved +UPDATE non-reserved reserved reserved reserved +UPPER reserved reserved reserved +URI non-reserved non-reserved +USAGE non-reserved non-reserved reserved +USER reserved reserved reserved reserved +USER_DEFINED_TYPE_CATALOG non-reserved non-reserved +USER_DEFINED_TYPE_CODE non-reserved non-reserved +USER_DEFINED_TYPE_NAME non-reserved non-reserved +USER_DEFINED_TYPE_SCHEMA non-reserved non-reserved +USING reserved reserved reserved reserved +VACUUM non-reserved +VALID non-reserved non-reserved non-reserved +VALIDATE non-reserved +VALIDATOR non-reserved +VALUE non-reserved reserved reserved reserved +VALUES non-reserved (cannot be function or type) reserved reserved reserved +VALUE_OF reserved +VARBINARY reserved reserved +VARCHAR non-reserved (cannot be function or type) reserved reserved reserved +VARIADIC reserved +VARYING non-reserved reserved reserved reserved +VAR_POP reserved reserved +VAR_SAMP reserved reserved +VERBOSE reserved (can be function or type) +VERSION non-reserved non-reserved non-reserved +VERSIONING reserved +VIEW non-reserved non-reserved non-reserved reserved +VOLATILE non-reserved +WHEN reserved reserved reserved reserved +WHENEVER reserved reserved reserved +WHERE reserved reserved reserved reserved +WHITESPACE non-reserved non-reserved non-reserved +WIDTH_BUCKET reserved reserved +WINDOW reserved reserved reserved +WITH reserved reserved reserved reserved +WITHIN reserved reserved +WITHOUT non-reserved reserved reserved +WORK non-reserved non-reserved non-reserved reserved +WRAPPER non-reserved non-reserved non-reserved +WRITE non-reserved non-reserved non-reserved reserved +XML non-reserved reserved reserved +XMLAGG reserved reserved +XMLATTRIBUTES non-reserved (cannot be function or type) reserved reserved +XMLBINARY reserved reserved +XMLCAST reserved reserved +XMLCOMMENT reserved reserved +XMLCONCAT non-reserved (cannot be function or type) reserved reserved +XMLDECLARATION non-reserved non-reserved +XMLDOCUMENT reserved reserved +XMLELEMENT non-reserved (cannot be function or type) reserved reserved +XMLEXISTS non-reserved (cannot be function or type) reserved reserved +XMLFOREST non-reserved (cannot be function or type) reserved reserved +XMLITERATE reserved reserved +XMLNAMESPACES reserved reserved +XMLPARSE non-reserved (cannot be function or type) reserved reserved +XMLPI non-reserved (cannot be function or type) reserved reserved +XMLQUERY reserved reserved +XMLROOT non-reserved (cannot be function or type) +XMLSCHEMA non-reserved non-reserved +XMLSERIALIZE non-reserved (cannot be function or type) reserved reserved +XMLTABLE reserved reserved +XMLTEXT reserved reserved +XMLVALIDATE reserved reserved +YEAR non-reserved reserved reserved reserved +YES non-reserved non-reserved non-reserved +ZONE non-reserved non-reserved non-reserved reserved \ No newline at end of file diff --git a/vendor/xorm.io/xorm/processors.go b/vendor/xorm.io/xorm/processors.go new file mode 100644 index 0000000000..dcd9c6ac0b --- /dev/null +++ b/vendor/xorm.io/xorm/processors.go @@ -0,0 +1,78 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +// BeforeInsertProcessor executed before an object is initially persisted to the database +type BeforeInsertProcessor interface { + BeforeInsert() +} + +// BeforeUpdateProcessor executed before an object is updated +type BeforeUpdateProcessor interface { + BeforeUpdate() +} + +// BeforeDeleteProcessor executed before an object is deleted +type BeforeDeleteProcessor interface { + BeforeDelete() +} + +// BeforeSetProcessor executed before data set to the struct fields +type BeforeSetProcessor interface { + BeforeSet(string, Cell) +} + +// AfterSetProcessor executed after data set to the struct fields +type AfterSetProcessor interface { + AfterSet(string, Cell) +} + +// AfterInsertProcessor executed after an object is persisted to the database +type AfterInsertProcessor interface { + AfterInsert() +} + +// AfterUpdateProcessor executed after an object has been updated +type AfterUpdateProcessor interface { + AfterUpdate() +} + +// AfterDeleteProcessor executed after an object has been deleted +type AfterDeleteProcessor interface { + AfterDelete() +} + +// AfterLoadProcessor executed after an ojbect has been loaded from database +type AfterLoadProcessor interface { + AfterLoad() +} + +// AfterLoadSessionProcessor executed after an ojbect has been loaded from database with session parameter +type AfterLoadSessionProcessor interface { + AfterLoad(*Session) +} + +type executedProcessorFunc func(*Session, interface{}) error + +type executedProcessor struct { + fun executedProcessorFunc + session *Session + bean interface{} +} + +func (executor *executedProcessor) execute() error { + return executor.fun(executor.session, executor.bean) +} + +func (session *Session) executeProcessors() error { + processors := session.afterProcessors + session.afterProcessors = make([]executedProcessor, 0) + for _, processor := range processors { + if err := processor.execute(); err != nil { + return err + } + } + return nil +} diff --git a/vendor/xorm.io/xorm/rows.go b/vendor/xorm.io/xorm/rows.go new file mode 100644 index 0000000000..bdd44589f8 --- /dev/null +++ b/vendor/xorm.io/xorm/rows.go @@ -0,0 +1,121 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "fmt" + "reflect" + + "xorm.io/core" +) + +// Rows rows wrapper a rows to +type Rows struct { + session *Session + rows *core.Rows + beanType reflect.Type + lastError error +} + +func newRows(session *Session, bean interface{}) (*Rows, error) { + rows := new(Rows) + rows.session = session + rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type() + + var sqlStr string + var args []interface{} + var err error + + if err = rows.session.statement.setRefBean(bean); err != nil { + return nil, err + } + + if len(session.statement.TableName()) <= 0 { + return nil, ErrTableNotFound + } + + if rows.session.statement.RawSQL == "" { + sqlStr, args, err = rows.session.statement.genGetSQL(bean) + if err != nil { + return nil, err + } + } else { + sqlStr = rows.session.statement.RawSQL + args = rows.session.statement.RawParams + } + + rows.rows, err = rows.session.queryRows(sqlStr, args...) + if err != nil { + rows.lastError = err + rows.Close() + return nil, err + } + + return rows, nil +} + +// Next move cursor to next record, return false if end has reached +func (rows *Rows) Next() bool { + if rows.lastError == nil && rows.rows != nil { + hasNext := rows.rows.Next() + if !hasNext { + rows.lastError = sql.ErrNoRows + } + return hasNext + } + return false +} + +// Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close. +func (rows *Rows) Err() error { + return rows.lastError +} + +// Scan row record to bean properties +func (rows *Rows) Scan(bean interface{}) error { + if rows.lastError != nil { + return rows.lastError + } + + if reflect.Indirect(reflect.ValueOf(bean)).Type() != rows.beanType { + return fmt.Errorf("scan arg is incompatible type to [%v]", rows.beanType) + } + + if err := rows.session.statement.setRefBean(bean); err != nil { + return err + } + + fields, err := rows.rows.Columns() + if err != nil { + return err + } + + scanResults, err := rows.session.row2Slice(rows.rows, fields, bean) + if err != nil { + return err + } + + dataStruct := rValue(bean) + _, err = rows.session.slice2Bean(scanResults, fields, bean, &dataStruct, rows.session.statement.RefTable) + if err != nil { + return err + } + + return rows.session.executeProcessors() +} + +// Close session if session.IsAutoClose is true, and claimed any opened resources +func (rows *Rows) Close() error { + if rows.session.isAutoClose { + defer rows.session.Close() + } + + if rows.rows != nil { + return rows.rows.Close() + } + + return rows.lastError +} diff --git a/vendor/xorm.io/xorm/session.go b/vendor/xorm.io/xorm/session.go new file mode 100644 index 0000000000..b33955fdce --- /dev/null +++ b/vendor/xorm.io/xorm/session.go @@ -0,0 +1,866 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "context" + "database/sql" + "errors" + "fmt" + "hash/crc32" + "reflect" + "strings" + "time" + + "xorm.io/core" +) + +type sessionType int + +const ( + engineSession sessionType = iota + groupSession +) + +// Session keep a pointer to sql.DB and provides all execution of all +// kind of database operations. +type Session struct { + db *core.DB + engine *Engine + tx *core.Tx + statement Statement + isAutoCommit bool + isCommitedOrRollbacked bool + isAutoClose bool + + // Automatically reset the statement after operations that execute a SQL + // query such as Count(), Find(), Get(), ... + autoResetStatement bool + + // !nashtsai! storing these beans due to yet committed tx + afterInsertBeans map[interface{}]*[]func(interface{}) + afterUpdateBeans map[interface{}]*[]func(interface{}) + afterDeleteBeans map[interface{}]*[]func(interface{}) + // -- + + beforeClosures []func(interface{}) + afterClosures []func(interface{}) + + afterProcessors []executedProcessor + + prepareStmt bool + stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr)) + + // !evalphobia! stored the last executed query on this session + //beforeSQLExec func(string, ...interface{}) + lastSQL string + lastSQLArgs []interface{} + + ctx context.Context + sessionType sessionType +} + +// Clone copy all the session's content and return a new session +func (session *Session) Clone() *Session { + var sess = *session + return &sess +} + +// Init reset the session as the init status. +func (session *Session) Init() { + session.statement.Init() + session.statement.Engine = session.engine + session.isAutoCommit = true + session.isCommitedOrRollbacked = false + session.isAutoClose = false + session.autoResetStatement = true + session.prepareStmt = false + + // !nashtsai! is lazy init better? + session.afterInsertBeans = make(map[interface{}]*[]func(interface{}), 0) + session.afterUpdateBeans = make(map[interface{}]*[]func(interface{}), 0) + session.afterDeleteBeans = make(map[interface{}]*[]func(interface{}), 0) + session.beforeClosures = make([]func(interface{}), 0) + session.afterClosures = make([]func(interface{}), 0) + session.stmtCache = make(map[uint32]*core.Stmt) + + session.afterProcessors = make([]executedProcessor, 0) + + session.lastSQL = "" + session.lastSQLArgs = []interface{}{} + + session.ctx = session.engine.defaultContext +} + +// Close release the connection from pool +func (session *Session) Close() { + for _, v := range session.stmtCache { + v.Close() + } + + if session.db != nil { + // When Close be called, if session is a transaction and do not call + // Commit or Rollback, then call Rollback. + if session.tx != nil && !session.isCommitedOrRollbacked { + session.Rollback() + } + session.tx = nil + session.stmtCache = nil + session.db = nil + } +} + +// ContextCache enable context cache or not +func (session *Session) ContextCache(context ContextCache) *Session { + session.statement.context = context + return session +} + +// IsClosed returns if session is closed +func (session *Session) IsClosed() bool { + return session.db == nil +} + +func (session *Session) resetStatement() { + if session.autoResetStatement { + session.statement.Init() + } +} + +// Prepare set a flag to session that should be prepare statement before execute query +func (session *Session) Prepare() *Session { + session.prepareStmt = true + return session +} + +// Before Apply before Processor, affected bean is passed to closure arg +func (session *Session) Before(closures func(interface{})) *Session { + if closures != nil { + session.beforeClosures = append(session.beforeClosures, closures) + } + return session +} + +// After Apply after Processor, affected bean is passed to closure arg +func (session *Session) After(closures func(interface{})) *Session { + if closures != nil { + session.afterClosures = append(session.afterClosures, closures) + } + return session +} + +// Table can input a string or pointer to struct for special a table to operate. +func (session *Session) Table(tableNameOrBean interface{}) *Session { + session.statement.Table(tableNameOrBean) + return session +} + +// Alias set the table alias +func (session *Session) Alias(alias string) *Session { + session.statement.Alias(alias) + return session +} + +// NoCascade indicate that no cascade load child object +func (session *Session) NoCascade() *Session { + session.statement.UseCascade = false + return session +} + +// ForUpdate Set Read/Write locking for UPDATE +func (session *Session) ForUpdate() *Session { + session.statement.IsForUpdate = true + return session +} + +// NoAutoCondition disable generate SQL condition from beans +func (session *Session) NoAutoCondition(no ...bool) *Session { + session.statement.NoAutoCondition(no...) + return session +} + +// Limit provide limit and offset query condition +func (session *Session) Limit(limit int, start ...int) *Session { + session.statement.Limit(limit, start...) + return session +} + +// OrderBy provide order by query condition, the input parameter is the content +// after order by on a sql statement. +func (session *Session) OrderBy(order string) *Session { + session.statement.OrderBy(order) + return session +} + +// Desc provide desc order by query condition, the input parameters are columns. +func (session *Session) Desc(colNames ...string) *Session { + session.statement.Desc(colNames...) + return session +} + +// Asc provide asc order by query condition, the input parameters are columns. +func (session *Session) Asc(colNames ...string) *Session { + session.statement.Asc(colNames...) + return session +} + +// StoreEngine is only avialble mysql dialect currently +func (session *Session) StoreEngine(storeEngine string) *Session { + session.statement.StoreEngine = storeEngine + return session +} + +// Charset is only avialble mysql dialect currently +func (session *Session) Charset(charset string) *Session { + session.statement.Charset = charset + return session +} + +// Cascade indicates if loading sub Struct +func (session *Session) Cascade(trueOrFalse ...bool) *Session { + if len(trueOrFalse) >= 1 { + session.statement.UseCascade = trueOrFalse[0] + } + return session +} + +// NoCache ask this session do not retrieve data from cache system and +// get data from database directly. +func (session *Session) NoCache() *Session { + session.statement.UseCache = false + return session +} + +// Join join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN +func (session *Session) Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session { + session.statement.Join(joinOperator, tablename, condition, args...) + return session +} + +// GroupBy Generate Group By statement +func (session *Session) GroupBy(keys string) *Session { + session.statement.GroupBy(keys) + return session +} + +// Having Generate Having statement +func (session *Session) Having(conditions string) *Session { + session.statement.Having(conditions) + return session +} + +// DB db return the wrapper of sql.DB +func (session *Session) DB() *core.DB { + if session.db == nil { + session.db = session.engine.db + session.stmtCache = make(map[uint32]*core.Stmt, 0) + } + return session.db +} + +func cleanupProcessorsClosures(slices *[]func(interface{})) { + if len(*slices) > 0 { + *slices = make([]func(interface{}), 0) + } +} + +func (session *Session) canCache() bool { + if session.statement.RefTable == nil || + session.statement.JoinStr != "" || + session.statement.RawSQL != "" || + !session.statement.UseCache || + session.statement.IsForUpdate || + session.tx != nil || + len(session.statement.selectStr) > 0 { + return false + } + return true +} + +func (session *Session) doPrepare(db *core.DB, sqlStr string) (stmt *core.Stmt, err error) { + crc := crc32.ChecksumIEEE([]byte(sqlStr)) + // TODO try hash(sqlStr+len(sqlStr)) + var has bool + stmt, has = session.stmtCache[crc] + if !has { + stmt, err = db.PrepareContext(session.ctx, sqlStr) + if err != nil { + return nil, err + } + session.stmtCache[crc] = stmt + } + return +} + +func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) (*reflect.Value, error) { + var col *core.Column + if col = table.GetColumnIdx(key, idx); col == nil { + return nil, ErrFieldIsNotExist{key, table.Name} + } + + fieldValue, err := col.ValueOfV(dataStruct) + if err != nil { + return nil, err + } + + if !fieldValue.IsValid() || !fieldValue.CanSet() { + return nil, ErrFieldIsNotValid{key, table.Name} + } + + return fieldValue, nil +} + +// Cell cell is a result of one column field +type Cell *interface{} + +func (session *Session) rows2Beans(rows *core.Rows, fields []string, + table *core.Table, newElemFunc func([]string) reflect.Value, + sliceValueSetFunc func(*reflect.Value, core.PK) error) error { + for rows.Next() { + var newValue = newElemFunc(fields) + bean := newValue.Interface() + dataStruct := newValue.Elem() + + // handle beforeClosures + scanResults, err := session.row2Slice(rows, fields, bean) + if err != nil { + return err + } + pk, err := session.slice2Bean(scanResults, fields, bean, &dataStruct, table) + if err != nil { + return err + } + session.afterProcessors = append(session.afterProcessors, executedProcessor{ + fun: func(*Session, interface{}) error { + return sliceValueSetFunc(&newValue, pk) + }, + session: session, + bean: bean, + }) + } + return nil +} + +func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interface{}) ([]interface{}, error) { + for _, closure := range session.beforeClosures { + closure(bean) + } + + scanResults := make([]interface{}, len(fields)) + for i := 0; i < len(fields); i++ { + var cell interface{} + scanResults[i] = &cell + } + if err := rows.Scan(scanResults...); err != nil { + return nil, err + } + + if b, hasBeforeSet := bean.(BeforeSetProcessor); hasBeforeSet { + for ii, key := range fields { + b.BeforeSet(key, Cell(scanResults[ii].(*interface{}))) + } + } + return scanResults, nil +} + +func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *core.Table) (core.PK, error) { + defer func() { + if b, hasAfterSet := bean.(AfterSetProcessor); hasAfterSet { + for ii, key := range fields { + b.AfterSet(key, Cell(scanResults[ii].(*interface{}))) + } + } + }() + + // handle afterClosures + for _, closure := range session.afterClosures { + session.afterProcessors = append(session.afterProcessors, executedProcessor{ + fun: func(sess *Session, bean interface{}) error { + closure(bean) + return nil + }, + session: session, + bean: bean, + }) + } + + if a, has := bean.(AfterLoadProcessor); has { + session.afterProcessors = append(session.afterProcessors, executedProcessor{ + fun: func(sess *Session, bean interface{}) error { + a.AfterLoad() + return nil + }, + session: session, + bean: bean, + }) + } + + if a, has := bean.(AfterLoadSessionProcessor); has { + session.afterProcessors = append(session.afterProcessors, executedProcessor{ + fun: func(sess *Session, bean interface{}) error { + a.AfterLoad(sess) + return nil + }, + session: session, + bean: bean, + }) + } + + var tempMap = make(map[string]int) + var pk core.PK + for ii, key := range fields { + var idx int + var ok bool + var lKey = strings.ToLower(key) + if idx, ok = tempMap[lKey]; !ok { + idx = 0 + } else { + idx = idx + 1 + } + tempMap[lKey] = idx + + fieldValue, err := session.getField(dataStruct, key, table, idx) + if err != nil { + if !strings.Contains(err.Error(), "is not valid") { + session.engine.logger.Warn(err) + } + continue + } + if fieldValue == nil { + continue + } + rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii])) + + // if row is null then ignore + if rawValue.Interface() == nil { + continue + } + + if fieldValue.CanAddr() { + if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { + if data, err := value2Bytes(&rawValue); err == nil { + if err := structConvert.FromDB(data); err != nil { + return nil, err + } + } else { + return nil, err + } + continue + } + } + + if _, ok := fieldValue.Interface().(core.Conversion); ok { + if data, err := value2Bytes(&rawValue); err == nil { + if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() { + fieldValue.Set(reflect.New(fieldValue.Type().Elem())) + } + fieldValue.Interface().(core.Conversion).FromDB(data) + } else { + return nil, err + } + continue + } + + rawValueType := reflect.TypeOf(rawValue.Interface()) + vv := reflect.ValueOf(rawValue.Interface()) + col := table.GetColumnIdx(key, idx) + if col.IsPrimaryKey { + pk = append(pk, rawValue.Interface()) + } + fieldType := fieldValue.Type() + hasAssigned := false + + if col.SQLType.IsJson() { + var bs []byte + if rawValueType.Kind() == reflect.String { + bs = []byte(vv.String()) + } else if rawValueType.ConvertibleTo(core.BytesType) { + bs = vv.Bytes() + } else { + return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind()) + } + + hasAssigned = true + + if len(bs) > 0 { + if fieldType.Kind() == reflect.String { + fieldValue.SetString(string(bs)) + continue + } + if fieldValue.CanAddr() { + err := DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface()) + if err != nil { + return nil, err + } + } else { + x := reflect.New(fieldType) + err := DefaultJSONHandler.Unmarshal(bs, x.Interface()) + if err != nil { + return nil, err + } + fieldValue.Set(x.Elem()) + } + } + + continue + } + + switch fieldType.Kind() { + case reflect.Complex64, reflect.Complex128: + // TODO: reimplement this + var bs []byte + if rawValueType.Kind() == reflect.String { + bs = []byte(vv.String()) + } else if rawValueType.ConvertibleTo(core.BytesType) { + bs = vv.Bytes() + } + + hasAssigned = true + if len(bs) > 0 { + if fieldValue.CanAddr() { + err := DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface()) + if err != nil { + return nil, err + } + } else { + x := reflect.New(fieldType) + err := DefaultJSONHandler.Unmarshal(bs, x.Interface()) + if err != nil { + return nil, err + } + fieldValue.Set(x.Elem()) + } + } + case reflect.Slice, reflect.Array: + switch rawValueType.Kind() { + case reflect.Slice, reflect.Array: + switch rawValueType.Elem().Kind() { + case reflect.Uint8: + if fieldType.Elem().Kind() == reflect.Uint8 { + hasAssigned = true + if col.SQLType.IsText() { + x := reflect.New(fieldType) + err := DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface()) + if err != nil { + return nil, err + } + fieldValue.Set(x.Elem()) + } else { + if fieldValue.Len() > 0 { + for i := 0; i < fieldValue.Len(); i++ { + if i < vv.Len() { + fieldValue.Index(i).Set(vv.Index(i)) + } + } + } else { + for i := 0; i < vv.Len(); i++ { + fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i))) + } + } + } + } + } + } + case reflect.String: + if rawValueType.Kind() == reflect.String { + hasAssigned = true + fieldValue.SetString(vv.String()) + } + case reflect.Bool: + if rawValueType.Kind() == reflect.Bool { + hasAssigned = true + fieldValue.SetBool(vv.Bool()) + } + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch rawValueType.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + hasAssigned = true + fieldValue.SetInt(vv.Int()) + } + case reflect.Float32, reflect.Float64: + switch rawValueType.Kind() { + case reflect.Float32, reflect.Float64: + hasAssigned = true + fieldValue.SetFloat(vv.Float()) + } + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + switch rawValueType.Kind() { + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + hasAssigned = true + fieldValue.SetUint(vv.Uint()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + hasAssigned = true + fieldValue.SetUint(uint64(vv.Int())) + } + case reflect.Struct: + if fieldType.ConvertibleTo(core.TimeType) { + dbTZ := session.engine.DatabaseTZ + if col.TimeZone != nil { + dbTZ = col.TimeZone + } + + if rawValueType == core.TimeType { + hasAssigned = true + + t := vv.Convert(core.TimeType).Interface().(time.Time) + + z, _ := t.Zone() + // set new location if database don't save timezone or give an incorrect timezone + if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location + session.engine.logger.Debugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location()) + t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), + t.Minute(), t.Second(), t.Nanosecond(), dbTZ) + } + + t = t.In(session.engine.TZLocation) + fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) + } else if rawValueType == core.IntType || rawValueType == core.Int64Type || + rawValueType == core.Int32Type { + hasAssigned = true + + t := time.Unix(vv.Int(), 0).In(session.engine.TZLocation) + fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) + } else { + if d, ok := vv.Interface().([]uint8); ok { + hasAssigned = true + t, err := session.byte2Time(col, d) + if err != nil { + session.engine.logger.Error("byte2Time error:", err.Error()) + hasAssigned = false + } else { + fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) + } + } else if d, ok := vv.Interface().(string); ok { + hasAssigned = true + t, err := session.str2Time(col, d) + if err != nil { + session.engine.logger.Error("byte2Time error:", err.Error()) + hasAssigned = false + } else { + fieldValue.Set(reflect.ValueOf(t).Convert(fieldType)) + } + } else { + return nil, fmt.Errorf("rawValueType is %v, value is %v", rawValueType, vv.Interface()) + } + } + } else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok { + // !! 增加支持sql.Scanner接口的结构,如sql.NullString + hasAssigned = true + if err := nulVal.Scan(vv.Interface()); err != nil { + session.engine.logger.Error("sql.Sanner error:", err.Error()) + hasAssigned = false + } + } else if col.SQLType.IsJson() { + if rawValueType.Kind() == reflect.String { + hasAssigned = true + x := reflect.New(fieldType) + if len([]byte(vv.String())) > 0 { + err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), x.Interface()) + if err != nil { + return nil, err + } + fieldValue.Set(x.Elem()) + } + } else if rawValueType.Kind() == reflect.Slice { + hasAssigned = true + x := reflect.New(fieldType) + if len(vv.Bytes()) > 0 { + err := DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface()) + if err != nil { + return nil, err + } + fieldValue.Set(x.Elem()) + } + } + } else if session.statement.UseCascade { + table, err := session.engine.autoMapType(*fieldValue) + if err != nil { + return nil, err + } + + hasAssigned = true + if len(table.PrimaryKeys) != 1 { + return nil, errors.New("unsupported non or composited primary key cascade") + } + var pk = make(core.PK, len(table.PrimaryKeys)) + pk[0], err = asKind(vv, rawValueType) + if err != nil { + return nil, err + } + + if !isPKZero(pk) { + // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch + // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne + // property to be fetched lazily + structInter := reflect.New(fieldValue.Type()) + has, err := session.ID(pk).NoCascade().get(structInter.Interface()) + if err != nil { + return nil, err + } + if has { + fieldValue.Set(structInter.Elem()) + } else { + return nil, errors.New("cascade obj is not exist") + } + } + } + case reflect.Ptr: + // !nashtsai! TODO merge duplicated codes above + switch fieldType { + // following types case matching ptr's native type, therefore assign ptr directly + case core.PtrStringType: + if rawValueType.Kind() == reflect.String { + x := vv.String() + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrBoolType: + if rawValueType.Kind() == reflect.Bool { + x := vv.Bool() + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrTimeType: + if rawValueType == core.PtrTimeType { + hasAssigned = true + var x = rawValue.Interface().(time.Time) + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrFloat64Type: + if rawValueType.Kind() == reflect.Float64 { + x := vv.Float() + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrUint64Type: + if rawValueType.Kind() == reflect.Int64 { + var x = uint64(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrInt64Type: + if rawValueType.Kind() == reflect.Int64 { + x := vv.Int() + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrFloat32Type: + if rawValueType.Kind() == reflect.Float64 { + var x = float32(vv.Float()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrIntType: + if rawValueType.Kind() == reflect.Int64 { + var x = int(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrInt32Type: + if rawValueType.Kind() == reflect.Int64 { + var x = int32(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrInt8Type: + if rawValueType.Kind() == reflect.Int64 { + var x = int8(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrInt16Type: + if rawValueType.Kind() == reflect.Int64 { + var x = int16(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrUintType: + if rawValueType.Kind() == reflect.Int64 { + var x = uint(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.PtrUint32Type: + if rawValueType.Kind() == reflect.Int64 { + var x = uint32(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.Uint8Type: + if rawValueType.Kind() == reflect.Int64 { + var x = uint8(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.Uint16Type: + if rawValueType.Kind() == reflect.Int64 { + var x = uint16(vv.Int()) + hasAssigned = true + fieldValue.Set(reflect.ValueOf(&x)) + } + case core.Complex64Type: + var x complex64 + if len([]byte(vv.String())) > 0 { + err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x) + if err != nil { + return nil, err + } + fieldValue.Set(reflect.ValueOf(&x)) + } + hasAssigned = true + case core.Complex128Type: + var x complex128 + if len([]byte(vv.String())) > 0 { + err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x) + if err != nil { + return nil, err + } + fieldValue.Set(reflect.ValueOf(&x)) + } + hasAssigned = true + } // switch fieldType + } // switch fieldType.Kind() + + // !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value + if !hasAssigned { + data, err := value2Bytes(&rawValue) + if err != nil { + return nil, err + } + + if err = session.bytes2Value(col, fieldValue, data); err != nil { + return nil, err + } + } + } + return pk, nil +} + +// saveLastSQL stores executed query information +func (session *Session) saveLastSQL(sql string, args ...interface{}) { + session.lastSQL = sql + session.lastSQLArgs = args + session.engine.logSQL(sql, args...) +} + +// LastSQL returns last query information +func (session *Session) LastSQL() (string, []interface{}) { + return session.lastSQL, session.lastSQLArgs +} + +// Unscoped always disable struct tag "deleted" +func (session *Session) Unscoped() *Session { + session.statement.Unscoped() + return session +} + +func (session *Session) incrVersionFieldValue(fieldValue *reflect.Value) { + switch fieldValue.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fieldValue.SetInt(fieldValue.Int() + 1) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fieldValue.SetUint(fieldValue.Uint() + 1) + } +} diff --git a/vendor/xorm.io/xorm/session_cols.go b/vendor/xorm.io/xorm/session_cols.go new file mode 100644 index 0000000000..1558074f3d --- /dev/null +++ b/vendor/xorm.io/xorm/session_cols.go @@ -0,0 +1,156 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "reflect" + "strings" + "time" + + "xorm.io/core" +) + +func setColumnInt(bean interface{}, col *core.Column, t int64) { + v, err := col.ValueOf(bean) + if err != nil { + return + } + if v.CanSet() { + switch v.Type().Kind() { + case reflect.Int, reflect.Int64, reflect.Int32: + v.SetInt(t) + case reflect.Uint, reflect.Uint64, reflect.Uint32: + v.SetUint(uint64(t)) + } + } +} + +func setColumnTime(bean interface{}, col *core.Column, t time.Time) { + v, err := col.ValueOf(bean) + if err != nil { + return + } + if v.CanSet() { + switch v.Type().Kind() { + case reflect.Struct: + v.Set(reflect.ValueOf(t).Convert(v.Type())) + case reflect.Int, reflect.Int64, reflect.Int32: + v.SetInt(t.Unix()) + case reflect.Uint, reflect.Uint64, reflect.Uint32: + v.SetUint(uint64(t.Unix())) + } + } +} + +func getFlagForColumn(m map[string]bool, col *core.Column) (val bool, has bool) { + if len(m) == 0 { + return false, false + } + + n := len(col.Name) + + for mk := range m { + if len(mk) != n { + continue + } + if strings.EqualFold(mk, col.Name) { + return m[mk], true + } + } + + return false, false +} + +func col2NewCols(columns ...string) []string { + newColumns := make([]string, 0, len(columns)) + for _, col := range columns { + col = strings.Replace(col, "`", "", -1) + col = strings.Replace(col, `"`, "", -1) + ccols := strings.Split(col, ",") + for _, c := range ccols { + newColumns = append(newColumns, strings.TrimSpace(c)) + } + } + return newColumns +} + +// Incr provides a query string like "count = count + 1" +func (session *Session) Incr(column string, arg ...interface{}) *Session { + session.statement.Incr(column, arg...) + return session +} + +// Decr provides a query string like "count = count - 1" +func (session *Session) Decr(column string, arg ...interface{}) *Session { + session.statement.Decr(column, arg...) + return session +} + +// SetExpr provides a query string like "column = {expression}" +func (session *Session) SetExpr(column string, expression interface{}) *Session { + session.statement.SetExpr(column, expression) + return session +} + +// Select provides some columns to special +func (session *Session) Select(str string) *Session { + session.statement.Select(str) + return session +} + +// Cols provides some columns to special +func (session *Session) Cols(columns ...string) *Session { + session.statement.Cols(columns...) + return session +} + +// AllCols ask all columns +func (session *Session) AllCols() *Session { + session.statement.AllCols() + return session +} + +// MustCols specify some columns must use even if they are empty +func (session *Session) MustCols(columns ...string) *Session { + session.statement.MustCols(columns...) + return session +} + +// UseBool automatically retrieve condition according struct, but +// if struct has bool field, it will ignore them. So use UseBool +// to tell system to do not ignore them. +// If no parameters, it will use all the bool field of struct, or +// it will use parameters's columns +func (session *Session) UseBool(columns ...string) *Session { + session.statement.UseBool(columns...) + return session +} + +// Distinct use for distinct columns. Caution: when you are using cache, +// distinct will not be cached because cache system need id, +// but distinct will not provide id +func (session *Session) Distinct(columns ...string) *Session { + session.statement.Distinct(columns...) + return session +} + +// Omit Only not use the parameters as select or update columns +func (session *Session) Omit(columns ...string) *Session { + session.statement.Omit(columns...) + return session +} + +// Nullable Set null when column is zero-value and nullable for update +func (session *Session) Nullable(columns ...string) *Session { + session.statement.Nullable(columns...) + return session +} + +// NoAutoTime means do not automatically give created field and updated field +// the current time on the current session temporarily +func (session *Session) NoAutoTime() *Session { + session.statement.UseAutoTime = false + return session +} diff --git a/vendor/xorm.io/xorm/session_cond.go b/vendor/xorm.io/xorm/session_cond.go new file mode 100644 index 0000000000..b16bdea8e0 --- /dev/null +++ b/vendor/xorm.io/xorm/session_cond.go @@ -0,0 +1,70 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import "xorm.io/builder" + +// Sql provides raw sql input parameter. When you have a complex SQL statement +// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL. +// +// Deprecated: use SQL instead. +func (session *Session) Sql(query string, args ...interface{}) *Session { + return session.SQL(query, args...) +} + +// SQL provides raw sql input parameter. When you have a complex SQL statement +// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL. +func (session *Session) SQL(query interface{}, args ...interface{}) *Session { + session.statement.SQL(query, args...) + return session +} + +// Where provides custom query condition. +func (session *Session) Where(query interface{}, args ...interface{}) *Session { + session.statement.Where(query, args...) + return session +} + +// And provides custom query condition. +func (session *Session) And(query interface{}, args ...interface{}) *Session { + session.statement.And(query, args...) + return session +} + +// Or provides custom query condition. +func (session *Session) Or(query interface{}, args ...interface{}) *Session { + session.statement.Or(query, args...) + return session +} + +// Id provides converting id as a query condition +// +// Deprecated: use ID instead +func (session *Session) Id(id interface{}) *Session { + return session.ID(id) +} + +// ID provides converting id as a query condition +func (session *Session) ID(id interface{}) *Session { + session.statement.ID(id) + return session +} + +// In provides a query string like "id in (1, 2, 3)" +func (session *Session) In(column string, args ...interface{}) *Session { + session.statement.In(column, args...) + return session +} + +// NotIn provides a query string like "id in (1, 2, 3)" +func (session *Session) NotIn(column string, args ...interface{}) *Session { + session.statement.NotIn(column, args...) + return session +} + +// Conds returns session query conditions except auto bean conditions +func (session *Session) Conds() builder.Cond { + return session.statement.cond +} diff --git a/vendor/xorm.io/xorm/session_context.go b/vendor/xorm.io/xorm/session_context.go new file mode 100644 index 0000000000..915f056858 --- /dev/null +++ b/vendor/xorm.io/xorm/session_context.go @@ -0,0 +1,23 @@ +// Copyright 2019 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import "context" + +// Context sets the context on this session +func (session *Session) Context(ctx context.Context) *Session { + session.ctx = ctx + return session +} + +// PingContext test if database is ok +func (session *Session) PingContext(ctx context.Context) error { + if session.isAutoClose { + defer session.Close() + } + + session.engine.logger.Infof("PING DATABASE %v", session.engine.DriverName()) + return session.DB().PingContext(ctx) +} diff --git a/vendor/xorm.io/xorm/session_convert.go b/vendor/xorm.io/xorm/session_convert.go new file mode 100644 index 0000000000..7f11354d5e --- /dev/null +++ b/vendor/xorm.io/xorm/session_convert.go @@ -0,0 +1,671 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "database/sql/driver" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "xorm.io/core" +) + +func (session *Session) str2Time(col *core.Column, data string) (outTime time.Time, outErr error) { + sdata := strings.TrimSpace(data) + var x time.Time + var err error + + var parseLoc = session.engine.DatabaseTZ + if col.TimeZone != nil { + parseLoc = col.TimeZone + } + + if sdata == zeroTime0 || sdata == zeroTime1 { + } else if !strings.ContainsAny(sdata, "- :") { // !nashtsai! has only found that mymysql driver is using this for time type column + // time stamp + sd, err := strconv.ParseInt(sdata, 10, 64) + if err == nil { + x = time.Unix(sd, 0) + //session.engine.logger.Debugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + } else { + //session.engine.logger.Debugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + } + } else if len(sdata) > 19 && strings.Contains(sdata, "-") { + x, err = time.ParseInLocation(time.RFC3339Nano, sdata, parseLoc) + session.engine.logger.Debugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + if err != nil { + x, err = time.ParseInLocation("2006-01-02 15:04:05.999999999", sdata, parseLoc) + //session.engine.logger.Debugf("time(2) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + } + if err != nil { + x, err = time.ParseInLocation("2006-01-02 15:04:05.9999999 Z07:00", sdata, parseLoc) + //session.engine.logger.Debugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + } + } else if len(sdata) == 19 && strings.Contains(sdata, "-") { + x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, parseLoc) + //session.engine.logger.Debugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + } else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' { + x, err = time.ParseInLocation("2006-01-02", sdata, parseLoc) + //session.engine.logger.Debugf("time(5) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + } else if col.SQLType.Name == core.Time { + if strings.Contains(sdata, " ") { + ssd := strings.Split(sdata, " ") + sdata = ssd[1] + } + + sdata = strings.TrimSpace(sdata) + if session.engine.dialect.DBType() == core.MYSQL && len(sdata) > 8 { + sdata = sdata[len(sdata)-8:] + } + + st := fmt.Sprintf("2006-01-02 %v", sdata) + x, err = time.ParseInLocation("2006-01-02 15:04:05", st, parseLoc) + //session.engine.logger.Debugf("time(6) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata) + } else { + outErr = fmt.Errorf("unsupported time format %v", sdata) + return + } + if err != nil { + outErr = fmt.Errorf("unsupported time format %v: %v", sdata, err) + return + } + outTime = x.In(session.engine.TZLocation) + return +} + +func (session *Session) byte2Time(col *core.Column, data []byte) (outTime time.Time, outErr error) { + return session.str2Time(col, string(data)) +} + +var ( + nullFloatType = reflect.TypeOf(sql.NullFloat64{}) +) + +// convert a db data([]byte) to a field value +func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value, data []byte) error { + if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { + return structConvert.FromDB(data) + } + + if structConvert, ok := fieldValue.Interface().(core.Conversion); ok { + return structConvert.FromDB(data) + } + + var v interface{} + key := col.Name + fieldType := fieldValue.Type() + + switch fieldType.Kind() { + case reflect.Complex64, reflect.Complex128: + x := reflect.New(fieldType) + if len(data) > 0 { + err := DefaultJSONHandler.Unmarshal(data, x.Interface()) + if err != nil { + session.engine.logger.Error(err) + return err + } + fieldValue.Set(x.Elem()) + } + case reflect.Slice, reflect.Array, reflect.Map: + v = data + t := fieldType.Elem() + k := t.Kind() + if col.SQLType.IsText() { + x := reflect.New(fieldType) + if len(data) > 0 { + err := DefaultJSONHandler.Unmarshal(data, x.Interface()) + if err != nil { + session.engine.logger.Error(err) + return err + } + fieldValue.Set(x.Elem()) + } + } else if col.SQLType.IsBlob() { + if k == reflect.Uint8 { + fieldValue.Set(reflect.ValueOf(v)) + } else { + x := reflect.New(fieldType) + if len(data) > 0 { + err := DefaultJSONHandler.Unmarshal(data, x.Interface()) + if err != nil { + session.engine.logger.Error(err) + return err + } + fieldValue.Set(x.Elem()) + } + } + } else { + return ErrUnSupportedType + } + case reflect.String: + fieldValue.SetString(string(data)) + case reflect.Bool: + v, err := asBool(data) + if err != nil { + return fmt.Errorf("arg %v as bool: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(v)) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + sdata := string(data) + var x int64 + var err error + // for mysql, when use bit, it returned \x01 + if col.SQLType.Name == core.Bit && + session.engine.dialect.DBType() == core.MYSQL { // !nashtsai! TODO dialect needs to provide conversion interface API + if len(data) == 1 { + x = int64(data[0]) + } else { + x = 0 + } + } else if strings.HasPrefix(sdata, "0x") { + x, err = strconv.ParseInt(sdata, 16, 64) + } else if strings.HasPrefix(sdata, "0") { + x, err = strconv.ParseInt(sdata, 8, 64) + } else if strings.EqualFold(sdata, "true") { + x = 1 + } else if strings.EqualFold(sdata, "false") { + x = 0 + } else { + x, err = strconv.ParseInt(sdata, 10, 64) + } + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.SetInt(x) + case reflect.Float32, reflect.Float64: + x, err := strconv.ParseFloat(string(data), 64) + if err != nil { + return fmt.Errorf("arg %v as float64: %s", key, err.Error()) + } + fieldValue.SetFloat(x) + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + x, err := strconv.ParseUint(string(data), 10, 64) + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.SetUint(x) + //Currently only support Time type + case reflect.Struct: + // !! 增加支持sql.Scanner接口的结构,如sql.NullString + if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok { + if err := nulVal.Scan(data); err != nil { + return fmt.Errorf("sql.Scan(%v) failed: %s ", data, err.Error()) + } + } else { + if fieldType.ConvertibleTo(core.TimeType) { + x, err := session.byte2Time(col, data) + if err != nil { + return err + } + v = x + fieldValue.Set(reflect.ValueOf(v).Convert(fieldType)) + } else if session.statement.UseCascade { + table, err := session.engine.autoMapType(*fieldValue) + if err != nil { + return err + } + + // TODO: current only support 1 primary key + if len(table.PrimaryKeys) > 1 { + return errors.New("unsupported composited primary key cascade") + } + + var pk = make(core.PK, len(table.PrimaryKeys)) + rawValueType := table.ColumnType(table.PKColumns()[0].FieldName) + pk[0], err = str2PK(string(data), rawValueType) + if err != nil { + return err + } + + if !isPKZero(pk) { + // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch + // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne + // property to be fetched lazily + structInter := reflect.New(fieldValue.Type()) + has, err := session.ID(pk).NoCascade().get(structInter.Interface()) + if err != nil { + return err + } + if has { + v = structInter.Elem().Interface() + fieldValue.Set(reflect.ValueOf(v)) + } else { + return errors.New("cascade obj is not exist") + } + } + } + } + case reflect.Ptr: + // !nashtsai! TODO merge duplicated codes above + //typeStr := fieldType.String() + switch fieldType.Elem().Kind() { + // case "*string": + case core.StringType.Kind(): + x := string(data) + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*bool": + case core.BoolType.Kind(): + d := string(data) + v, err := strconv.ParseBool(d) + if err != nil { + return fmt.Errorf("arg %v as bool: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&v).Convert(fieldType)) + // case "*complex64": + case core.Complex64Type.Kind(): + var x complex64 + if len(data) > 0 { + err := DefaultJSONHandler.Unmarshal(data, &x) + if err != nil { + session.engine.logger.Error(err) + return err + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + } + // case "*complex128": + case core.Complex128Type.Kind(): + var x complex128 + if len(data) > 0 { + err := DefaultJSONHandler.Unmarshal(data, &x) + if err != nil { + session.engine.logger.Error(err) + return err + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + } + // case "*float64": + case core.Float64Type.Kind(): + x, err := strconv.ParseFloat(string(data), 64) + if err != nil { + return fmt.Errorf("arg %v as float64: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*float32": + case core.Float32Type.Kind(): + var x float32 + x1, err := strconv.ParseFloat(string(data), 32) + if err != nil { + return fmt.Errorf("arg %v as float32: %s", key, err.Error()) + } + x = float32(x1) + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*uint64": + case core.Uint64Type.Kind(): + var x uint64 + x, err := strconv.ParseUint(string(data), 10, 64) + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*uint": + case core.UintType.Kind(): + var x uint + x1, err := strconv.ParseUint(string(data), 10, 64) + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + x = uint(x1) + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*uint32": + case core.Uint32Type.Kind(): + var x uint32 + x1, err := strconv.ParseUint(string(data), 10, 64) + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + x = uint32(x1) + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*uint8": + case core.Uint8Type.Kind(): + var x uint8 + x1, err := strconv.ParseUint(string(data), 10, 64) + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + x = uint8(x1) + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*uint16": + case core.Uint16Type.Kind(): + var x uint16 + x1, err := strconv.ParseUint(string(data), 10, 64) + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + x = uint16(x1) + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*int64": + case core.Int64Type.Kind(): + sdata := string(data) + var x int64 + var err error + // for mysql, when use bit, it returned \x01 + if col.SQLType.Name == core.Bit && + strings.Contains(session.engine.DriverName(), "mysql") { + if len(data) == 1 { + x = int64(data[0]) + } else { + x = 0 + } + } else if strings.HasPrefix(sdata, "0x") { + x, err = strconv.ParseInt(sdata, 16, 64) + } else if strings.HasPrefix(sdata, "0") { + x, err = strconv.ParseInt(sdata, 8, 64) + } else { + x, err = strconv.ParseInt(sdata, 10, 64) + } + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*int": + case core.IntType.Kind(): + sdata := string(data) + var x int + var x1 int64 + var err error + // for mysql, when use bit, it returned \x01 + if col.SQLType.Name == core.Bit && + strings.Contains(session.engine.DriverName(), "mysql") { + if len(data) == 1 { + x = int(data[0]) + } else { + x = 0 + } + } else if strings.HasPrefix(sdata, "0x") { + x1, err = strconv.ParseInt(sdata, 16, 64) + x = int(x1) + } else if strings.HasPrefix(sdata, "0") { + x1, err = strconv.ParseInt(sdata, 8, 64) + x = int(x1) + } else { + x1, err = strconv.ParseInt(sdata, 10, 64) + x = int(x1) + } + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*int32": + case core.Int32Type.Kind(): + sdata := string(data) + var x int32 + var x1 int64 + var err error + // for mysql, when use bit, it returned \x01 + if col.SQLType.Name == core.Bit && + session.engine.dialect.DBType() == core.MYSQL { + if len(data) == 1 { + x = int32(data[0]) + } else { + x = 0 + } + } else if strings.HasPrefix(sdata, "0x") { + x1, err = strconv.ParseInt(sdata, 16, 64) + x = int32(x1) + } else if strings.HasPrefix(sdata, "0") { + x1, err = strconv.ParseInt(sdata, 8, 64) + x = int32(x1) + } else { + x1, err = strconv.ParseInt(sdata, 10, 64) + x = int32(x1) + } + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*int8": + case core.Int8Type.Kind(): + sdata := string(data) + var x int8 + var x1 int64 + var err error + // for mysql, when use bit, it returned \x01 + if col.SQLType.Name == core.Bit && + strings.Contains(session.engine.DriverName(), "mysql") { + if len(data) == 1 { + x = int8(data[0]) + } else { + x = 0 + } + } else if strings.HasPrefix(sdata, "0x") { + x1, err = strconv.ParseInt(sdata, 16, 64) + x = int8(x1) + } else if strings.HasPrefix(sdata, "0") { + x1, err = strconv.ParseInt(sdata, 8, 64) + x = int8(x1) + } else { + x1, err = strconv.ParseInt(sdata, 10, 64) + x = int8(x1) + } + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*int16": + case core.Int16Type.Kind(): + sdata := string(data) + var x int16 + var x1 int64 + var err error + // for mysql, when use bit, it returned \x01 + if col.SQLType.Name == core.Bit && + strings.Contains(session.engine.DriverName(), "mysql") { + if len(data) == 1 { + x = int16(data[0]) + } else { + x = 0 + } + } else if strings.HasPrefix(sdata, "0x") { + x1, err = strconv.ParseInt(sdata, 16, 64) + x = int16(x1) + } else if strings.HasPrefix(sdata, "0") { + x1, err = strconv.ParseInt(sdata, 8, 64) + x = int16(x1) + } else { + x1, err = strconv.ParseInt(sdata, 10, 64) + x = int16(x1) + } + if err != nil { + return fmt.Errorf("arg %v as int: %s", key, err.Error()) + } + fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType)) + // case "*SomeStruct": + case reflect.Struct: + switch fieldType { + // case "*.time.Time": + case core.PtrTimeType: + x, err := session.byte2Time(col, data) + if err != nil { + return err + } + v = x + fieldValue.Set(reflect.ValueOf(&x)) + default: + if session.statement.UseCascade { + structInter := reflect.New(fieldType.Elem()) + table, err := session.engine.autoMapType(structInter.Elem()) + if err != nil { + return err + } + + if len(table.PrimaryKeys) > 1 { + return errors.New("unsupported composited primary key cascade") + } + + var pk = make(core.PK, len(table.PrimaryKeys)) + rawValueType := table.ColumnType(table.PKColumns()[0].FieldName) + pk[0], err = str2PK(string(data), rawValueType) + if err != nil { + return err + } + + if !isPKZero(pk) { + // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch + // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne + // property to be fetched lazily + has, err := session.ID(pk).NoCascade().get(structInter.Interface()) + if err != nil { + return err + } + if has { + v = structInter.Interface() + fieldValue.Set(reflect.ValueOf(v)) + } else { + return errors.New("cascade obj is not exist") + } + } + } else { + return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String()) + } + } + default: + return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String()) + } + default: + return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String()) + } + + return nil +} + +// convert a field value of a struct to interface for put into db +func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Value) (interface{}, error) { + if fieldValue.CanAddr() { + if fieldConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { + data, err := fieldConvert.ToDB() + if err != nil { + return 0, err + } + if col.SQLType.IsBlob() { + return data, nil + } + return string(data), nil + } + } + + if fieldConvert, ok := fieldValue.Interface().(core.Conversion); ok { + data, err := fieldConvert.ToDB() + if err != nil { + return 0, err + } + if col.SQLType.IsBlob() { + return data, nil + } + return string(data), nil + } + + fieldType := fieldValue.Type() + k := fieldType.Kind() + if k == reflect.Ptr { + if fieldValue.IsNil() { + return nil, nil + } else if !fieldValue.IsValid() { + session.engine.logger.Warn("the field[", col.FieldName, "] is invalid") + return nil, nil + } else { + // !nashtsai! deference pointer type to instance type + fieldValue = fieldValue.Elem() + fieldType = fieldValue.Type() + k = fieldType.Kind() + } + } + + switch k { + case reflect.Bool: + return fieldValue.Bool(), nil + case reflect.String: + return fieldValue.String(), nil + case reflect.Struct: + if fieldType.ConvertibleTo(core.TimeType) { + t := fieldValue.Convert(core.TimeType).Interface().(time.Time) + tf := session.engine.formatColTime(col, t) + return tf, nil + } else if fieldType.ConvertibleTo(nullFloatType) { + t := fieldValue.Convert(nullFloatType).Interface().(sql.NullFloat64) + if !t.Valid { + return nil, nil + } + return t.Float64, nil + } + + if !col.SQLType.IsJson() { + // !! 增加支持driver.Valuer接口的结构,如sql.NullString + if v, ok := fieldValue.Interface().(driver.Valuer); ok { + return v.Value() + } + + fieldTable, err := session.engine.autoMapType(fieldValue) + if err != nil { + return nil, err + } + if len(fieldTable.PrimaryKeys) == 1 { + pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName) + return pkField.Interface(), nil + } + return 0, fmt.Errorf("no primary key for col %v", col.Name) + } + + if col.SQLType.IsText() { + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + session.engine.logger.Error(err) + return 0, err + } + return string(bytes), nil + } else if col.SQLType.IsBlob() { + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + session.engine.logger.Error(err) + return 0, err + } + return bytes, nil + } + return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type()) + case reflect.Complex64, reflect.Complex128: + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + session.engine.logger.Error(err) + return 0, err + } + return string(bytes), nil + case reflect.Array, reflect.Slice, reflect.Map: + if !fieldValue.IsValid() { + return fieldValue.Interface(), nil + } + + if col.SQLType.IsText() { + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + session.engine.logger.Error(err) + return 0, err + } + return string(bytes), nil + } else if col.SQLType.IsBlob() { + var bytes []byte + var err error + if (k == reflect.Slice) && + (fieldValue.Type().Elem().Kind() == reflect.Uint8) { + bytes = fieldValue.Bytes() + } else { + bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + session.engine.logger.Error(err) + return 0, err + } + } + return bytes, nil + } + return nil, ErrUnSupportedType + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return int64(fieldValue.Uint()), nil + default: + return fieldValue.Interface(), nil + } +} diff --git a/vendor/xorm.io/xorm/session_delete.go b/vendor/xorm.io/xorm/session_delete.go new file mode 100644 index 0000000000..675d4d8c7d --- /dev/null +++ b/vendor/xorm.io/xorm/session_delete.go @@ -0,0 +1,244 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "strconv" + + "xorm.io/core" +) + +func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string, args ...interface{}) error { + if table == nil || + session.tx != nil { + return ErrCacheFailed + } + + for _, filter := range session.engine.dialect.Filters() { + sqlStr = filter.Do(sqlStr, session.engine.dialect, table) + } + + newsql := session.statement.convertIDSQL(sqlStr) + if newsql == "" { + return ErrCacheFailed + } + + cacher := session.engine.getCacher(tableName) + pkColumns := table.PKColumns() + ids, err := core.GetCacheSql(cacher, tableName, newsql, args) + if err != nil { + resultsSlice, err := session.queryBytes(newsql, args...) + if err != nil { + return err + } + ids = make([]core.PK, 0) + if len(resultsSlice) > 0 { + for _, data := range resultsSlice { + var id int64 + var pk core.PK = make([]interface{}, 0) + for _, col := range pkColumns { + if v, ok := data[col.Name]; !ok { + return errors.New("no id") + } else if col.SQLType.IsText() { + pk = append(pk, string(v)) + } else if col.SQLType.IsNumeric() { + id, err = strconv.ParseInt(string(v), 10, 64) + if err != nil { + return err + } + pk = append(pk, id) + } else { + return errors.New("not supported primary key type") + } + } + ids = append(ids, pk) + } + } + } + + for _, id := range ids { + session.engine.logger.Debug("[cacheDelete] delete cache obj:", tableName, id) + sid, err := id.ToString() + if err != nil { + return err + } + cacher.DelBean(tableName, sid) + } + session.engine.logger.Debug("[cacheDelete] clear cache table:", tableName) + cacher.ClearIds(tableName) + return nil +} + +// Delete records, bean's non-empty fields are conditions +func (session *Session) Delete(bean interface{}) (int64, error) { + if session.isAutoClose { + defer session.Close() + } + + if session.statement.lastError != nil { + return 0, session.statement.lastError + } + + if err := session.statement.setRefBean(bean); err != nil { + return 0, err + } + + // handle before delete processors + for _, closure := range session.beforeClosures { + closure(bean) + } + cleanupProcessorsClosures(&session.beforeClosures) + + if processor, ok := interface{}(bean).(BeforeDeleteProcessor); ok { + processor.BeforeDelete() + } + + condSQL, condArgs, err := session.statement.genConds(bean) + if err != nil { + return 0, err + } + if len(condSQL) == 0 && session.statement.LimitN == 0 { + return 0, ErrNeedDeletedCond + } + + var tableNameNoQuote = session.statement.TableName() + var tableName = session.engine.Quote(tableNameNoQuote) + var table = session.statement.RefTable + var deleteSQL string + if len(condSQL) > 0 { + deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condSQL) + } else { + deleteSQL = fmt.Sprintf("DELETE FROM %v", tableName) + } + + var orderSQL string + if len(session.statement.OrderStr) > 0 { + orderSQL += fmt.Sprintf(" ORDER BY %s", session.statement.OrderStr) + } + if session.statement.LimitN > 0 { + orderSQL += fmt.Sprintf(" LIMIT %d", session.statement.LimitN) + } + + if len(orderSQL) > 0 { + switch session.engine.dialect.DBType() { + case core.POSTGRES: + inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL) + if len(condSQL) > 0 { + deleteSQL += " AND " + inSQL + } else { + deleteSQL += " WHERE " + inSQL + } + case core.SQLITE: + inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL) + if len(condSQL) > 0 { + deleteSQL += " AND " + inSQL + } else { + deleteSQL += " WHERE " + inSQL + } + // TODO: how to handle delete limit on mssql? + case core.MSSQL: + return 0, ErrNotImplemented + default: + deleteSQL += orderSQL + } + } + + var realSQL string + argsForCache := make([]interface{}, 0, len(condArgs)*2) + if session.statement.unscoped || table.DeletedColumn() == nil { // tag "deleted" is disabled + realSQL = deleteSQL + copy(argsForCache, condArgs) + argsForCache = append(condArgs, argsForCache...) + } else { + // !oinume! sqlStrForCache and argsForCache is needed to behave as executing "DELETE FROM ..." for cache. + copy(argsForCache, condArgs) + argsForCache = append(condArgs, argsForCache...) + + deletedColumn := table.DeletedColumn() + realSQL = fmt.Sprintf("UPDATE %v SET %v = ? WHERE %v", + session.engine.Quote(session.statement.TableName()), + session.engine.Quote(deletedColumn.Name), + condSQL) + + if len(orderSQL) > 0 { + switch session.engine.dialect.DBType() { + case core.POSTGRES: + inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL) + if len(condSQL) > 0 { + realSQL += " AND " + inSQL + } else { + realSQL += " WHERE " + inSQL + } + case core.SQLITE: + inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL) + if len(condSQL) > 0 { + realSQL += " AND " + inSQL + } else { + realSQL += " WHERE " + inSQL + } + // TODO: how to handle delete limit on mssql? + case core.MSSQL: + return 0, ErrNotImplemented + default: + realSQL += orderSQL + } + } + + // !oinume! Insert nowTime to the head of session.statement.Params + condArgs = append(condArgs, "") + paramsLen := len(condArgs) + copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1]) + + val, t := session.engine.nowTime(deletedColumn) + condArgs[0] = val + + var colName = deletedColumn.Name + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnTime(bean, col, t) + }) + } + + if cacher := session.engine.getCacher(tableNameNoQuote); cacher != nil && session.statement.UseCache { + session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...) + } + + session.statement.RefTable = table + res, err := session.exec(realSQL, condArgs...) + if err != nil { + return 0, err + } + + // handle after delete processors + if session.isAutoCommit { + for _, closure := range session.afterClosures { + closure(bean) + } + if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok { + processor.AfterDelete() + } + } else { + lenAfterClosures := len(session.afterClosures) + if lenAfterClosures > 0 { + if value, has := session.afterDeleteBeans[bean]; has && value != nil { + *value = append(*value, session.afterClosures...) + } else { + afterClosures := make([]func(interface{}), lenAfterClosures) + copy(afterClosures, session.afterClosures) + session.afterDeleteBeans[bean] = &afterClosures + } + } else { + if _, ok := interface{}(bean).(AfterDeleteProcessor); ok { + session.afterDeleteBeans[bean] = nil + } + } + } + cleanupProcessorsClosures(&session.afterClosures) + // -- + + return res.RowsAffected() +} diff --git a/vendor/xorm.io/xorm/session_exist.go b/vendor/xorm.io/xorm/session_exist.go new file mode 100644 index 0000000000..660cc47e42 --- /dev/null +++ b/vendor/xorm.io/xorm/session_exist.go @@ -0,0 +1,96 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "reflect" + + "xorm.io/builder" + "xorm.io/core" +) + +// Exist returns true if the record exist otherwise return false +func (session *Session) Exist(bean ...interface{}) (bool, error) { + if session.isAutoClose { + defer session.Close() + } + + if session.statement.lastError != nil { + return false, session.statement.lastError + } + + var sqlStr string + var args []interface{} + var err error + + if session.statement.RawSQL == "" { + if len(bean) == 0 { + tableName := session.statement.TableName() + if len(tableName) <= 0 { + return false, ErrTableNotFound + } + + tableName = session.statement.Engine.Quote(tableName) + + if session.statement.cond.IsValid() { + condSQL, condArgs, err := builder.ToSQL(session.statement.cond) + if err != nil { + return false, err + } + + if session.engine.dialect.DBType() == core.MSSQL { + sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s WHERE %s", tableName, condSQL) + } else if session.engine.dialect.DBType() == core.ORACLE { + sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE (%s) AND ROWNUM=1", tableName, condSQL) + } else { + sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL) + } + args = condArgs + } else { + if session.engine.dialect.DBType() == core.MSSQL { + sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s", tableName) + } else if session.engine.dialect.DBType() == core.ORACLE { + sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE ROWNUM=1", tableName) + } else { + sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName) + } + args = []interface{}{} + } + } else { + beanValue := reflect.ValueOf(bean[0]) + if beanValue.Kind() != reflect.Ptr { + return false, errors.New("needs a pointer") + } + + if beanValue.Elem().Kind() == reflect.Struct { + if err := session.statement.setRefBean(bean[0]); err != nil { + return false, err + } + } + + if len(session.statement.TableName()) <= 0 { + return false, ErrTableNotFound + } + session.statement.Limit(1) + sqlStr, args, err = session.statement.genGetSQL(bean[0]) + if err != nil { + return false, err + } + } + } else { + sqlStr = session.statement.RawSQL + args = session.statement.RawParams + } + + rows, err := session.queryRows(sqlStr, args...) + if err != nil { + return false, err + } + defer rows.Close() + + return rows.Next(), nil +} diff --git a/vendor/xorm.io/xorm/session_find.go b/vendor/xorm.io/xorm/session_find.go new file mode 100644 index 0000000000..e16ae54c94 --- /dev/null +++ b/vendor/xorm.io/xorm/session_find.go @@ -0,0 +1,505 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "reflect" + "strings" + + "xorm.io/builder" + "xorm.io/core" +) + +const ( + tpStruct = iota + tpNonStruct +) + +// Find retrieve records from table, condiBeans's non-empty fields +// are conditions. beans could be []Struct, []*Struct, map[int64]Struct +// map[int64]*Struct +func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) error { + if session.isAutoClose { + defer session.Close() + } + return session.find(rowsSlicePtr, condiBean...) +} + +// FindAndCount find the results and also return the counts +func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) { + if session.isAutoClose { + defer session.Close() + } + + session.autoResetStatement = false + err := session.find(rowsSlicePtr, condiBean...) + if err != nil { + return 0, err + } + + sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) + if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { + return 0, errors.New("needs a pointer to a slice or a map") + } + + sliceElementType := sliceValue.Type().Elem() + if sliceElementType.Kind() == reflect.Ptr { + sliceElementType = sliceElementType.Elem() + } + session.autoResetStatement = true + + if session.statement.selectStr != "" { + session.statement.selectStr = "" + } + if session.statement.OrderStr != "" { + session.statement.OrderStr = "" + } + + return session.Count(reflect.New(sliceElementType).Interface()) +} + +func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { + defer session.resetStatement() + + if session.statement.lastError != nil { + return session.statement.lastError + } + + sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) + if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { + return errors.New("needs a pointer to a slice or a map") + } + + sliceElementType := sliceValue.Type().Elem() + + var tp = tpStruct + if session.statement.RefTable == nil { + if sliceElementType.Kind() == reflect.Ptr { + if sliceElementType.Elem().Kind() == reflect.Struct { + pv := reflect.New(sliceElementType.Elem()) + if err := session.statement.setRefValue(pv); err != nil { + return err + } + } else { + tp = tpNonStruct + } + } else if sliceElementType.Kind() == reflect.Struct { + pv := reflect.New(sliceElementType) + if err := session.statement.setRefValue(pv); err != nil { + return err + } + } else { + tp = tpNonStruct + } + } + + var table = session.statement.RefTable + + var addedTableName = (len(session.statement.JoinStr) > 0) + var autoCond builder.Cond + if tp == tpStruct { + if !session.statement.noAutoCondition && len(condiBean) > 0 { + var err error + autoCond, err = session.statement.buildConds(table, condiBean[0], true, true, false, true, addedTableName) + if err != nil { + return err + } + } else { + // !oinume! Add " IS NULL" to WHERE whatever condiBean is given. + // See https://gitea.com/xorm/xorm/issues/179 + if col := table.DeletedColumn(); col != nil && !session.statement.unscoped { // tag "deleted" is enabled + var colName = session.engine.Quote(col.Name) + if addedTableName { + var nm = session.statement.TableName() + if len(session.statement.TableAlias) > 0 { + nm = session.statement.TableAlias + } + colName = session.engine.Quote(nm) + "." + colName + } + + autoCond = session.engine.CondDeleted(colName) + } + } + } + + var sqlStr string + var args []interface{} + var err error + if session.statement.RawSQL == "" { + if len(session.statement.TableName()) <= 0 { + return ErrTableNotFound + } + + var columnStr = session.statement.ColumnStr + if len(session.statement.selectStr) > 0 { + columnStr = session.statement.selectStr + } else { + if session.statement.JoinStr == "" { + if columnStr == "" { + if session.statement.GroupByStr != "" { + columnStr = session.engine.quoteColumns(session.statement.GroupByStr) + } else { + columnStr = session.statement.genColumnStr() + } + } + } else { + if columnStr == "" { + if session.statement.GroupByStr != "" { + columnStr = session.engine.quoteColumns(session.statement.GroupByStr) + } else { + columnStr = "*" + } + } + } + if columnStr == "" { + columnStr = "*" + } + } + + session.statement.cond = session.statement.cond.And(autoCond) + condSQL, condArgs, err := builder.ToSQL(session.statement.cond) + if err != nil { + return err + } + + args = append(session.statement.joinArgs, condArgs...) + sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL, true, true) + if err != nil { + return err + } + // for mssql and use limit + qs := strings.Count(sqlStr, "?") + if len(args)*2 == qs { + args = append(args, args...) + } + } else { + sqlStr = session.statement.RawSQL + args = session.statement.RawParams + } + + if session.canCache() { + if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil && + !session.statement.IsDistinct && + !session.statement.unscoped { + err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) + if err != ErrCacheFailed { + return err + } + err = nil // !nashtsai! reset err to nil for ErrCacheFailed + session.engine.logger.Warn("Cache Find Failed") + } + } + + return session.noCacheFind(table, sliceValue, sqlStr, args...) +} + +func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error { + rows, err := session.queryRows(sqlStr, args...) + if err != nil { + return err + } + defer rows.Close() + + fields, err := rows.Columns() + if err != nil { + return err + } + + var newElemFunc func(fields []string) reflect.Value + elemType := containerValue.Type().Elem() + var isPointer bool + if elemType.Kind() == reflect.Ptr { + isPointer = true + elemType = elemType.Elem() + } + if elemType.Kind() == reflect.Ptr { + return errors.New("pointer to pointer is not supported") + } + + newElemFunc = func(fields []string) reflect.Value { + switch elemType.Kind() { + case reflect.Slice: + slice := reflect.MakeSlice(elemType, len(fields), len(fields)) + x := reflect.New(slice.Type()) + x.Elem().Set(slice) + return x + case reflect.Map: + mp := reflect.MakeMap(elemType) + x := reflect.New(mp.Type()) + x.Elem().Set(mp) + return x + } + return reflect.New(elemType) + } + + var containerValueSetFunc func(*reflect.Value, core.PK) error + + if containerValue.Kind() == reflect.Slice { + containerValueSetFunc = func(newValue *reflect.Value, pk core.PK) error { + if isPointer { + containerValue.Set(reflect.Append(containerValue, newValue.Elem().Addr())) + } else { + containerValue.Set(reflect.Append(containerValue, newValue.Elem())) + } + return nil + } + } else { + keyType := containerValue.Type().Key() + if len(table.PrimaryKeys) == 0 { + return errors.New("don't support multiple primary key's map has non-slice key type") + } + if len(table.PrimaryKeys) > 1 && keyType.Kind() != reflect.Slice { + return errors.New("don't support multiple primary key's map has non-slice key type") + } + + containerValueSetFunc = func(newValue *reflect.Value, pk core.PK) error { + keyValue := reflect.New(keyType) + err := convertPKToValue(table, keyValue.Interface(), pk) + if err != nil { + return err + } + if isPointer { + containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem().Addr()) + } else { + containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem()) + } + return nil + } + } + + if elemType.Kind() == reflect.Struct { + var newValue = newElemFunc(fields) + dataStruct := rValue(newValue.Interface()) + tb, err := session.engine.autoMapType(dataStruct) + if err != nil { + return err + } + err = session.rows2Beans(rows, fields, tb, newElemFunc, containerValueSetFunc) + rows.Close() + if err != nil { + return err + } + return session.executeProcessors() + } + + for rows.Next() { + var newValue = newElemFunc(fields) + bean := newValue.Interface() + + switch elemType.Kind() { + case reflect.Slice: + err = rows.ScanSlice(bean) + case reflect.Map: + err = rows.ScanMap(bean) + default: + err = rows.Scan(bean) + } + + if err != nil { + return err + } + + if err := containerValueSetFunc(&newValue, nil); err != nil { + return err + } + } + return nil +} + +func convertPKToValue(table *core.Table, dst interface{}, pk core.PK) error { + cols := table.PKColumns() + if len(cols) == 1 { + return convertAssign(dst, pk[0]) + } + + dst = pk + return nil +} + +func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) { + if !session.canCache() || + indexNoCase(sqlStr, "having") != -1 || + indexNoCase(sqlStr, "group by") != -1 { + return ErrCacheFailed + } + + tableName := session.statement.TableName() + cacher := session.engine.getCacher(tableName) + if cacher == nil { + return nil + } + + for _, filter := range session.engine.dialect.Filters() { + sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable) + } + + newsql := session.statement.convertIDSQL(sqlStr) + if newsql == "" { + return ErrCacheFailed + } + + table := session.statement.RefTable + ids, err := core.GetCacheSql(cacher, tableName, newsql, args) + if err != nil { + rows, err := session.queryRows(newsql, args...) + if err != nil { + return err + } + defer rows.Close() + + var i int + ids = make([]core.PK, 0) + for rows.Next() { + i++ + if i > 500 { + session.engine.logger.Debug("[cacheFind] ids length > 500, no cache") + return ErrCacheFailed + } + var res = make([]string, len(table.PrimaryKeys)) + err = rows.ScanSlice(&res) + if err != nil { + return err + } + var pk core.PK = make([]interface{}, len(table.PrimaryKeys)) + for i, col := range table.PKColumns() { + pk[i], err = session.engine.idTypeAssertion(col, res[i]) + if err != nil { + return err + } + } + + ids = append(ids, pk) + } + + session.engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, sqlStr, newsql, args) + err = core.PutCacheSql(cacher, ids, tableName, newsql, args) + if err != nil { + return err + } + } else { + session.engine.logger.Debug("[cacheFind] cache hit sql:", tableName, sqlStr, newsql, args) + } + + sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) + + ididxes := make(map[string]int) + var ides []core.PK + var temps = make([]interface{}, len(ids)) + + for idx, id := range ids { + sid, err := id.ToString() + if err != nil { + return err + } + bean := cacher.GetBean(tableName, sid) + if bean == nil || reflect.ValueOf(bean).Elem().Type() != t { + ides = append(ides, id) + ididxes[sid] = idx + } else { + session.engine.logger.Debug("[cacheFind] cache hit bean:", tableName, id, bean) + + pk := session.engine.IdOf(bean) + xid, err := pk.ToString() + if err != nil { + return err + } + + if sid != xid { + session.engine.logger.Error("[cacheFind] error cache", xid, sid, bean) + return ErrCacheFailed + } + temps[idx] = bean + } + } + + if len(ides) > 0 { + slices := reflect.New(reflect.SliceOf(t)) + beans := slices.Interface() + + if len(table.PrimaryKeys) == 1 { + ff := make([]interface{}, 0, len(ides)) + for _, ie := range ides { + ff = append(ff, ie[0]) + } + + session.In("`"+table.PrimaryKeys[0]+"`", ff...) + } else { + for _, ie := range ides { + cond := builder.NewCond() + for i, name := range table.PrimaryKeys { + cond = cond.And(builder.Eq{"`" + name + "`": ie[i]}) + } + session.Or(cond) + } + } + + err = session.NoCache().Table(tableName).find(beans) + if err != nil { + return err + } + + vs := reflect.Indirect(reflect.ValueOf(beans)) + for i := 0; i < vs.Len(); i++ { + rv := vs.Index(i) + if rv.Kind() != reflect.Ptr { + rv = rv.Addr() + } + id, err := session.engine.idOfV(rv) + if err != nil { + return err + } + sid, err := id.ToString() + if err != nil { + return err + } + + bean := rv.Interface() + temps[ididxes[sid]] = bean + session.engine.logger.Debug("[cacheFind] cache bean:", tableName, id, bean, temps) + cacher.PutBean(tableName, sid, bean) + } + } + + for j := 0; j < len(temps); j++ { + bean := temps[j] + if bean == nil { + session.engine.logger.Warn("[cacheFind] cache no hit:", tableName, ids[j], temps) + // return errors.New("cache error") // !nashtsai! no need to return error, but continue instead + continue + } + if sliceValue.Kind() == reflect.Slice { + if t.Kind() == reflect.Ptr { + sliceValue.Set(reflect.Append(sliceValue, reflect.ValueOf(bean))) + } else { + sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(bean)))) + } + } else if sliceValue.Kind() == reflect.Map { + var key = ids[j] + keyType := sliceValue.Type().Key() + var ikey interface{} + if len(key) == 1 { + ikey, err = str2PK(fmt.Sprintf("%v", key[0]), keyType) + if err != nil { + return err + } + } else { + if keyType.Kind() != reflect.Slice { + return errors.New("table have multiple primary keys, key is not core.PK or slice") + } + ikey = key + } + + if t.Kind() == reflect.Ptr { + sliceValue.SetMapIndex(reflect.ValueOf(ikey), reflect.ValueOf(bean)) + } else { + sliceValue.SetMapIndex(reflect.ValueOf(ikey), reflect.Indirect(reflect.ValueOf(bean))) + } + } + } + + return nil +} diff --git a/vendor/xorm.io/xorm/session_get.go b/vendor/xorm.io/xorm/session_get.go new file mode 100644 index 0000000000..cc0a2019ea --- /dev/null +++ b/vendor/xorm.io/xorm/session_get.go @@ -0,0 +1,356 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "errors" + "fmt" + "reflect" + "strconv" + + "xorm.io/core" +) + +// Get retrieve one record from database, bean's non-empty fields +// will be as conditions +func (session *Session) Get(bean interface{}) (bool, error) { + if session.isAutoClose { + defer session.Close() + } + return session.get(bean) +} + +func (session *Session) get(bean interface{}) (bool, error) { + defer session.resetStatement() + + if session.statement.lastError != nil { + return false, session.statement.lastError + } + + beanValue := reflect.ValueOf(bean) + if beanValue.Kind() != reflect.Ptr { + return false, errors.New("needs a pointer to a value") + } else if beanValue.Elem().Kind() == reflect.Ptr { + return false, errors.New("a pointer to a pointer is not allowed") + } + + if beanValue.Elem().Kind() == reflect.Struct { + if err := session.statement.setRefBean(bean); err != nil { + return false, err + } + } + + var sqlStr string + var args []interface{} + var err error + + if session.statement.RawSQL == "" { + if len(session.statement.TableName()) <= 0 { + return false, ErrTableNotFound + } + session.statement.Limit(1) + sqlStr, args, err = session.statement.genGetSQL(bean) + if err != nil { + return false, err + } + } else { + sqlStr = session.statement.RawSQL + args = session.statement.RawParams + } + + table := session.statement.RefTable + + if session.canCache() && beanValue.Elem().Kind() == reflect.Struct { + if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil && + !session.statement.unscoped { + has, err := session.cacheGet(bean, sqlStr, args...) + if err != ErrCacheFailed { + return has, err + } + } + } + + context := session.statement.context + if context != nil { + res := context.Get(fmt.Sprintf("%v-%v", sqlStr, args)) + if res != nil { + session.engine.logger.Debug("hit context cache", sqlStr) + + structValue := reflect.Indirect(reflect.ValueOf(bean)) + structValue.Set(reflect.Indirect(reflect.ValueOf(res))) + session.lastSQL = "" + session.lastSQLArgs = nil + return true, nil + } + } + + has, err := session.nocacheGet(beanValue.Elem().Kind(), table, bean, sqlStr, args...) + if err != nil || !has { + return has, err + } + + if context != nil { + context.Put(fmt.Sprintf("%v-%v", sqlStr, args), bean) + } + + return true, nil +} + +func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bean interface{}, sqlStr string, args ...interface{}) (bool, error) { + rows, err := session.queryRows(sqlStr, args...) + if err != nil { + return false, err + } + defer rows.Close() + + if !rows.Next() { + if rows.Err() != nil { + return false, rows.Err() + } + return false, nil + } + + switch bean.(type) { + case sql.NullInt64, sql.NullBool, sql.NullFloat64, sql.NullString: + return true, rows.Scan(&bean) + case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString: + return true, rows.Scan(bean) + case *string: + var res sql.NullString + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*string)) = res.String + } + return true, nil + case *int: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*int)) = int(res.Int64) + } + return true, nil + case *int8: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*int8)) = int8(res.Int64) + } + return true, nil + case *int16: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*int16)) = int16(res.Int64) + } + return true, nil + case *int32: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*int32)) = int32(res.Int64) + } + return true, nil + case *int64: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*int64)) = int64(res.Int64) + } + return true, nil + case *uint: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*uint)) = uint(res.Int64) + } + return true, nil + case *uint8: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*uint8)) = uint8(res.Int64) + } + return true, nil + case *uint16: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*uint16)) = uint16(res.Int64) + } + return true, nil + case *uint32: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*uint32)) = uint32(res.Int64) + } + return true, nil + case *uint64: + var res sql.NullInt64 + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*uint64)) = uint64(res.Int64) + } + return true, nil + case *bool: + var res sql.NullBool + if err := rows.Scan(&res); err != nil { + return true, err + } + if res.Valid { + *(bean.(*bool)) = res.Bool + } + return true, nil + } + + switch beanKind { + case reflect.Struct: + fields, err := rows.Columns() + if err != nil { + // WARN: Alougth rows return true, but get fields failed + return true, err + } + + scanResults, err := session.row2Slice(rows, fields, bean) + if err != nil { + return false, err + } + // close it before covert data + rows.Close() + + dataStruct := rValue(bean) + _, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table) + if err != nil { + return true, err + } + + return true, session.executeProcessors() + case reflect.Slice: + err = rows.ScanSlice(bean) + case reflect.Map: + err = rows.ScanMap(bean) + case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + err = rows.Scan(bean) + default: + err = rows.Scan(bean) + } + + return true, err +} + +func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) { + // if has no reftable, then don't use cache currently + if !session.canCache() { + return false, ErrCacheFailed + } + + for _, filter := range session.engine.dialect.Filters() { + sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable) + } + newsql := session.statement.convertIDSQL(sqlStr) + if newsql == "" { + return false, ErrCacheFailed + } + + tableName := session.statement.TableName() + cacher := session.engine.getCacher(tableName) + + session.engine.logger.Debug("[cacheGet] find sql:", newsql, args) + table := session.statement.RefTable + ids, err := core.GetCacheSql(cacher, tableName, newsql, args) + if err != nil { + var res = make([]string, len(table.PrimaryKeys)) + rows, err := session.NoCache().queryRows(newsql, args...) + if err != nil { + return false, err + } + defer rows.Close() + + if rows.Next() { + err = rows.ScanSlice(&res) + if err != nil { + return false, err + } + } else { + return false, ErrCacheFailed + } + + var pk core.PK = make([]interface{}, len(table.PrimaryKeys)) + for i, col := range table.PKColumns() { + if col.SQLType.IsText() { + pk[i] = res[i] + } else if col.SQLType.IsNumeric() { + n, err := strconv.ParseInt(res[i], 10, 64) + if err != nil { + return false, err + } + pk[i] = n + } else { + return false, errors.New("unsupported") + } + } + + ids = []core.PK{pk} + session.engine.logger.Debug("[cacheGet] cache ids:", newsql, ids) + err = core.PutCacheSql(cacher, ids, tableName, newsql, args) + if err != nil { + return false, err + } + } else { + session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql, ids) + } + + if len(ids) > 0 { + structValue := reflect.Indirect(reflect.ValueOf(bean)) + id := ids[0] + session.engine.logger.Debug("[cacheGet] get bean:", tableName, id) + sid, err := id.ToString() + if err != nil { + return false, err + } + cacheBean := cacher.GetBean(tableName, sid) + if cacheBean == nil { + cacheBean = bean + has, err = session.nocacheGet(reflect.Struct, table, cacheBean, sqlStr, args...) + if err != nil || !has { + return has, err + } + + session.engine.logger.Debug("[cacheGet] cache bean:", tableName, id, cacheBean) + cacher.PutBean(tableName, sid, cacheBean) + } else { + session.engine.logger.Debug("[cacheGet] cache hit bean:", tableName, id, cacheBean) + has = true + } + structValue.Set(reflect.Indirect(reflect.ValueOf(cacheBean))) + + return has, nil + } + return false, nil +} diff --git a/vendor/xorm.io/xorm/session_insert.go b/vendor/xorm.io/xorm/session_insert.go new file mode 100644 index 0000000000..1e19ce7a4e --- /dev/null +++ b/vendor/xorm.io/xorm/session_insert.go @@ -0,0 +1,878 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "reflect" + "sort" + "strconv" + "strings" + + "xorm.io/builder" + "xorm.io/core" +) + +// Insert insert one or more beans +func (session *Session) Insert(beans ...interface{}) (int64, error) { + var affected int64 + var err error + + if session.isAutoClose { + defer session.Close() + } + + session.autoResetStatement = false + defer func() { + session.autoResetStatement = true + session.resetStatement() + }() + + for _, bean := range beans { + switch bean.(type) { + case map[string]interface{}: + cnt, err := session.insertMapInterface(bean.(map[string]interface{})) + if err != nil { + return affected, err + } + affected += cnt + case []map[string]interface{}: + s := bean.([]map[string]interface{}) + for i := 0; i < len(s); i++ { + cnt, err := session.insertMapInterface(s[i]) + if err != nil { + return affected, err + } + affected += cnt + } + case map[string]string: + cnt, err := session.insertMapString(bean.(map[string]string)) + if err != nil { + return affected, err + } + affected += cnt + case []map[string]string: + s := bean.([]map[string]string) + for i := 0; i < len(s); i++ { + cnt, err := session.insertMapString(s[i]) + if err != nil { + return affected, err + } + affected += cnt + } + default: + sliceValue := reflect.Indirect(reflect.ValueOf(bean)) + if sliceValue.Kind() == reflect.Slice { + size := sliceValue.Len() + if size > 0 { + if session.engine.SupportInsertMany() { + cnt, err := session.innerInsertMulti(bean) + if err != nil { + return affected, err + } + affected += cnt + } else { + for i := 0; i < size; i++ { + cnt, err := session.innerInsert(sliceValue.Index(i).Interface()) + if err != nil { + return affected, err + } + affected += cnt + } + } + } + } else { + cnt, err := session.innerInsert(bean) + if err != nil { + return affected, err + } + affected += cnt + } + } + } + + return affected, err +} + +func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error) { + sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) + if sliceValue.Kind() != reflect.Slice { + return 0, errors.New("needs a pointer to a slice") + } + + if sliceValue.Len() <= 0 { + return 0, errors.New("could not insert a empty slice") + } + + if err := session.statement.setRefBean(sliceValue.Index(0).Interface()); err != nil { + return 0, err + } + + tableName := session.statement.TableName() + if len(tableName) <= 0 { + return 0, ErrTableNotFound + } + + table := session.statement.RefTable + size := sliceValue.Len() + + var colNames []string + var colMultiPlaces []string + var args []interface{} + var cols []*core.Column + + for i := 0; i < size; i++ { + v := sliceValue.Index(i) + vv := reflect.Indirect(v) + elemValue := v.Interface() + var colPlaces []string + + // handle BeforeInsertProcessor + // !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi?? + for _, closure := range session.beforeClosures { + closure(elemValue) + } + + if processor, ok := interface{}(elemValue).(BeforeInsertProcessor); ok { + processor.BeforeInsert() + } + // -- + + if i == 0 { + for _, col := range table.Columns() { + ptrFieldValue, err := col.ValueOfV(&vv) + if err != nil { + return 0, err + } + fieldValue := *ptrFieldValue + if col.IsAutoIncrement && isZero(fieldValue.Interface()) { + continue + } + if col.MapType == core.ONLYFROMDB { + continue + } + if col.IsDeleted { + continue + } + if session.statement.omitColumnMap.contain(col.Name) { + continue + } + if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { + continue + } + if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { + val, t := session.engine.nowTime(col) + args = append(args, val) + + var colName = col.Name + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnTime(bean, col, t) + }) + } else if col.IsVersion && session.statement.checkVersion { + args = append(args, 1) + var colName = col.Name + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnInt(bean, col, 1) + }) + } else { + arg, err := session.value2Interface(col, fieldValue) + if err != nil { + return 0, err + } + args = append(args, arg) + } + + colNames = append(colNames, col.Name) + cols = append(cols, col) + colPlaces = append(colPlaces, "?") + } + } else { + for _, col := range cols { + ptrFieldValue, err := col.ValueOfV(&vv) + if err != nil { + return 0, err + } + fieldValue := *ptrFieldValue + + if col.IsAutoIncrement && isZero(fieldValue.Interface()) { + continue + } + if col.MapType == core.ONLYFROMDB { + continue + } + if col.IsDeleted { + continue + } + if session.statement.omitColumnMap.contain(col.Name) { + continue + } + if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { + continue + } + if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime { + val, t := session.engine.nowTime(col) + args = append(args, val) + + var colName = col.Name + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnTime(bean, col, t) + }) + } else if col.IsVersion && session.statement.checkVersion { + args = append(args, 1) + var colName = col.Name + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnInt(bean, col, 1) + }) + } else { + arg, err := session.value2Interface(col, fieldValue) + if err != nil { + return 0, err + } + args = append(args, arg) + } + + colPlaces = append(colPlaces, "?") + } + } + colMultiPlaces = append(colMultiPlaces, strings.Join(colPlaces, ", ")) + } + cleanupProcessorsClosures(&session.beforeClosures) + + var sql string + if session.engine.dialect.DBType() == core.ORACLE { + temp := fmt.Sprintf(") INTO %s (%v) VALUES (", + session.engine.Quote(tableName), + quoteColumns(colNames, session.engine.Quote, ",")) + sql = fmt.Sprintf("INSERT ALL INTO %s (%v) VALUES (%v) SELECT 1 FROM DUAL", + session.engine.Quote(tableName), + quoteColumns(colNames, session.engine.Quote, ","), + strings.Join(colMultiPlaces, temp)) + } else { + sql = fmt.Sprintf("INSERT INTO %s (%v) VALUES (%v)", + session.engine.Quote(tableName), + quoteColumns(colNames, session.engine.Quote, ","), + strings.Join(colMultiPlaces, "),(")) + } + res, err := session.exec(sql, args...) + if err != nil { + return 0, err + } + + session.cacheInsert(tableName) + + lenAfterClosures := len(session.afterClosures) + for i := 0; i < size; i++ { + elemValue := reflect.Indirect(sliceValue.Index(i)).Addr().Interface() + + // handle AfterInsertProcessor + if session.isAutoCommit { + // !nashtsai! does user expect it's same slice to passed closure when using Before()/After() when insert multi?? + for _, closure := range session.afterClosures { + closure(elemValue) + } + if processor, ok := interface{}(elemValue).(AfterInsertProcessor); ok { + processor.AfterInsert() + } + } else { + if lenAfterClosures > 0 { + if value, has := session.afterInsertBeans[elemValue]; has && value != nil { + *value = append(*value, session.afterClosures...) + } else { + afterClosures := make([]func(interface{}), lenAfterClosures) + copy(afterClosures, session.afterClosures) + session.afterInsertBeans[elemValue] = &afterClosures + } + } else { + if _, ok := interface{}(elemValue).(AfterInsertProcessor); ok { + session.afterInsertBeans[elemValue] = nil + } + } + } + } + + cleanupProcessorsClosures(&session.afterClosures) + return res.RowsAffected() +} + +// InsertMulti insert multiple records +func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) { + if session.isAutoClose { + defer session.Close() + } + + sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) + if sliceValue.Kind() != reflect.Slice { + return 0, ErrParamsType + + } + + if sliceValue.Len() <= 0 { + return 0, nil + } + + return session.innerInsertMulti(rowsSlicePtr) +} + +func (session *Session) innerInsert(bean interface{}) (int64, error) { + if err := session.statement.setRefBean(bean); err != nil { + return 0, err + } + if len(session.statement.TableName()) <= 0 { + return 0, ErrTableNotFound + } + + table := session.statement.RefTable + + // handle BeforeInsertProcessor + for _, closure := range session.beforeClosures { + closure(bean) + } + cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used + + if processor, ok := interface{}(bean).(BeforeInsertProcessor); ok { + processor.BeforeInsert() + } + + colNames, args, err := session.genInsertColumns(bean) + if err != nil { + return 0, err + } + + exprs := session.statement.exprColumns + colPlaces := strings.Repeat("?, ", len(colNames)) + if exprs.Len() <= 0 && len(colPlaces) > 0 { + colPlaces = colPlaces[0 : len(colPlaces)-2] + } + + var tableName = session.statement.TableName() + var output string + if session.engine.dialect.DBType() == core.MSSQL && len(table.AutoIncrement) > 0 { + output = fmt.Sprintf(" OUTPUT Inserted.%s", table.AutoIncrement) + } + + var buf = builder.NewWriter() + if _, err := buf.WriteString(fmt.Sprintf("INSERT INTO %s", session.engine.Quote(tableName))); err != nil { + return 0, err + } + + if len(colPlaces) <= 0 { + if session.engine.dialect.DBType() == core.MYSQL { + if _, err := buf.WriteString(" VALUES ()"); err != nil { + return 0, err + } + } else { + if _, err := buf.WriteString(fmt.Sprintf("%s DEFAULT VALUES", output)); err != nil { + return 0, err + } + } + } else { + if _, err := buf.WriteString(" ("); err != nil { + return 0, err + } + + if err := writeStrings(buf, append(colNames, exprs.colNames...), "`", "`"); err != nil { + return 0, err + } + + if session.statement.cond.IsValid() { + if _, err := buf.WriteString(fmt.Sprintf(")%s SELECT ", output)); err != nil { + return 0, err + } + + if err := session.statement.writeArgs(buf, args); err != nil { + return 0, err + } + + if len(exprs.args) > 0 { + if _, err := buf.WriteString(","); err != nil { + return 0, err + } + } + if err := exprs.writeArgs(buf); err != nil { + return 0, err + } + + if _, err := buf.WriteString(fmt.Sprintf(" FROM %v WHERE ", session.engine.Quote(tableName))); err != nil { + return 0, err + } + + if err := session.statement.cond.WriteTo(buf); err != nil { + return 0, err + } + } else { + buf.Append(args...) + + if _, err := buf.WriteString(fmt.Sprintf(")%s VALUES (%v", + output, + colPlaces)); err != nil { + return 0, err + } + + if err := exprs.writeArgs(buf); err != nil { + return 0, err + } + + if _, err := buf.WriteString(")"); err != nil { + return 0, err + } + } + } + + if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == core.POSTGRES { + if _, err := buf.WriteString(" RETURNING " + session.engine.Quote(table.AutoIncrement)); err != nil { + return 0, err + } + } + + sqlStr := buf.String() + args = buf.Args() + + handleAfterInsertProcessorFunc := func(bean interface{}) { + if session.isAutoCommit { + for _, closure := range session.afterClosures { + closure(bean) + } + if processor, ok := interface{}(bean).(AfterInsertProcessor); ok { + processor.AfterInsert() + } + } else { + lenAfterClosures := len(session.afterClosures) + if lenAfterClosures > 0 { + if value, has := session.afterInsertBeans[bean]; has && value != nil { + *value = append(*value, session.afterClosures...) + } else { + afterClosures := make([]func(interface{}), lenAfterClosures) + copy(afterClosures, session.afterClosures) + session.afterInsertBeans[bean] = &afterClosures + } + + } else { + if _, ok := interface{}(bean).(AfterInsertProcessor); ok { + session.afterInsertBeans[bean] = nil + } + } + } + cleanupProcessorsClosures(&session.afterClosures) // cleanup after used + } + + // for postgres, many of them didn't implement lastInsertId, so we should + // implemented it ourself. + if session.engine.dialect.DBType() == core.ORACLE && len(table.AutoIncrement) > 0 { + res, err := session.queryBytes("select seq_atable.currval from dual", args...) + if err != nil { + return 0, err + } + + defer handleAfterInsertProcessorFunc(bean) + + session.cacheInsert(tableName) + + if table.Version != "" && session.statement.checkVersion { + verValue, err := table.VersionColumn().ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } else if verValue.IsValid() && verValue.CanSet() { + session.incrVersionFieldValue(verValue) + } + } + + if len(res) < 1 { + return 0, errors.New("insert no error but not returned id") + } + + idByte := res[0][table.AutoIncrement] + id, err := strconv.ParseInt(string(idByte), 10, 64) + if err != nil || id <= 0 { + return 1, err + } + + aiValue, err := table.AutoIncrColumn().ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } + + if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { + return 1, nil + } + + aiValue.Set(int64ToIntValue(id, aiValue.Type())) + + return 1, nil + } else if len(table.AutoIncrement) > 0 && (session.engine.dialect.DBType() == core.POSTGRES || session.engine.dialect.DBType() == core.MSSQL) { + res, err := session.queryBytes(sqlStr, args...) + + if err != nil { + return 0, err + } + defer handleAfterInsertProcessorFunc(bean) + + session.cacheInsert(tableName) + + if table.Version != "" && session.statement.checkVersion { + verValue, err := table.VersionColumn().ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } else if verValue.IsValid() && verValue.CanSet() { + session.incrVersionFieldValue(verValue) + } + } + + if len(res) < 1 { + return 0, errors.New("insert successfully but not returned id") + } + + idByte := res[0][table.AutoIncrement] + id, err := strconv.ParseInt(string(idByte), 10, 64) + if err != nil || id <= 0 { + return 1, err + } + + aiValue, err := table.AutoIncrColumn().ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } + + if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { + return 1, nil + } + + aiValue.Set(int64ToIntValue(id, aiValue.Type())) + + return 1, nil + } else { + res, err := session.exec(sqlStr, args...) + if err != nil { + return 0, err + } + + defer handleAfterInsertProcessorFunc(bean) + + session.cacheInsert(tableName) + + if table.Version != "" && session.statement.checkVersion { + verValue, err := table.VersionColumn().ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } else if verValue.IsValid() && verValue.CanSet() { + session.incrVersionFieldValue(verValue) + } + } + + if table.AutoIncrement == "" { + return res.RowsAffected() + } + + var id int64 + id, err = res.LastInsertId() + if err != nil || id <= 0 { + return res.RowsAffected() + } + + aiValue, err := table.AutoIncrColumn().ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } + + if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { + return res.RowsAffected() + } + + aiValue.Set(int64ToIntValue(id, aiValue.Type())) + + return res.RowsAffected() + } +} + +// InsertOne insert only one struct into database as a record. +// The in parameter bean must a struct or a point to struct. The return +// parameter is inserted and error +func (session *Session) InsertOne(bean interface{}) (int64, error) { + if session.isAutoClose { + defer session.Close() + } + + return session.innerInsert(bean) +} + +func (session *Session) cacheInsert(table string) error { + if !session.statement.UseCache { + return nil + } + cacher := session.engine.getCacher(table) + if cacher == nil { + return nil + } + session.engine.logger.Debug("[cache] clear sql:", table) + cacher.ClearIds(table) + return nil +} + +// genInsertColumns generates insert needed columns +func (session *Session) genInsertColumns(bean interface{}) ([]string, []interface{}, error) { + table := session.statement.RefTable + colNames := make([]string, 0, len(table.ColumnsSeq())) + args := make([]interface{}, 0, len(table.ColumnsSeq())) + + for _, col := range table.Columns() { + if col.MapType == core.ONLYFROMDB { + continue + } + + if col.IsDeleted { + continue + } + + if session.statement.omitColumnMap.contain(col.Name) { + continue + } + + if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { + continue + } + + if session.statement.incrColumns.isColExist(col.Name) { + continue + } else if session.statement.decrColumns.isColExist(col.Name) { + continue + } else if session.statement.exprColumns.isColExist(col.Name) { + continue + } + + fieldValuePtr, err := col.ValueOf(bean) + if err != nil { + return nil, nil, err + } + fieldValue := *fieldValuePtr + + if col.IsAutoIncrement { + switch fieldValue.Type().Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: + if fieldValue.Int() == 0 { + continue + } + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: + if fieldValue.Uint() == 0 { + continue + } + case reflect.String: + if len(fieldValue.String()) == 0 { + continue + } + case reflect.Ptr: + if fieldValue.Pointer() == 0 { + continue + } + } + } + + // !evalphobia! set fieldValue as nil when column is nullable and zero-value + if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok { + if col.Nullable && isZero(fieldValue.Interface()) { + var nilValue *int + fieldValue = reflect.ValueOf(nilValue) + } + } + + if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { + // if time is non-empty, then set to auto time + val, t := session.engine.nowTime(col) + args = append(args, val) + + var colName = col.Name + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnTime(bean, col, t) + }) + } else if col.IsVersion && session.statement.checkVersion { + args = append(args, 1) + } else { + arg, err := session.value2Interface(col, fieldValue) + if err != nil { + return colNames, args, err + } + args = append(args, arg) + } + + colNames = append(colNames, col.Name) + } + return colNames, args, nil +} + +func (session *Session) insertMapInterface(m map[string]interface{}) (int64, error) { + if len(m) == 0 { + return 0, ErrParamsType + } + + tableName := session.statement.TableName() + if len(tableName) <= 0 { + return 0, ErrTableNotFound + } + + var columns = make([]string, 0, len(m)) + exprs := session.statement.exprColumns + for k := range m { + if !exprs.isColExist(k) { + columns = append(columns, k) + } + } + sort.Strings(columns) + + var args = make([]interface{}, 0, len(m)) + for _, colName := range columns { + args = append(args, m[colName]) + } + + w := builder.NewWriter() + if session.statement.cond.IsValid() { + if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil { + return 0, err + } + + if err := writeStrings(w, append(columns, exprs.colNames...), "`", "`"); err != nil { + return 0, err + } + + if _, err := w.WriteString(") SELECT "); err != nil { + return 0, err + } + + if err := session.statement.writeArgs(w, args); err != nil { + return 0, err + } + + if len(exprs.args) > 0 { + if _, err := w.WriteString(","); err != nil { + return 0, err + } + if err := exprs.writeArgs(w); err != nil { + return 0, err + } + } + + if _, err := w.WriteString(fmt.Sprintf(" FROM %s WHERE ", session.engine.Quote(tableName))); err != nil { + return 0, err + } + + if err := session.statement.cond.WriteTo(w); err != nil { + return 0, err + } + } else { + qm := strings.Repeat("?,", len(columns)) + qm = qm[:len(qm)-1] + + if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)); err != nil { + return 0, err + } + w.Append(args...) + } + + sql := w.String() + args = w.Args() + + if err := session.cacheInsert(tableName); err != nil { + return 0, err + } + + res, err := session.exec(sql, args...) + if err != nil { + return 0, err + } + affected, err := res.RowsAffected() + if err != nil { + return 0, err + } + return affected, nil +} + +func (session *Session) insertMapString(m map[string]string) (int64, error) { + if len(m) == 0 { + return 0, ErrParamsType + } + + tableName := session.statement.TableName() + if len(tableName) <= 0 { + return 0, ErrTableNotFound + } + + var columns = make([]string, 0, len(m)) + exprs := session.statement.exprColumns + for k := range m { + if !exprs.isColExist(k) { + columns = append(columns, k) + } + } + sort.Strings(columns) + + var args = make([]interface{}, 0, len(m)) + for _, colName := range columns { + args = append(args, m[colName]) + } + + w := builder.NewWriter() + if session.statement.cond.IsValid() { + if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil { + return 0, err + } + + if err := writeStrings(w, append(columns, exprs.colNames...), "`", "`"); err != nil { + return 0, err + } + + if _, err := w.WriteString(") SELECT "); err != nil { + return 0, err + } + + if err := session.statement.writeArgs(w, args); err != nil { + return 0, err + } + + if len(exprs.args) > 0 { + if _, err := w.WriteString(","); err != nil { + return 0, err + } + if err := exprs.writeArgs(w); err != nil { + return 0, err + } + } + + if _, err := w.WriteString(fmt.Sprintf(" FROM %s WHERE ", session.engine.Quote(tableName))); err != nil { + return 0, err + } + + if err := session.statement.cond.WriteTo(w); err != nil { + return 0, err + } + } else { + qm := strings.Repeat("?,", len(columns)) + qm = qm[:len(qm)-1] + + if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)); err != nil { + return 0, err + } + w.Append(args...) + } + + sql := w.String() + args = w.Args() + + if err := session.cacheInsert(tableName); err != nil { + return 0, err + } + + res, err := session.exec(sql, args...) + if err != nil { + return 0, err + } + affected, err := res.RowsAffected() + if err != nil { + return 0, err + } + return affected, nil +} diff --git a/vendor/xorm.io/xorm/session_iterate.go b/vendor/xorm.io/xorm/session_iterate.go new file mode 100644 index 0000000000..ca996c2884 --- /dev/null +++ b/vendor/xorm.io/xorm/session_iterate.go @@ -0,0 +1,100 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import "reflect" + +// IterFunc only use by Iterate +type IterFunc func(idx int, bean interface{}) error + +// Rows return sql.Rows compatible Rows obj, as a forward Iterator object for iterating record by record, bean's non-empty fields +// are conditions. +func (session *Session) Rows(bean interface{}) (*Rows, error) { + return newRows(session, bean) +} + +// Iterate record by record handle records from table, condiBeans's non-empty fields +// are conditions. beans could be []Struct, []*Struct, map[int64]Struct +// map[int64]*Struct +func (session *Session) Iterate(bean interface{}, fun IterFunc) error { + if session.isAutoClose { + defer session.Close() + } + + if session.statement.lastError != nil { + return session.statement.lastError + } + + if session.statement.bufferSize > 0 { + return session.bufferIterate(bean, fun) + } + + rows, err := session.Rows(bean) + if err != nil { + return err + } + defer rows.Close() + + i := 0 + for rows.Next() { + b := reflect.New(rows.beanType).Interface() + err = rows.Scan(b) + if err != nil { + return err + } + err = fun(i, b) + if err != nil { + return err + } + i++ + } + return err +} + +// BufferSize sets the buffersize for iterate +func (session *Session) BufferSize(size int) *Session { + session.statement.bufferSize = size + return session +} + +func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error { + if session.isAutoClose { + defer session.Close() + } + + var bufferSize = session.statement.bufferSize + var limit = session.statement.LimitN + if limit > 0 && bufferSize > limit { + bufferSize = limit + } + var start = session.statement.Start + v := rValue(bean) + sliceType := reflect.SliceOf(v.Type()) + var idx = 0 + for { + slice := reflect.New(sliceType) + if err := session.Limit(bufferSize, start).find(slice.Interface(), bean); err != nil { + return err + } + + for i := 0; i < slice.Elem().Len(); i++ { + if err := fun(idx, slice.Elem().Index(i).Addr().Interface()); err != nil { + return err + } + idx++ + } + + start = start + slice.Elem().Len() + if limit > 0 && idx+bufferSize > limit { + bufferSize = limit - idx + } + + if bufferSize <= 0 || slice.Elem().Len() < bufferSize || idx == limit { + break + } + } + + return nil +} diff --git a/vendor/xorm.io/xorm/session_query.go b/vendor/xorm.io/xorm/session_query.go new file mode 100644 index 0000000000..21c00b8d7f --- /dev/null +++ b/vendor/xorm.io/xorm/session_query.go @@ -0,0 +1,320 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "xorm.io/builder" + "xorm.io/core" +) + +func (session *Session) genQuerySQL(sqlOrArgs ...interface{}) (string, []interface{}, error) { + if len(sqlOrArgs) > 0 { + return convertSQLOrArgs(sqlOrArgs...) + } + + if session.statement.RawSQL != "" { + return session.statement.RawSQL, session.statement.RawParams, nil + } + + if len(session.statement.TableName()) <= 0 { + return "", nil, ErrTableNotFound + } + + var columnStr = session.statement.ColumnStr + if len(session.statement.selectStr) > 0 { + columnStr = session.statement.selectStr + } else { + if session.statement.JoinStr == "" { + if columnStr == "" { + if session.statement.GroupByStr != "" { + columnStr = session.engine.quoteColumns(session.statement.GroupByStr) + } else { + columnStr = session.statement.genColumnStr() + } + } + } else { + if columnStr == "" { + if session.statement.GroupByStr != "" { + columnStr = session.engine.quoteColumns(session.statement.GroupByStr) + } else { + columnStr = "*" + } + } + } + if columnStr == "" { + columnStr = "*" + } + } + + if err := session.statement.processIDParam(); err != nil { + return "", nil, err + } + + condSQL, condArgs, err := builder.ToSQL(session.statement.cond) + if err != nil { + return "", nil, err + } + + args := append(session.statement.joinArgs, condArgs...) + sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL, true, true) + if err != nil { + return "", nil, err + } + // for mssql and use limit + qs := strings.Count(sqlStr, "?") + if len(args)*2 == qs { + args = append(args, args...) + } + + return sqlStr, args, nil +} + +// Query runs a raw sql and return records as []map[string][]byte +func (session *Session) Query(sqlOrArgs ...interface{}) ([]map[string][]byte, error) { + if session.isAutoClose { + defer session.Close() + } + + sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) + if err != nil { + return nil, err + } + + return session.queryBytes(sqlStr, args...) +} + +func value2String(rawValue *reflect.Value) (str string, err error) { + aa := reflect.TypeOf((*rawValue).Interface()) + vv := reflect.ValueOf((*rawValue).Interface()) + switch aa.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + str = strconv.FormatInt(vv.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + str = strconv.FormatUint(vv.Uint(), 10) + case reflect.Float32, reflect.Float64: + str = strconv.FormatFloat(vv.Float(), 'f', -1, 64) + case reflect.String: + str = vv.String() + case reflect.Array, reflect.Slice: + switch aa.Elem().Kind() { + case reflect.Uint8: + data := rawValue.Interface().([]byte) + str = string(data) + if str == "\x00" { + str = "0" + } + default: + err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) + } + // time type + case reflect.Struct: + if aa.ConvertibleTo(core.TimeType) { + str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano) + } else { + err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) + } + case reflect.Bool: + str = strconv.FormatBool(vv.Bool()) + case reflect.Complex128, reflect.Complex64: + str = fmt.Sprintf("%v", vv.Complex()) + /* TODO: unsupported types below + case reflect.Map: + case reflect.Ptr: + case reflect.Uintptr: + case reflect.UnsafePointer: + case reflect.Chan, reflect.Func, reflect.Interface: + */ + default: + err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name()) + } + return +} + +func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) { + result := make(map[string]string) + scanResultContainers := make([]interface{}, len(fields)) + for i := 0; i < len(fields); i++ { + var scanResultContainer interface{} + scanResultContainers[i] = &scanResultContainer + } + if err := rows.Scan(scanResultContainers...); err != nil { + return nil, err + } + + for ii, key := range fields { + rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])) + // if row is null then as empty string + if rawValue.Interface() == nil { + result[key] = "" + continue + } + + if data, err := value2String(&rawValue); err == nil { + result[key] = data + } else { + return nil, err + } + } + return result, nil +} + +func row2sliceStr(rows *core.Rows, fields []string) (results []string, err error) { + result := make([]string, 0, len(fields)) + scanResultContainers := make([]interface{}, len(fields)) + for i := 0; i < len(fields); i++ { + var scanResultContainer interface{} + scanResultContainers[i] = &scanResultContainer + } + if err := rows.Scan(scanResultContainers...); err != nil { + return nil, err + } + + for i := 0; i < len(fields); i++ { + rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[i])) + // if row is null then as empty string + if rawValue.Interface() == nil { + result = append(result, "") + continue + } + + if data, err := value2String(&rawValue); err == nil { + result = append(result, data) + } else { + return nil, err + } + } + return result, nil +} + +func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) { + fields, err := rows.Columns() + if err != nil { + return nil, err + } + for rows.Next() { + result, err := row2mapStr(rows, fields) + if err != nil { + return nil, err + } + resultsSlice = append(resultsSlice, result) + } + + return resultsSlice, nil +} + +func rows2SliceString(rows *core.Rows) (resultsSlice [][]string, err error) { + fields, err := rows.Columns() + if err != nil { + return nil, err + } + for rows.Next() { + record, err := row2sliceStr(rows, fields) + if err != nil { + return nil, err + } + resultsSlice = append(resultsSlice, record) + } + + return resultsSlice, nil +} + +// QueryString runs a raw sql and return records as []map[string]string +func (session *Session) QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) { + if session.isAutoClose { + defer session.Close() + } + + sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) + if err != nil { + return nil, err + } + + rows, err := session.queryRows(sqlStr, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + return rows2Strings(rows) +} + +// QuerySliceString runs a raw sql and return records as [][]string +func (session *Session) QuerySliceString(sqlOrArgs ...interface{}) ([][]string, error) { + if session.isAutoClose { + defer session.Close() + } + + sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) + if err != nil { + return nil, err + } + + rows, err := session.queryRows(sqlStr, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + return rows2SliceString(rows) +} + +func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) { + resultsMap = make(map[string]interface{}, len(fields)) + scanResultContainers := make([]interface{}, len(fields)) + for i := 0; i < len(fields); i++ { + var scanResultContainer interface{} + scanResultContainers[i] = &scanResultContainer + } + if err := rows.Scan(scanResultContainers...); err != nil { + return nil, err + } + + for ii, key := range fields { + resultsMap[key] = reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])).Interface() + } + return +} + +func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) { + fields, err := rows.Columns() + if err != nil { + return nil, err + } + for rows.Next() { + result, err := row2mapInterface(rows, fields) + if err != nil { + return nil, err + } + resultsSlice = append(resultsSlice, result) + } + + return resultsSlice, nil +} + +// QueryInterface runs a raw sql and return records as []map[string]interface{} +func (session *Session) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) { + if session.isAutoClose { + defer session.Close() + } + + sqlStr, args, err := session.genQuerySQL(sqlOrArgs...) + if err != nil { + return nil, err + } + + rows, err := session.queryRows(sqlStr, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + return rows2Interfaces(rows) +} diff --git a/vendor/xorm.io/xorm/session_raw.go b/vendor/xorm.io/xorm/session_raw.go new file mode 100644 index 0000000000..67648ef130 --- /dev/null +++ b/vendor/xorm.io/xorm/session_raw.go @@ -0,0 +1,227 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "reflect" + "time" + + "xorm.io/builder" + "xorm.io/core" +) + +func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) { + for _, filter := range session.engine.dialect.Filters() { + *sqlStr = filter.Do(*sqlStr, session.engine.dialect, session.statement.RefTable) + } + + session.lastSQL = *sqlStr + session.lastSQLArgs = paramStr +} + +func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Rows, error) { + defer session.resetStatement() + + session.queryPreprocess(&sqlStr, args...) + + if session.engine.showSQL { + if session.engine.showExecTime { + b4ExecTime := time.Now() + defer func() { + execDuration := time.Since(b4ExecTime) + if len(args) > 0 { + session.engine.logger.Infof("[SQL] %s %#v - took: %v", sqlStr, args, execDuration) + } else { + session.engine.logger.Infof("[SQL] %s - took: %v", sqlStr, execDuration) + } + }() + } else { + if len(args) > 0 { + session.engine.logger.Infof("[SQL] %v %#v", sqlStr, args) + } else { + session.engine.logger.Infof("[SQL] %v", sqlStr) + } + } + } + + if session.isAutoCommit { + var db *core.DB + if session.sessionType == groupSession { + db = session.engine.engineGroup.Slave().DB() + } else { + db = session.DB() + } + + if session.prepareStmt { + // don't clear stmt since session will cache them + stmt, err := session.doPrepare(db, sqlStr) + if err != nil { + return nil, err + } + + rows, err := stmt.QueryContext(session.ctx, args...) + if err != nil { + return nil, err + } + return rows, nil + } + + rows, err := db.QueryContext(session.ctx, sqlStr, args...) + if err != nil { + return nil, err + } + return rows, nil + } + + rows, err := session.tx.QueryContext(session.ctx, sqlStr, args...) + if err != nil { + return nil, err + } + return rows, nil +} + +func (session *Session) queryRow(sqlStr string, args ...interface{}) *core.Row { + return core.NewRow(session.queryRows(sqlStr, args...)) +} + +func value2Bytes(rawValue *reflect.Value) ([]byte, error) { + str, err := value2String(rawValue) + if err != nil { + return nil, err + } + return []byte(str), nil +} + +func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) { + result := make(map[string][]byte) + scanResultContainers := make([]interface{}, len(fields)) + for i := 0; i < len(fields); i++ { + var scanResultContainer interface{} + scanResultContainers[i] = &scanResultContainer + } + if err := rows.Scan(scanResultContainers...); err != nil { + return nil, err + } + + for ii, key := range fields { + rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])) + //if row is null then ignore + if rawValue.Interface() == nil { + result[key] = []byte{} + continue + } + + if data, err := value2Bytes(&rawValue); err == nil { + result[key] = data + } else { + return nil, err // !nashtsai! REVIEW, should return err or just error log? + } + } + return result, nil +} + +func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) { + fields, err := rows.Columns() + if err != nil { + return nil, err + } + for rows.Next() { + result, err := row2map(rows, fields) + if err != nil { + return nil, err + } + resultsSlice = append(resultsSlice, result) + } + + return resultsSlice, nil +} + +func (session *Session) queryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) { + rows, err := session.queryRows(sqlStr, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + return rows2maps(rows) +} + +func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) { + defer session.resetStatement() + + session.queryPreprocess(&sqlStr, args...) + + if session.engine.showSQL { + if session.engine.showExecTime { + b4ExecTime := time.Now() + defer func() { + execDuration := time.Since(b4ExecTime) + if len(args) > 0 { + session.engine.logger.Infof("[SQL] %s %#v - took: %v", sqlStr, args, execDuration) + } else { + session.engine.logger.Infof("[SQL] %s - took: %v", sqlStr, execDuration) + } + }() + } else { + if len(args) > 0 { + session.engine.logger.Infof("[SQL] %v %#v", sqlStr, args) + } else { + session.engine.logger.Infof("[SQL] %v", sqlStr) + } + } + } + + if !session.isAutoCommit { + return session.tx.ExecContext(session.ctx, sqlStr, args...) + } + + if session.prepareStmt { + stmt, err := session.doPrepare(session.DB(), sqlStr) + if err != nil { + return nil, err + } + + res, err := stmt.ExecContext(session.ctx, args...) + if err != nil { + return nil, err + } + return res, nil + } + + return session.DB().ExecContext(session.ctx, sqlStr, args...) +} + +func convertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) { + switch sqlOrArgs[0].(type) { + case string: + return sqlOrArgs[0].(string), sqlOrArgs[1:], nil + case *builder.Builder: + return sqlOrArgs[0].(*builder.Builder).ToSQL() + case builder.Builder: + bd := sqlOrArgs[0].(builder.Builder) + return bd.ToSQL() + } + + return "", nil, ErrUnSupportedType +} + +// Exec raw sql +func (session *Session) Exec(sqlOrArgs ...interface{}) (sql.Result, error) { + if session.isAutoClose { + defer session.Close() + } + + if len(sqlOrArgs) == 0 { + return nil, ErrUnSupportedType + } + + sqlStr, args, err := convertSQLOrArgs(sqlOrArgs...) + if err != nil { + return nil, err + } + + return session.exec(sqlStr, args...) +} diff --git a/vendor/xorm.io/xorm/session_schema.go b/vendor/xorm.io/xorm/session_schema.go new file mode 100644 index 0000000000..5e576c29aa --- /dev/null +++ b/vendor/xorm.io/xorm/session_schema.go @@ -0,0 +1,430 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "fmt" + "strings" + + "xorm.io/core" +) + +// Ping test if database is ok +func (session *Session) Ping() error { + if session.isAutoClose { + defer session.Close() + } + + session.engine.logger.Infof("PING DATABASE %v", session.engine.DriverName()) + return session.DB().PingContext(session.ctx) +} + +// CreateTable create a table according a bean +func (session *Session) CreateTable(bean interface{}) error { + if session.isAutoClose { + defer session.Close() + } + + return session.createTable(bean) +} + +func (session *Session) createTable(bean interface{}) error { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + + sqlStr := session.statement.genCreateTableSQL() + _, err := session.exec(sqlStr) + return err +} + +// CreateIndexes create indexes +func (session *Session) CreateIndexes(bean interface{}) error { + if session.isAutoClose { + defer session.Close() + } + + return session.createIndexes(bean) +} + +func (session *Session) createIndexes(bean interface{}) error { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + + sqls := session.statement.genIndexSQL() + for _, sqlStr := range sqls { + _, err := session.exec(sqlStr) + if err != nil { + return err + } + } + return nil +} + +// CreateUniques create uniques +func (session *Session) CreateUniques(bean interface{}) error { + if session.isAutoClose { + defer session.Close() + } + return session.createUniques(bean) +} + +func (session *Session) createUniques(bean interface{}) error { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + + sqls := session.statement.genUniqueSQL() + for _, sqlStr := range sqls { + _, err := session.exec(sqlStr) + if err != nil { + return err + } + } + return nil +} + +// DropIndexes drop indexes +func (session *Session) DropIndexes(bean interface{}) error { + if session.isAutoClose { + defer session.Close() + } + + return session.dropIndexes(bean) +} + +func (session *Session) dropIndexes(bean interface{}) error { + if err := session.statement.setRefBean(bean); err != nil { + return err + } + + sqls := session.statement.genDelIndexSQL() + for _, sqlStr := range sqls { + _, err := session.exec(sqlStr) + if err != nil { + return err + } + } + return nil +} + +// DropTable drop table will drop table if exist, if drop failed, it will return error +func (session *Session) DropTable(beanOrTableName interface{}) error { + if session.isAutoClose { + defer session.Close() + } + + return session.dropTable(beanOrTableName) +} + +func (session *Session) dropTable(beanOrTableName interface{}) error { + tableName := session.engine.TableName(beanOrTableName) + var needDrop = true + if !session.engine.dialect.SupportDropIfExists() { + sqlStr, args := session.engine.dialect.TableCheckSql(tableName) + results, err := session.queryBytes(sqlStr, args...) + if err != nil { + return err + } + needDrop = len(results) > 0 + } + + if needDrop { + sqlStr := session.engine.Dialect().DropTableSql(session.engine.TableName(tableName, true)) + _, err := session.exec(sqlStr) + return err + } + return nil +} + +// IsTableExist if a table is exist +func (session *Session) IsTableExist(beanOrTableName interface{}) (bool, error) { + if session.isAutoClose { + defer session.Close() + } + + tableName := session.engine.TableName(beanOrTableName) + + return session.isTableExist(tableName) +} + +func (session *Session) isTableExist(tableName string) (bool, error) { + sqlStr, args := session.engine.dialect.TableCheckSql(tableName) + results, err := session.queryBytes(sqlStr, args...) + return len(results) > 0, err +} + +// IsTableEmpty if table have any records +func (session *Session) IsTableEmpty(bean interface{}) (bool, error) { + if session.isAutoClose { + defer session.Close() + } + return session.isTableEmpty(session.engine.TableName(bean)) +} + +func (session *Session) isTableEmpty(tableName string) (bool, error) { + var total int64 + sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(session.engine.TableName(tableName, true))) + err := session.queryRow(sqlStr).Scan(&total) + if err != nil { + if err == sql.ErrNoRows { + err = nil + } + return true, err + } + + return total == 0, nil +} + +// find if index is exist according cols +func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) { + indexes, err := session.engine.dialect.GetIndexes(tableName) + if err != nil { + return false, err + } + + for _, index := range indexes { + if sliceEq(index.Cols, cols) { + if unique { + return index.Type == core.UniqueType, nil + } + return index.Type == core.IndexType, nil + } + } + return false, nil +} + +func (session *Session) addColumn(colName string) error { + col := session.statement.RefTable.GetColumn(colName) + sql, args := session.statement.genAddColumnStr(col) + _, err := session.exec(sql, args...) + return err +} + +func (session *Session) addIndex(tableName, idxName string) error { + index := session.statement.RefTable.Indexes[idxName] + sqlStr := session.engine.dialect.CreateIndexSql(tableName, index) + _, err := session.exec(sqlStr) + return err +} + +func (session *Session) addUnique(tableName, uqeName string) error { + index := session.statement.RefTable.Indexes[uqeName] + sqlStr := session.engine.dialect.CreateIndexSql(tableName, index) + _, err := session.exec(sqlStr) + return err +} + +// Sync2 synchronize structs to database tables +func (session *Session) Sync2(beans ...interface{}) error { + engine := session.engine + + if session.isAutoClose { + session.isAutoClose = false + defer session.Close() + } + + tables, err := engine.dialect.GetTables() + if err != nil { + return err + } + + session.autoResetStatement = false + defer func() { + session.autoResetStatement = true + session.resetStatement() + }() + + for _, bean := range beans { + v := rValue(bean) + table, err := engine.mapType(v) + if err != nil { + return err + } + var tbName string + if len(session.statement.AltTableName) > 0 { + tbName = session.statement.AltTableName + } else { + tbName = engine.TableName(bean) + } + tbNameWithSchema := engine.tbNameWithSchema(tbName) + + var oriTable *core.Table + for _, tb := range tables { + if strings.EqualFold(engine.tbNameWithSchema(tb.Name), engine.tbNameWithSchema(tbName)) { + oriTable = tb + break + } + } + + // this is a new table + if oriTable == nil { + err = session.StoreEngine(session.statement.StoreEngine).createTable(bean) + if err != nil { + return err + } + + err = session.createUniques(bean) + if err != nil { + return err + } + + err = session.createIndexes(bean) + if err != nil { + return err + } + continue + } + + // this will modify an old table + if err = engine.loadTableInfo(oriTable); err != nil { + return err + } + + // check columns + for _, col := range table.Columns() { + var oriCol *core.Column + for _, col2 := range oriTable.Columns() { + if strings.EqualFold(col.Name, col2.Name) { + oriCol = col2 + break + } + } + + // column is not exist on table + if oriCol == nil { + session.statement.RefTable = table + session.statement.tableName = tbNameWithSchema + if err = session.addColumn(col.Name); err != nil { + return err + } + continue + } + + err = nil + expectedType := engine.dialect.SqlType(col) + curType := engine.dialect.SqlType(oriCol) + if expectedType != curType { + if expectedType == core.Text && + strings.HasPrefix(curType, core.Varchar) { + // currently only support mysql & postgres + if engine.dialect.DBType() == core.MYSQL || + engine.dialect.DBType() == core.POSTGRES { + engine.logger.Infof("Table %s column %s change type from %s to %s\n", + tbNameWithSchema, col.Name, curType, expectedType) + _, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) + } else { + engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n", + tbNameWithSchema, col.Name, curType, expectedType) + } + } else if strings.HasPrefix(curType, core.Varchar) && strings.HasPrefix(expectedType, core.Varchar) { + if engine.dialect.DBType() == core.MYSQL { + if oriCol.Length < col.Length { + engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", + tbNameWithSchema, col.Name, oriCol.Length, col.Length) + _, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) + } + } + } else { + if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') { + engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s", + tbNameWithSchema, col.Name, curType, expectedType) + } + } + } else if expectedType == core.Varchar { + if engine.dialect.DBType() == core.MYSQL { + if oriCol.Length < col.Length { + engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", + tbNameWithSchema, col.Name, oriCol.Length, col.Length) + _, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) + } + } + } + + if col.Default != oriCol.Default { + if (col.SQLType.Name == core.Bool || col.SQLType.Name == core.Boolean) && + ((strings.EqualFold(col.Default, "true") && oriCol.Default == "1") || + (strings.EqualFold(col.Default, "false") && oriCol.Default == "0")) { + } else { + engine.logger.Warnf("Table %s Column %s db default is %s, struct default is %s", + tbName, col.Name, oriCol.Default, col.Default) + } + } + if col.Nullable != oriCol.Nullable { + engine.logger.Warnf("Table %s Column %s db nullable is %v, struct nullable is %v", + tbName, col.Name, oriCol.Nullable, col.Nullable) + } + + if err != nil { + return err + } + } + + var foundIndexNames = make(map[string]bool) + var addedNames = make(map[string]*core.Index) + + for name, index := range table.Indexes { + var oriIndex *core.Index + for name2, index2 := range oriTable.Indexes { + if index.Equal(index2) { + oriIndex = index2 + foundIndexNames[name2] = true + break + } + } + + if oriIndex != nil { + if oriIndex.Type != index.Type { + sql := engine.dialect.DropIndexSql(tbNameWithSchema, oriIndex) + _, err = session.exec(sql) + if err != nil { + return err + } + oriIndex = nil + } + } + + if oriIndex == nil { + addedNames[name] = index + } + } + + for name2, index2 := range oriTable.Indexes { + if _, ok := foundIndexNames[name2]; !ok { + sql := engine.dialect.DropIndexSql(tbNameWithSchema, index2) + _, err = session.exec(sql) + if err != nil { + return err + } + } + } + + for name, index := range addedNames { + if index.Type == core.UniqueType { + session.statement.RefTable = table + session.statement.tableName = tbNameWithSchema + err = session.addUnique(tbNameWithSchema, name) + } else if index.Type == core.IndexType { + session.statement.RefTable = table + session.statement.tableName = tbNameWithSchema + err = session.addIndex(tbNameWithSchema, name) + } + if err != nil { + return err + } + } + + // check all the columns which removed from struct fields but left on database tables. + for _, colName := range oriTable.ColumnsSeq() { + if table.GetColumn(colName) == nil { + engine.logger.Warnf("Table %s has column %s but struct has not related field", engine.TableName(oriTable.Name, true), colName) + } + } + } + + return nil +} diff --git a/vendor/xorm.io/xorm/session_stats.go b/vendor/xorm.io/xorm/session_stats.go new file mode 100644 index 0000000000..c2cac83069 --- /dev/null +++ b/vendor/xorm.io/xorm/session_stats.go @@ -0,0 +1,98 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "errors" + "reflect" +) + +// Count counts the records. bean's non-empty fields +// are conditions. +func (session *Session) Count(bean ...interface{}) (int64, error) { + if session.isAutoClose { + defer session.Close() + } + + var sqlStr string + var args []interface{} + var err error + if session.statement.RawSQL == "" { + sqlStr, args, err = session.statement.genCountSQL(bean...) + if err != nil { + return 0, err + } + } else { + sqlStr = session.statement.RawSQL + args = session.statement.RawParams + } + + var total int64 + err = session.queryRow(sqlStr, args...).Scan(&total) + if err == sql.ErrNoRows || err == nil { + return total, nil + } + + return 0, err +} + +// sum call sum some column. bean's non-empty fields are conditions. +func (session *Session) sum(res interface{}, bean interface{}, columnNames ...string) error { + if session.isAutoClose { + defer session.Close() + } + + v := reflect.ValueOf(res) + if v.Kind() != reflect.Ptr { + return errors.New("need a pointer to a variable") + } + + var isSlice = v.Elem().Kind() == reflect.Slice + var sqlStr string + var args []interface{} + var err error + if len(session.statement.RawSQL) == 0 { + sqlStr, args, err = session.statement.genSumSQL(bean, columnNames...) + if err != nil { + return err + } + } else { + sqlStr = session.statement.RawSQL + args = session.statement.RawParams + } + + if isSlice { + err = session.queryRow(sqlStr, args...).ScanSlice(res) + } else { + err = session.queryRow(sqlStr, args...).Scan(res) + } + if err == sql.ErrNoRows || err == nil { + return nil + } + return err +} + +// Sum call sum some column. bean's non-empty fields are conditions. +func (session *Session) Sum(bean interface{}, columnName string) (res float64, err error) { + return res, session.sum(&res, bean, columnName) +} + +// SumInt call sum some column. bean's non-empty fields are conditions. +func (session *Session) SumInt(bean interface{}, columnName string) (res int64, err error) { + return res, session.sum(&res, bean, columnName) +} + +// Sums call sum some columns. bean's non-empty fields are conditions. +func (session *Session) Sums(bean interface{}, columnNames ...string) ([]float64, error) { + var res = make([]float64, len(columnNames), len(columnNames)) + return res, session.sum(&res, bean, columnNames...) +} + +// SumsInt sum specify columns and return as []int64 instead of []float64 +func (session *Session) SumsInt(bean interface{}, columnNames ...string) ([]int64, error) { + var res = make([]int64, len(columnNames), len(columnNames)) + return res, session.sum(&res, bean, columnNames...) +} diff --git a/vendor/xorm.io/xorm/session_tx.go b/vendor/xorm.io/xorm/session_tx.go new file mode 100644 index 0000000000..ee3d473f95 --- /dev/null +++ b/vendor/xorm.io/xorm/session_tx.go @@ -0,0 +1,83 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +// Begin a transaction +func (session *Session) Begin() error { + if session.isAutoCommit { + tx, err := session.DB().BeginTx(session.ctx, nil) + if err != nil { + return err + } + session.isAutoCommit = false + session.isCommitedOrRollbacked = false + session.tx = tx + session.saveLastSQL("BEGIN TRANSACTION") + } + return nil +} + +// Rollback When using transaction, you can rollback if any error +func (session *Session) Rollback() error { + if !session.isAutoCommit && !session.isCommitedOrRollbacked { + session.saveLastSQL(session.engine.dialect.RollBackStr()) + session.isCommitedOrRollbacked = true + session.isAutoCommit = true + return session.tx.Rollback() + } + return nil +} + +// Commit When using transaction, Commit will commit all operations. +func (session *Session) Commit() error { + if !session.isAutoCommit && !session.isCommitedOrRollbacked { + session.saveLastSQL("COMMIT") + session.isCommitedOrRollbacked = true + session.isAutoCommit = true + var err error + if err = session.tx.Commit(); err == nil { + // handle processors after tx committed + closureCallFunc := func(closuresPtr *[]func(interface{}), bean interface{}) { + if closuresPtr != nil { + for _, closure := range *closuresPtr { + closure(bean) + } + } + } + + for bean, closuresPtr := range session.afterInsertBeans { + closureCallFunc(closuresPtr, bean) + + if processor, ok := interface{}(bean).(AfterInsertProcessor); ok { + processor.AfterInsert() + } + } + for bean, closuresPtr := range session.afterUpdateBeans { + closureCallFunc(closuresPtr, bean) + + if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok { + processor.AfterUpdate() + } + } + for bean, closuresPtr := range session.afterDeleteBeans { + closureCallFunc(closuresPtr, bean) + + if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok { + processor.AfterDelete() + } + } + cleanUpFunc := func(slices *map[interface{}]*[]func(interface{})) { + if len(*slices) > 0 { + *slices = make(map[interface{}]*[]func(interface{}), 0) + } + } + cleanUpFunc(&session.afterInsertBeans) + cleanUpFunc(&session.afterUpdateBeans) + cleanUpFunc(&session.afterDeleteBeans) + } + return err + } + return nil +} diff --git a/vendor/xorm.io/xorm/session_update.go b/vendor/xorm.io/xorm/session_update.go new file mode 100644 index 0000000000..c5c65a452a --- /dev/null +++ b/vendor/xorm.io/xorm/session_update.go @@ -0,0 +1,525 @@ +// Copyright 2016 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "strings" + + "xorm.io/builder" + "xorm.io/core" +) + +func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string, args ...interface{}) error { + if table == nil || + session.tx != nil { + return ErrCacheFailed + } + + oldhead, newsql := session.statement.convertUpdateSQL(sqlStr) + if newsql == "" { + return ErrCacheFailed + } + for _, filter := range session.engine.dialect.Filters() { + newsql = filter.Do(newsql, session.engine.dialect, table) + } + session.engine.logger.Debug("[cacheUpdate] new sql", oldhead, newsql) + + var nStart int + if len(args) > 0 { + if strings.Index(sqlStr, "?") > -1 { + nStart = strings.Count(oldhead, "?") + } else { + // only for pq, TODO: if any other databse? + nStart = strings.Count(oldhead, "$") + } + } + + cacher := session.engine.getCacher(tableName) + session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:]) + ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:]) + if err != nil { + rows, err := session.NoCache().queryRows(newsql, args[nStart:]...) + if err != nil { + return err + } + defer rows.Close() + + ids = make([]core.PK, 0) + for rows.Next() { + var res = make([]string, len(table.PrimaryKeys)) + err = rows.ScanSlice(&res) + if err != nil { + return err + } + var pk core.PK = make([]interface{}, len(table.PrimaryKeys)) + for i, col := range table.PKColumns() { + if col.SQLType.IsNumeric() { + n, err := strconv.ParseInt(res[i], 10, 64) + if err != nil { + return err + } + pk[i] = n + } else if col.SQLType.IsText() { + pk[i] = res[i] + } else { + return errors.New("not supported") + } + } + + ids = append(ids, pk) + } + session.engine.logger.Debug("[cacheUpdate] find updated id", ids) + } /*else { + session.engine.LogDebug("[xorm:cacheUpdate] del cached sql:", tableName, newsql, args) + cacher.DelIds(tableName, genSqlKey(newsql, args)) + }*/ + + for _, id := range ids { + sid, err := id.ToString() + if err != nil { + return err + } + if bean := cacher.GetBean(tableName, sid); bean != nil { + sqls := splitNNoCase(sqlStr, "where", 2) + if len(sqls) == 0 || len(sqls) > 2 { + return ErrCacheFailed + } + + sqls = splitNNoCase(sqls[0], "set", 2) + if len(sqls) != 2 { + return ErrCacheFailed + } + kvs := strings.Split(strings.TrimSpace(sqls[1]), ",") + + for idx, kv := range kvs { + sps := strings.SplitN(kv, "=", 2) + sps2 := strings.Split(sps[0], ".") + colName := sps2[len(sps2)-1] + // treat quote prefix, suffix and '`' as quotes + quotes := append(strings.Split(session.engine.Quote(""), ""), "`") + if strings.ContainsAny(colName, strings.Join(quotes, "")) { + colName = strings.TrimSpace(eraseAny(colName, quotes...)) + } else { + session.engine.logger.Debug("[cacheUpdate] cannot find column", tableName, colName) + return ErrCacheFailed + } + + if col := table.GetColumn(colName); col != nil { + fieldValue, err := col.ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } else { + session.engine.logger.Debug("[cacheUpdate] set bean field", bean, colName, fieldValue.Interface()) + if col.IsVersion && session.statement.checkVersion { + session.incrVersionFieldValue(fieldValue) + } else { + fieldValue.Set(reflect.ValueOf(args[idx])) + } + } + } else { + session.engine.logger.Errorf("[cacheUpdate] ERROR: column %v is not table %v's", + colName, table.Name) + } + } + + session.engine.logger.Debug("[cacheUpdate] update cache", tableName, id, bean) + cacher.PutBean(tableName, sid, bean) + } + } + session.engine.logger.Debug("[cacheUpdate] clear cached table sql:", tableName) + cacher.ClearIds(tableName) + return nil +} + +// Update records, bean's non-empty fields are updated contents, +// condiBean' non-empty filds are conditions +// CAUTION: +// 1.bool will defaultly be updated content nor conditions +// You should call UseBool if you have bool to use. +// 2.float32 & float64 may be not inexact as conditions +func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int64, error) { + if session.isAutoClose { + defer session.Close() + } + + if session.statement.lastError != nil { + return 0, session.statement.lastError + } + + v := rValue(bean) + t := v.Type() + + var colNames []string + var args []interface{} + + // handle before update processors + for _, closure := range session.beforeClosures { + closure(bean) + } + cleanupProcessorsClosures(&session.beforeClosures) // cleanup after used + if processor, ok := interface{}(bean).(BeforeUpdateProcessor); ok { + processor.BeforeUpdate() + } + // -- + + var err error + var isMap = t.Kind() == reflect.Map + var isStruct = t.Kind() == reflect.Struct + if isStruct { + if err := session.statement.setRefBean(bean); err != nil { + return 0, err + } + + if len(session.statement.TableName()) <= 0 { + return 0, ErrTableNotFound + } + + if session.statement.ColumnStr == "" { + colNames, args = session.statement.buildUpdates(bean, false, false, + false, false, true) + } else { + colNames, args, err = session.genUpdateColumns(bean) + if err != nil { + return 0, err + } + } + } else if isMap { + colNames = make([]string, 0) + args = make([]interface{}, 0) + bValue := reflect.Indirect(reflect.ValueOf(bean)) + + for _, v := range bValue.MapKeys() { + colNames = append(colNames, session.engine.Quote(v.String())+" = ?") + args = append(args, bValue.MapIndex(v).Interface()) + } + } else { + return 0, ErrParamsType + } + + table := session.statement.RefTable + + if session.statement.UseAutoTime && table != nil && table.Updated != "" { + if !session.statement.columnMap.contain(table.Updated) && + !session.statement.omitColumnMap.contain(table.Updated) { + colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?") + col := table.UpdatedColumn() + val, t := session.engine.nowTime(col) + args = append(args, val) + + var colName = col.Name + if isStruct { + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnTime(bean, col, t) + }) + } + } + } + + // for update action to like "column = column + ?" + incColumns := session.statement.incrColumns + for i, colName := range incColumns.colNames { + colNames = append(colNames, session.engine.Quote(colName)+" = "+session.engine.Quote(colName)+" + ?") + args = append(args, incColumns.args[i]) + } + // for update action to like "column = column - ?" + decColumns := session.statement.decrColumns + for i, colName := range decColumns.colNames { + colNames = append(colNames, session.engine.Quote(colName)+" = "+session.engine.Quote(colName)+" - ?") + args = append(args, decColumns.args[i]) + } + // for update action to like "column = expression" + exprColumns := session.statement.exprColumns + for i, colName := range exprColumns.colNames { + switch tp := exprColumns.args[i].(type) { + case string: + colNames = append(colNames, session.engine.Quote(colName)+" = "+tp) + case *builder.Builder: + subQuery, subArgs, err := builder.ToSQL(tp) + if err != nil { + return 0, err + } + colNames = append(colNames, session.engine.Quote(colName)+" = ("+subQuery+")") + args = append(args, subArgs...) + } + } + + if err = session.statement.processIDParam(); err != nil { + return 0, err + } + + var autoCond builder.Cond + if !session.statement.noAutoCondition { + condBeanIsStruct := false + if len(condiBean) > 0 { + if c, ok := condiBean[0].(map[string]interface{}); ok { + autoCond = builder.Eq(c) + } else { + ct := reflect.TypeOf(condiBean[0]) + k := ct.Kind() + if k == reflect.Ptr { + k = ct.Elem().Kind() + } + if k == reflect.Struct { + var err error + autoCond, err = session.statement.buildConds(session.statement.RefTable, condiBean[0], true, true, false, true, false) + if err != nil { + return 0, err + } + condBeanIsStruct = true + } else { + return 0, ErrConditionType + } + } + } + + if !condBeanIsStruct && table != nil { + if col := table.DeletedColumn(); col != nil && !session.statement.unscoped { // tag "deleted" is enabled + autoCond1 := session.engine.CondDeleted(session.engine.Quote(col.Name)) + + if autoCond == nil { + autoCond = autoCond1 + } else { + autoCond = autoCond.And(autoCond1) + } + } + } + } + + st := &session.statement + + var sqlStr string + var condArgs []interface{} + var condSQL string + cond := session.statement.cond.And(autoCond) + + var doIncVer = (table != nil && table.Version != "" && session.statement.checkVersion) + var verValue *reflect.Value + if doIncVer { + verValue, err = table.VersionColumn().ValueOf(bean) + if err != nil { + return 0, err + } + + cond = cond.And(builder.Eq{session.engine.Quote(table.Version): verValue.Interface()}) + colNames = append(colNames, session.engine.Quote(table.Version)+" = "+session.engine.Quote(table.Version)+" + 1") + } + + condSQL, condArgs, err = builder.ToSQL(cond) + if err != nil { + return 0, err + } + + if len(condSQL) > 0 { + condSQL = "WHERE " + condSQL + } + + if st.OrderStr != "" { + condSQL = condSQL + fmt.Sprintf(" ORDER BY %v", st.OrderStr) + } + + var tableName = session.statement.TableName() + // TODO: Oracle support needed + var top string + if st.LimitN > 0 { + if st.Engine.dialect.DBType() == core.MYSQL { + condSQL = condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN) + } else if st.Engine.dialect.DBType() == core.SQLITE { + tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN) + cond = cond.And(builder.Expr(fmt.Sprintf("rowid IN (SELECT rowid FROM %v %v)", + session.engine.Quote(tableName), tempCondSQL), condArgs...)) + condSQL, condArgs, err = builder.ToSQL(cond) + if err != nil { + return 0, err + } + if len(condSQL) > 0 { + condSQL = "WHERE " + condSQL + } + } else if st.Engine.dialect.DBType() == core.POSTGRES { + tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN) + cond = cond.And(builder.Expr(fmt.Sprintf("CTID IN (SELECT CTID FROM %v %v)", + session.engine.Quote(tableName), tempCondSQL), condArgs...)) + condSQL, condArgs, err = builder.ToSQL(cond) + if err != nil { + return 0, err + } + + if len(condSQL) > 0 { + condSQL = "WHERE " + condSQL + } + } else if st.Engine.dialect.DBType() == core.MSSQL { + if st.OrderStr != "" && st.Engine.dialect.DBType() == core.MSSQL && + table != nil && len(table.PrimaryKeys) == 1 { + cond = builder.Expr(fmt.Sprintf("%s IN (SELECT TOP (%d) %s FROM %v%v)", + table.PrimaryKeys[0], st.LimitN, table.PrimaryKeys[0], + session.engine.Quote(tableName), condSQL), condArgs...) + + condSQL, condArgs, err = builder.ToSQL(cond) + if err != nil { + return 0, err + } + if len(condSQL) > 0 { + condSQL = "WHERE " + condSQL + } + } else { + top = fmt.Sprintf("TOP (%d) ", st.LimitN) + } + } + } + + if len(colNames) <= 0 { + return 0, errors.New("No content found to be updated") + } + + sqlStr = fmt.Sprintf("UPDATE %v%v SET %v %v", + top, + session.engine.Quote(tableName), + strings.Join(colNames, ", "), + condSQL) + + res, err := session.exec(sqlStr, append(args, condArgs...)...) + if err != nil { + return 0, err + } else if doIncVer { + if verValue != nil && verValue.IsValid() && verValue.CanSet() { + session.incrVersionFieldValue(verValue) + } + } + + if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache { + // session.cacheUpdate(table, tableName, sqlStr, args...) + session.engine.logger.Debug("[cacheUpdate] clear table ", tableName) + cacher.ClearIds(tableName) + cacher.ClearBeans(tableName) + } + + // handle after update processors + if session.isAutoCommit { + for _, closure := range session.afterClosures { + closure(bean) + } + if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok { + session.engine.logger.Debug("[event]", tableName, " has after update processor") + processor.AfterUpdate() + } + } else { + lenAfterClosures := len(session.afterClosures) + if lenAfterClosures > 0 { + if value, has := session.afterUpdateBeans[bean]; has && value != nil { + *value = append(*value, session.afterClosures...) + } else { + afterClosures := make([]func(interface{}), lenAfterClosures) + copy(afterClosures, session.afterClosures) + // FIXME: if bean is a map type, it will panic because map cannot be as map key + session.afterUpdateBeans[bean] = &afterClosures + } + + } else { + if _, ok := interface{}(bean).(AfterUpdateProcessor); ok { + session.afterUpdateBeans[bean] = nil + } + } + } + cleanupProcessorsClosures(&session.afterClosures) // cleanup after used + // -- + + return res.RowsAffected() +} + +func (session *Session) genUpdateColumns(bean interface{}) ([]string, []interface{}, error) { + table := session.statement.RefTable + colNames := make([]string, 0, len(table.ColumnsSeq())) + args := make([]interface{}, 0, len(table.ColumnsSeq())) + + for _, col := range table.Columns() { + if !col.IsVersion && !col.IsCreated && !col.IsUpdated { + if session.statement.omitColumnMap.contain(col.Name) { + continue + } + } + if col.MapType == core.ONLYFROMDB { + continue + } + + fieldValuePtr, err := col.ValueOf(bean) + if err != nil { + return nil, nil, err + } + fieldValue := *fieldValuePtr + + if col.IsAutoIncrement { + switch fieldValue.Type().Kind() { + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64: + if fieldValue.Int() == 0 { + continue + } + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64: + if fieldValue.Uint() == 0 { + continue + } + case reflect.String: + if len(fieldValue.String()) == 0 { + continue + } + case reflect.Ptr: + if fieldValue.Pointer() == 0 { + continue + } + } + } + + if (col.IsDeleted && !session.statement.unscoped) || col.IsCreated { + continue + } + + // if only update specify columns + if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) { + continue + } + + if session.statement.incrColumns.isColExist(col.Name) { + continue + } else if session.statement.decrColumns.isColExist(col.Name) { + continue + } else if session.statement.exprColumns.isColExist(col.Name) { + continue + } + + // !evalphobia! set fieldValue as nil when column is nullable and zero-value + if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok { + if col.Nullable && isZero(fieldValue.Interface()) { + var nilValue *int + fieldValue = reflect.ValueOf(nilValue) + } + } + + if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ { + // if time is non-empty, then set to auto time + val, t := session.engine.nowTime(col) + args = append(args, val) + + var colName = col.Name + session.afterClosures = append(session.afterClosures, func(bean interface{}) { + col := table.GetColumn(colName) + setColumnTime(bean, col, t) + }) + } else if col.IsVersion && session.statement.checkVersion { + args = append(args, 1) + } else { + arg, err := session.value2Interface(col, fieldValue) + if err != nil { + return colNames, args, err + } + args = append(args, arg) + } + + colNames = append(colNames, session.engine.Quote(col.Name)+" = ?") + } + return colNames, args, nil +} diff --git a/vendor/xorm.io/xorm/statement.go b/vendor/xorm.io/xorm/statement.go new file mode 100644 index 0000000000..67e352136f --- /dev/null +++ b/vendor/xorm.io/xorm/statement.go @@ -0,0 +1,1256 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql/driver" + "fmt" + "reflect" + "strings" + "time" + + "xorm.io/builder" + "xorm.io/core" +) + +// Statement save all the sql info for executing SQL +type Statement struct { + RefTable *core.Table + Engine *Engine + Start int + LimitN int + idParam *core.PK + OrderStr string + JoinStr string + joinArgs []interface{} + GroupByStr string + HavingStr string + ColumnStr string + selectStr string + useAllCols bool + OmitStr string + AltTableName string + tableName string + RawSQL string + RawParams []interface{} + UseCascade bool + UseAutoJoin bool + StoreEngine string + Charset string + UseCache bool + UseAutoTime bool + noAutoCondition bool + IsDistinct bool + IsForUpdate bool + TableAlias string + allUseBool bool + checkVersion bool + unscoped bool + columnMap columnMap + omitColumnMap columnMap + mustColumnMap map[string]bool + nullableMap map[string]bool + incrColumns exprParams + decrColumns exprParams + exprColumns exprParams + cond builder.Cond + bufferSize int + context ContextCache + lastError error +} + +// Init reset all the statement's fields +func (statement *Statement) Init() { + statement.RefTable = nil + statement.Start = 0 + statement.LimitN = 0 + statement.OrderStr = "" + statement.UseCascade = true + statement.JoinStr = "" + statement.joinArgs = make([]interface{}, 0) + statement.GroupByStr = "" + statement.HavingStr = "" + statement.ColumnStr = "" + statement.OmitStr = "" + statement.columnMap = columnMap{} + statement.omitColumnMap = columnMap{} + statement.AltTableName = "" + statement.tableName = "" + statement.idParam = nil + statement.RawSQL = "" + statement.RawParams = make([]interface{}, 0) + statement.UseCache = true + statement.UseAutoTime = true + statement.noAutoCondition = false + statement.IsDistinct = false + statement.IsForUpdate = false + statement.TableAlias = "" + statement.selectStr = "" + statement.allUseBool = false + statement.useAllCols = false + statement.mustColumnMap = make(map[string]bool) + statement.nullableMap = make(map[string]bool) + statement.checkVersion = true + statement.unscoped = false + statement.incrColumns = exprParams{} + statement.decrColumns = exprParams{} + statement.exprColumns = exprParams{} + statement.cond = builder.NewCond() + statement.bufferSize = 0 + statement.context = nil + statement.lastError = nil +} + +// NoAutoCondition if you do not want convert bean's field as query condition, then use this function +func (statement *Statement) NoAutoCondition(no ...bool) *Statement { + statement.noAutoCondition = true + if len(no) > 0 { + statement.noAutoCondition = no[0] + } + return statement +} + +// Alias set the table alias +func (statement *Statement) Alias(alias string) *Statement { + statement.TableAlias = alias + return statement +} + +// SQL adds raw sql statement +func (statement *Statement) SQL(query interface{}, args ...interface{}) *Statement { + switch query.(type) { + case (*builder.Builder): + var err error + statement.RawSQL, statement.RawParams, err = query.(*builder.Builder).ToSQL() + if err != nil { + statement.lastError = err + } + case string: + statement.RawSQL = query.(string) + statement.RawParams = args + default: + statement.lastError = ErrUnSupportedSQLType + } + + return statement +} + +// Where add Where statement +func (statement *Statement) Where(query interface{}, args ...interface{}) *Statement { + return statement.And(query, args...) +} + +// And add Where & and statement +func (statement *Statement) And(query interface{}, args ...interface{}) *Statement { + switch query.(type) { + case string: + cond := builder.Expr(query.(string), args...) + statement.cond = statement.cond.And(cond) + case map[string]interface{}: + queryMap := query.(map[string]interface{}) + newMap := make(map[string]interface{}) + for k, v := range queryMap { + newMap[statement.Engine.Quote(k)] = v + } + statement.cond = statement.cond.And(builder.Eq(newMap)) + case builder.Cond: + cond := query.(builder.Cond) + statement.cond = statement.cond.And(cond) + for _, v := range args { + if vv, ok := v.(builder.Cond); ok { + statement.cond = statement.cond.And(vv) + } + } + default: + statement.lastError = ErrConditionType + } + + return statement +} + +// Or add Where & Or statement +func (statement *Statement) Or(query interface{}, args ...interface{}) *Statement { + switch query.(type) { + case string: + cond := builder.Expr(query.(string), args...) + statement.cond = statement.cond.Or(cond) + case map[string]interface{}: + cond := builder.Eq(query.(map[string]interface{})) + statement.cond = statement.cond.Or(cond) + case builder.Cond: + cond := query.(builder.Cond) + statement.cond = statement.cond.Or(cond) + for _, v := range args { + if vv, ok := v.(builder.Cond); ok { + statement.cond = statement.cond.Or(vv) + } + } + default: + // TODO: not support condition type + } + return statement +} + +// In generate "Where column IN (?) " statement +func (statement *Statement) In(column string, args ...interface{}) *Statement { + in := builder.In(statement.Engine.Quote(column), args...) + statement.cond = statement.cond.And(in) + return statement +} + +// NotIn generate "Where column NOT IN (?) " statement +func (statement *Statement) NotIn(column string, args ...interface{}) *Statement { + notIn := builder.NotIn(statement.Engine.Quote(column), args...) + statement.cond = statement.cond.And(notIn) + return statement +} + +func (statement *Statement) setRefValue(v reflect.Value) error { + var err error + statement.RefTable, err = statement.Engine.autoMapType(reflect.Indirect(v)) + if err != nil { + return err + } + statement.tableName = statement.Engine.TableName(v, true) + return nil +} + +func (statement *Statement) setRefBean(bean interface{}) error { + var err error + statement.RefTable, err = statement.Engine.autoMapType(rValue(bean)) + if err != nil { + return err + } + statement.tableName = statement.Engine.TableName(bean, true) + return nil +} + +// Auto generating update columnes and values according a struct +func (statement *Statement) buildUpdates(bean interface{}, + includeVersion, includeUpdated, includeNil, + includeAutoIncr, update bool) ([]string, []interface{}) { + engine := statement.Engine + table := statement.RefTable + allUseBool := statement.allUseBool + useAllCols := statement.useAllCols + mustColumnMap := statement.mustColumnMap + nullableMap := statement.nullableMap + columnMap := statement.columnMap + omitColumnMap := statement.omitColumnMap + unscoped := statement.unscoped + + var colNames = make([]string, 0) + var args = make([]interface{}, 0) + for _, col := range table.Columns() { + if !includeVersion && col.IsVersion { + continue + } + if col.IsCreated { + continue + } + if !includeUpdated && col.IsUpdated { + continue + } + if !includeAutoIncr && col.IsAutoIncrement { + continue + } + if col.IsDeleted && !unscoped { + continue + } + if omitColumnMap.contain(col.Name) { + continue + } + if len(columnMap) > 0 && !columnMap.contain(col.Name) { + continue + } + + if col.MapType == core.ONLYFROMDB { + continue + } + + if statement.incrColumns.isColExist(col.Name) { + continue + } else if statement.decrColumns.isColExist(col.Name) { + continue + } else if statement.exprColumns.isColExist(col.Name) { + continue + } + + fieldValuePtr, err := col.ValueOf(bean) + if err != nil { + engine.logger.Error(err) + continue + } + + fieldValue := *fieldValuePtr + fieldType := reflect.TypeOf(fieldValue.Interface()) + if fieldType == nil { + continue + } + + requiredField := useAllCols + includeNil := useAllCols + + if b, ok := getFlagForColumn(mustColumnMap, col); ok { + if b { + requiredField = true + } else { + continue + } + } + + // !evalphobia! set fieldValue as nil when column is nullable and zero-value + if b, ok := getFlagForColumn(nullableMap, col); ok { + if b && col.Nullable && isZero(fieldValue.Interface()) { + var nilValue *int + fieldValue = reflect.ValueOf(nilValue) + fieldType = reflect.TypeOf(fieldValue.Interface()) + includeNil = true + } + } + + var val interface{} + + if fieldValue.CanAddr() { + if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok { + data, err := structConvert.ToDB() + if err != nil { + engine.logger.Error(err) + } else { + val = data + } + goto APPEND + } + } + + if structConvert, ok := fieldValue.Interface().(core.Conversion); ok { + data, err := structConvert.ToDB() + if err != nil { + engine.logger.Error(err) + } else { + val = data + } + goto APPEND + } + + if fieldType.Kind() == reflect.Ptr { + if fieldValue.IsNil() { + if includeNil { + args = append(args, nil) + colNames = append(colNames, fmt.Sprintf("%v=?", engine.Quote(col.Name))) + } + continue + } else if !fieldValue.IsValid() { + continue + } else { + // dereference ptr type to instance type + fieldValue = fieldValue.Elem() + fieldType = reflect.TypeOf(fieldValue.Interface()) + requiredField = true + } + } + + switch fieldType.Kind() { + case reflect.Bool: + if allUseBool || requiredField { + val = fieldValue.Interface() + } else { + // if a bool in a struct, it will not be as a condition because it default is false, + // please use Where() instead + continue + } + case reflect.String: + if !requiredField && fieldValue.String() == "" { + continue + } + // for MyString, should convert to string or panic + if fieldType.String() != reflect.String.String() { + val = fieldValue.String() + } else { + val = fieldValue.Interface() + } + case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64: + if !requiredField && fieldValue.Int() == 0 { + continue + } + val = fieldValue.Interface() + case reflect.Float32, reflect.Float64: + if !requiredField && fieldValue.Float() == 0.0 { + continue + } + val = fieldValue.Interface() + case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64: + if !requiredField && fieldValue.Uint() == 0 { + continue + } + t := int64(fieldValue.Uint()) + val = reflect.ValueOf(&t).Interface() + case reflect.Struct: + if fieldType.ConvertibleTo(core.TimeType) { + t := fieldValue.Convert(core.TimeType).Interface().(time.Time) + if !requiredField && (t.IsZero() || !fieldValue.IsValid()) { + continue + } + val = engine.formatColTime(col, t) + } else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok { + val, _ = nulType.Value() + } else { + if !col.SQLType.IsJson() { + engine.autoMapType(fieldValue) + if table, ok := engine.Tables[fieldValue.Type()]; ok { + if len(table.PrimaryKeys) == 1 { + pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName) + // fix non-int pk issues + if pkField.IsValid() && (!requiredField && !isZero(pkField.Interface())) { + val = pkField.Interface() + } else { + continue + } + } else { + // TODO: how to handler? + panic("not supported") + } + } else { + val = fieldValue.Interface() + } + } else { + // Blank struct could not be as update data + if requiredField || !isStructZero(fieldValue) { + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + panic(fmt.Sprintf("mashal %v failed", fieldValue.Interface())) + } + if col.SQLType.IsText() { + val = string(bytes) + } else if col.SQLType.IsBlob() { + val = bytes + } + } else { + continue + } + } + } + case reflect.Array, reflect.Slice, reflect.Map: + if !requiredField { + if fieldValue == reflect.Zero(fieldType) { + continue + } + if fieldType.Kind() == reflect.Array { + if isArrayValueZero(fieldValue) { + continue + } + } else if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 { + continue + } + } + + if col.SQLType.IsText() { + bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + engine.logger.Error(err) + continue + } + val = string(bytes) + } else if col.SQLType.IsBlob() { + var bytes []byte + var err error + if fieldType.Kind() == reflect.Slice && + fieldType.Elem().Kind() == reflect.Uint8 { + if fieldValue.Len() > 0 { + val = fieldValue.Bytes() + } else { + continue + } + } else if fieldType.Kind() == reflect.Array && + fieldType.Elem().Kind() == reflect.Uint8 { + val = fieldValue.Slice(0, 0).Interface() + } else { + bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface()) + if err != nil { + engine.logger.Error(err) + continue + } + val = bytes + } + } else { + continue + } + default: + val = fieldValue.Interface() + } + + APPEND: + args = append(args, val) + if col.IsPrimaryKey && engine.dialect.DBType() == "ql" { + continue + } + colNames = append(colNames, fmt.Sprintf("%v = ?", engine.Quote(col.Name))) + } + + return colNames, args +} + +func (statement *Statement) needTableName() bool { + return len(statement.JoinStr) > 0 +} + +func (statement *Statement) colName(col *core.Column, tableName string) string { + if statement.needTableName() { + var nm = tableName + if len(statement.TableAlias) > 0 { + nm = statement.TableAlias + } + return statement.Engine.Quote(nm) + "." + statement.Engine.Quote(col.Name) + } + return statement.Engine.Quote(col.Name) +} + +// TableName return current tableName +func (statement *Statement) TableName() string { + if statement.AltTableName != "" { + return statement.AltTableName + } + + return statement.tableName +} + +// ID generate "where id = ? " statement or for composite key "where key1 = ? and key2 = ?" +func (statement *Statement) ID(id interface{}) *Statement { + idValue := reflect.ValueOf(id) + idType := reflect.TypeOf(idValue.Interface()) + + switch idType { + case ptrPkType: + if pkPtr, ok := (id).(*core.PK); ok { + statement.idParam = pkPtr + return statement + } + case pkType: + if pk, ok := (id).(core.PK); ok { + statement.idParam = &pk + return statement + } + } + + switch idType.Kind() { + case reflect.String: + statement.idParam = &core.PK{idValue.Convert(reflect.TypeOf("")).Interface()} + return statement + } + + statement.idParam = &core.PK{id} + return statement +} + +// Incr Generate "Update ... Set column = column + arg" statement +func (statement *Statement) Incr(column string, arg ...interface{}) *Statement { + if len(arg) > 0 { + statement.incrColumns.addParam(column, arg[0]) + } else { + statement.incrColumns.addParam(column, 1) + } + return statement +} + +// Decr Generate "Update ... Set column = column - arg" statement +func (statement *Statement) Decr(column string, arg ...interface{}) *Statement { + if len(arg) > 0 { + statement.decrColumns.addParam(column, arg[0]) + } else { + statement.decrColumns.addParam(column, 1) + } + return statement +} + +// SetExpr Generate "Update ... Set column = {expression}" statement +func (statement *Statement) SetExpr(column string, expression interface{}) *Statement { + statement.exprColumns.addParam(column, expression) + return statement +} + +func (statement *Statement) col2NewColsWithQuote(columns ...string) []string { + newColumns := make([]string, 0) + quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`") + for _, col := range columns { + newColumns = append(newColumns, statement.Engine.Quote(eraseAny(col, quotes...))) + } + return newColumns +} + +func (statement *Statement) colmap2NewColsWithQuote() []string { + newColumns := make([]string, len(statement.columnMap), len(statement.columnMap)) + copy(newColumns, statement.columnMap) + for i := 0; i < len(statement.columnMap); i++ { + newColumns[i] = statement.Engine.Quote(newColumns[i]) + } + return newColumns +} + +// Distinct generates "DISTINCT col1, col2 " statement +func (statement *Statement) Distinct(columns ...string) *Statement { + statement.IsDistinct = true + statement.Cols(columns...) + return statement +} + +// ForUpdate generates "SELECT ... FOR UPDATE" statement +func (statement *Statement) ForUpdate() *Statement { + statement.IsForUpdate = true + return statement +} + +// Select replace select +func (statement *Statement) Select(str string) *Statement { + statement.selectStr = str + return statement +} + +// Cols generate "col1, col2" statement +func (statement *Statement) Cols(columns ...string) *Statement { + cols := col2NewCols(columns...) + for _, nc := range cols { + statement.columnMap.add(nc) + } + + newColumns := statement.colmap2NewColsWithQuote() + + statement.ColumnStr = strings.Join(newColumns, ", ") + statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.quote("*"), "*", -1) + return statement +} + +// AllCols update use only: update all columns +func (statement *Statement) AllCols() *Statement { + statement.useAllCols = true + return statement +} + +// MustCols update use only: must update columns +func (statement *Statement) MustCols(columns ...string) *Statement { + newColumns := col2NewCols(columns...) + for _, nc := range newColumns { + statement.mustColumnMap[strings.ToLower(nc)] = true + } + return statement +} + +// UseBool indicates that use bool fields as update contents and query contiditions +func (statement *Statement) UseBool(columns ...string) *Statement { + if len(columns) > 0 { + statement.MustCols(columns...) + } else { + statement.allUseBool = true + } + return statement +} + +// Omit do not use the columns +func (statement *Statement) Omit(columns ...string) { + newColumns := col2NewCols(columns...) + for _, nc := range newColumns { + statement.omitColumnMap = append(statement.omitColumnMap, nc) + } + statement.OmitStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", "))) +} + +// Nullable Update use only: update columns to null when value is nullable and zero-value +func (statement *Statement) Nullable(columns ...string) { + newColumns := col2NewCols(columns...) + for _, nc := range newColumns { + statement.nullableMap[strings.ToLower(nc)] = true + } +} + +// Top generate LIMIT limit statement +func (statement *Statement) Top(limit int) *Statement { + statement.Limit(limit) + return statement +} + +// Limit generate LIMIT start, limit statement +func (statement *Statement) Limit(limit int, start ...int) *Statement { + statement.LimitN = limit + if len(start) > 0 { + statement.Start = start[0] + } + return statement +} + +// OrderBy generate "Order By order" statement +func (statement *Statement) OrderBy(order string) *Statement { + if len(statement.OrderStr) > 0 { + statement.OrderStr += ", " + } + statement.OrderStr += order + return statement +} + +// Desc generate `ORDER BY xx DESC` +func (statement *Statement) Desc(colNames ...string) *Statement { + var buf strings.Builder + if len(statement.OrderStr) > 0 { + fmt.Fprint(&buf, statement.OrderStr, ", ") + } + newColNames := statement.col2NewColsWithQuote(colNames...) + fmt.Fprintf(&buf, "%v DESC", strings.Join(newColNames, " DESC, ")) + statement.OrderStr = buf.String() + return statement +} + +// Asc provide asc order by query condition, the input parameters are columns. +func (statement *Statement) Asc(colNames ...string) *Statement { + var buf strings.Builder + if len(statement.OrderStr) > 0 { + fmt.Fprint(&buf, statement.OrderStr, ", ") + } + newColNames := statement.col2NewColsWithQuote(colNames...) + fmt.Fprintf(&buf, "%v ASC", strings.Join(newColNames, " ASC, ")) + statement.OrderStr = buf.String() + return statement +} + +// Table tempororily set table name, the parameter could be a string or a pointer of struct +func (statement *Statement) Table(tableNameOrBean interface{}) *Statement { + v := rValue(tableNameOrBean) + t := v.Type() + if t.Kind() == reflect.Struct { + var err error + statement.RefTable, err = statement.Engine.autoMapType(v) + if err != nil { + statement.Engine.logger.Error(err) + return statement + } + } + + statement.AltTableName = statement.Engine.TableName(tableNameOrBean, true) + return statement +} + +// Join The joinOP should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN +func (statement *Statement) Join(joinOP string, tablename interface{}, condition string, args ...interface{}) *Statement { + var buf strings.Builder + if len(statement.JoinStr) > 0 { + fmt.Fprintf(&buf, "%v %v JOIN ", statement.JoinStr, joinOP) + } else { + fmt.Fprintf(&buf, "%v JOIN ", joinOP) + } + + switch tp := tablename.(type) { + case builder.Builder: + subSQL, subQueryArgs, err := tp.ToSQL() + if err != nil { + statement.lastError = err + return statement + } + tbs := strings.Split(tp.TableName(), ".") + quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`") + + var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, "")) + fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition) + statement.joinArgs = append(statement.joinArgs, subQueryArgs...) + case *builder.Builder: + subSQL, subQueryArgs, err := tp.ToSQL() + if err != nil { + statement.lastError = err + return statement + } + tbs := strings.Split(tp.TableName(), ".") + quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`") + + var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, "")) + fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition) + statement.joinArgs = append(statement.joinArgs, subQueryArgs...) + default: + tbName := statement.Engine.TableName(tablename, true) + fmt.Fprintf(&buf, "%s ON %v", tbName, condition) + } + + statement.JoinStr = buf.String() + statement.joinArgs = append(statement.joinArgs, args...) + return statement +} + +// GroupBy generate "Group By keys" statement +func (statement *Statement) GroupBy(keys string) *Statement { + statement.GroupByStr = keys + return statement +} + +// Having generate "Having conditions" statement +func (statement *Statement) Having(conditions string) *Statement { + statement.HavingStr = fmt.Sprintf("HAVING %v", conditions) + return statement +} + +// Unscoped always disable struct tag "deleted" +func (statement *Statement) Unscoped() *Statement { + statement.unscoped = true + return statement +} + +func (statement *Statement) genColumnStr() string { + if statement.RefTable == nil { + return "" + } + + var buf strings.Builder + columns := statement.RefTable.Columns() + + for _, col := range columns { + if statement.omitColumnMap.contain(col.Name) { + continue + } + + if len(statement.columnMap) > 0 && !statement.columnMap.contain(col.Name) { + continue + } + + if col.MapType == core.ONLYTODB { + continue + } + + if buf.Len() != 0 { + buf.WriteString(", ") + } + + if statement.JoinStr != "" { + if statement.TableAlias != "" { + buf.WriteString(statement.TableAlias) + } else { + buf.WriteString(statement.TableName()) + } + + buf.WriteString(".") + } + + statement.Engine.QuoteTo(&buf, col.Name) + } + + return buf.String() +} + +func (statement *Statement) genCreateTableSQL() string { + return statement.Engine.dialect.CreateTableSql(statement.RefTable, statement.TableName(), + statement.StoreEngine, statement.Charset) +} + +func (statement *Statement) genIndexSQL() []string { + var sqls []string + tbName := statement.TableName() + for _, index := range statement.RefTable.Indexes { + if index.Type == core.IndexType { + sql := statement.Engine.dialect.CreateIndexSql(tbName, index) + /*idxTBName := strings.Replace(tbName, ".", "_", -1) + idxTBName = strings.Replace(idxTBName, `"`, "", -1) + sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(idxTBName, idxName)), + quote(tbName), quote(strings.Join(index.Cols, quote(","))))*/ + sqls = append(sqls, sql) + } + } + return sqls +} + +func uniqueName(tableName, uqeName string) string { + return fmt.Sprintf("UQE_%v_%v", tableName, uqeName) +} + +func (statement *Statement) genUniqueSQL() []string { + var sqls []string + tbName := statement.TableName() + for _, index := range statement.RefTable.Indexes { + if index.Type == core.UniqueType { + sql := statement.Engine.dialect.CreateIndexSql(tbName, index) + sqls = append(sqls, sql) + } + } + return sqls +} + +func (statement *Statement) genDelIndexSQL() []string { + var sqls []string + tbName := statement.TableName() + idxPrefixName := strings.Replace(tbName, `"`, "", -1) + idxPrefixName = strings.Replace(idxPrefixName, `.`, "_", -1) + for idxName, index := range statement.RefTable.Indexes { + var rIdxName string + if index.Type == core.UniqueType { + rIdxName = uniqueName(idxPrefixName, idxName) + } else if index.Type == core.IndexType { + rIdxName = indexName(idxPrefixName, idxName) + } + sql := fmt.Sprintf("DROP INDEX %v", statement.Engine.Quote(statement.Engine.TableName(rIdxName, true))) + if statement.Engine.dialect.IndexOnTable() { + sql += fmt.Sprintf(" ON %v", statement.Engine.Quote(tbName)) + } + sqls = append(sqls, sql) + } + return sqls +} + +func (statement *Statement) genAddColumnStr(col *core.Column) (string, []interface{}) { + quote := statement.Engine.Quote + sql := fmt.Sprintf("ALTER TABLE %v ADD %v", quote(statement.TableName()), + col.String(statement.Engine.dialect)) + if statement.Engine.dialect.DBType() == core.MYSQL && len(col.Comment) > 0 { + sql += " COMMENT '" + col.Comment + "'" + } + sql += ";" + return sql, []interface{}{} +} + +func (statement *Statement) buildConds(table *core.Table, bean interface{}, includeVersion bool, includeUpdated bool, includeNil bool, includeAutoIncr bool, addedTableName bool) (builder.Cond, error) { + return statement.Engine.buildConds(table, bean, includeVersion, includeUpdated, includeNil, includeAutoIncr, statement.allUseBool, statement.useAllCols, + statement.unscoped, statement.mustColumnMap, statement.TableName(), statement.TableAlias, addedTableName) +} + +func (statement *Statement) mergeConds(bean interface{}) error { + if !statement.noAutoCondition { + var addedTableName = (len(statement.JoinStr) > 0) + autoCond, err := statement.buildConds(statement.RefTable, bean, true, true, false, true, addedTableName) + if err != nil { + return err + } + statement.cond = statement.cond.And(autoCond) + } + + if err := statement.processIDParam(); err != nil { + return err + } + return nil +} + +func (statement *Statement) genConds(bean interface{}) (string, []interface{}, error) { + if err := statement.mergeConds(bean); err != nil { + return "", nil, err + } + + return builder.ToSQL(statement.cond) +} + +func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{}, error) { + v := rValue(bean) + isStruct := v.Kind() == reflect.Struct + if isStruct { + statement.setRefBean(bean) + } + + var columnStr = statement.ColumnStr + if len(statement.selectStr) > 0 { + columnStr = statement.selectStr + } else { + // TODO: always generate column names, not use * even if join + if len(statement.JoinStr) == 0 { + if len(columnStr) == 0 { + if len(statement.GroupByStr) > 0 { + columnStr = statement.Engine.quoteColumns(statement.GroupByStr) + } else { + columnStr = statement.genColumnStr() + } + } + } else { + if len(columnStr) == 0 { + if len(statement.GroupByStr) > 0 { + columnStr = statement.Engine.quoteColumns(statement.GroupByStr) + } + } + } + } + + if len(columnStr) == 0 { + columnStr = "*" + } + + if isStruct { + if err := statement.mergeConds(bean); err != nil { + return "", nil, err + } + } else { + if err := statement.processIDParam(); err != nil { + return "", nil, err + } + } + condSQL, condArgs, err := builder.ToSQL(statement.cond) + if err != nil { + return "", nil, err + } + + sqlStr, err := statement.genSelectSQL(columnStr, condSQL, true, true) + if err != nil { + return "", nil, err + } + + return sqlStr, append(statement.joinArgs, condArgs...), nil +} + +func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interface{}, error) { + var condSQL string + var condArgs []interface{} + var err error + if len(beans) > 0 { + statement.setRefBean(beans[0]) + condSQL, condArgs, err = statement.genConds(beans[0]) + } else { + condSQL, condArgs, err = builder.ToSQL(statement.cond) + } + if err != nil { + return "", nil, err + } + + var selectSQL = statement.selectStr + if len(selectSQL) <= 0 { + if statement.IsDistinct { + selectSQL = fmt.Sprintf("count(DISTINCT %s)", statement.ColumnStr) + } else { + selectSQL = "count(*)" + } + } + sqlStr, err := statement.genSelectSQL(selectSQL, condSQL, false, false) + if err != nil { + return "", nil, err + } + + return sqlStr, append(statement.joinArgs, condArgs...), nil +} + +func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (string, []interface{}, error) { + statement.setRefBean(bean) + + var sumStrs = make([]string, 0, len(columns)) + for _, colName := range columns { + if !strings.Contains(colName, " ") && !strings.Contains(colName, "(") { + colName = statement.Engine.Quote(colName) + } + sumStrs = append(sumStrs, fmt.Sprintf("COALESCE(sum(%s),0)", colName)) + } + sumSelect := strings.Join(sumStrs, ", ") + + condSQL, condArgs, err := statement.genConds(bean) + if err != nil { + return "", nil, err + } + + sqlStr, err := statement.genSelectSQL(sumSelect, condSQL, true, true) + if err != nil { + return "", nil, err + } + + return sqlStr, append(statement.joinArgs, condArgs...), nil +} + +func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit, needOrderBy bool) (string, error) { + var ( + distinct string + dialect = statement.Engine.Dialect() + quote = statement.Engine.Quote + fromStr = " FROM " + top, mssqlCondi, whereStr string + ) + if statement.IsDistinct && !strings.HasPrefix(columnStr, "count") { + distinct = "DISTINCT " + } + if len(condSQL) > 0 { + whereStr = " WHERE " + condSQL + } + + if dialect.DBType() == core.MSSQL && strings.Contains(statement.TableName(), "..") { + fromStr += statement.TableName() + } else { + fromStr += quote(statement.TableName()) + } + + if statement.TableAlias != "" { + if dialect.DBType() == core.ORACLE { + fromStr += " " + quote(statement.TableAlias) + } else { + fromStr += " AS " + quote(statement.TableAlias) + } + } + if statement.JoinStr != "" { + fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr) + } + + if dialect.DBType() == core.MSSQL { + if statement.LimitN > 0 { + top = fmt.Sprintf("TOP %d ", statement.LimitN) + } + if statement.Start > 0 { + var column string + if len(statement.RefTable.PKColumns()) == 0 { + for _, index := range statement.RefTable.Indexes { + if len(index.Cols) == 1 { + column = index.Cols[0] + break + } + } + if len(column) == 0 { + column = statement.RefTable.ColumnsSeq()[0] + } + } else { + column = statement.RefTable.PKColumns()[0].Name + } + if statement.needTableName() { + if len(statement.TableAlias) > 0 { + column = statement.TableAlias + "." + column + } else { + column = statement.TableName() + "." + column + } + } + + var orderStr string + if needOrderBy && len(statement.OrderStr) > 0 { + orderStr = " ORDER BY " + statement.OrderStr + } + + var groupStr string + if len(statement.GroupByStr) > 0 { + groupStr = " GROUP BY " + statement.GroupByStr + } + mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s%s%s))", + column, statement.Start, column, fromStr, whereStr, orderStr, groupStr) + } + } + + var buf strings.Builder + fmt.Fprintf(&buf, "SELECT %v%v%v%v%v", distinct, top, columnStr, fromStr, whereStr) + if len(mssqlCondi) > 0 { + if len(whereStr) > 0 { + fmt.Fprint(&buf, " AND ", mssqlCondi) + } else { + fmt.Fprint(&buf, " WHERE ", mssqlCondi) + } + } + + if statement.GroupByStr != "" { + fmt.Fprint(&buf, " GROUP BY ", statement.GroupByStr) + } + if statement.HavingStr != "" { + fmt.Fprint(&buf, " ", statement.HavingStr) + } + if needOrderBy && statement.OrderStr != "" { + fmt.Fprint(&buf, " ORDER BY ", statement.OrderStr) + } + if needLimit { + if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE { + if statement.Start > 0 { + fmt.Fprintf(&buf, " LIMIT %v OFFSET %v", statement.LimitN, statement.Start) + } else if statement.LimitN > 0 { + fmt.Fprint(&buf, " LIMIT ", statement.LimitN) + } + } else if dialect.DBType() == core.ORACLE { + if statement.Start != 0 || statement.LimitN != 0 { + oldString := buf.String() + buf.Reset() + rawColStr := columnStr + if rawColStr == "*" { + rawColStr = "at.*" + } + fmt.Fprintf(&buf, "SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", + columnStr, rawColStr, oldString, statement.Start+statement.LimitN, statement.Start) + } + } + } + if statement.IsForUpdate { + return dialect.ForUpdateSql(buf.String()), nil + } + + return buf.String(), nil +} + +func (statement *Statement) processIDParam() error { + if statement.idParam == nil || statement.RefTable == nil { + return nil + } + + if len(statement.RefTable.PrimaryKeys) != len(*statement.idParam) { + return fmt.Errorf("ID condition is error, expect %d primarykeys, there are %d", + len(statement.RefTable.PrimaryKeys), + len(*statement.idParam), + ) + } + + for i, col := range statement.RefTable.PKColumns() { + var colName = statement.colName(col, statement.TableName()) + statement.cond = statement.cond.And(builder.Eq{colName: (*(statement.idParam))[i]}) + } + return nil +} + +func (statement *Statement) joinColumns(cols []*core.Column, includeTableName bool) string { + var colnames = make([]string, len(cols)) + for i, col := range cols { + if includeTableName { + colnames[i] = statement.Engine.Quote(statement.TableName()) + + "." + statement.Engine.Quote(col.Name) + } else { + colnames[i] = statement.Engine.Quote(col.Name) + } + } + return strings.Join(colnames, ", ") +} + +func (statement *Statement) convertIDSQL(sqlStr string) string { + if statement.RefTable != nil { + cols := statement.RefTable.PKColumns() + if len(cols) == 0 { + return "" + } + + colstrs := statement.joinColumns(cols, false) + sqls := splitNNoCase(sqlStr, " from ", 2) + if len(sqls) != 2 { + return "" + } + + var top string + if statement.LimitN > 0 && statement.Engine.dialect.DBType() == core.MSSQL { + top = fmt.Sprintf("TOP %d ", statement.LimitN) + } + + newsql := fmt.Sprintf("SELECT %s%s FROM %v", top, colstrs, sqls[1]) + return newsql + } + return "" +} + +func (statement *Statement) convertUpdateSQL(sqlStr string) (string, string) { + if statement.RefTable == nil || len(statement.RefTable.PrimaryKeys) != 1 { + return "", "" + } + + colstrs := statement.joinColumns(statement.RefTable.PKColumns(), true) + sqls := splitNNoCase(sqlStr, "where", 2) + if len(sqls) != 2 { + if len(sqls) == 1 { + return sqls[0], fmt.Sprintf("SELECT %v FROM %v", + colstrs, statement.Engine.Quote(statement.TableName())) + } + return "", "" + } + + var whereStr = sqls[1] + + // TODO: for postgres only, if any other database? + var paraStr string + if statement.Engine.dialect.DBType() == core.POSTGRES { + paraStr = "$" + } else if statement.Engine.dialect.DBType() == core.MSSQL { + paraStr = ":" + } + + if paraStr != "" { + if strings.Contains(sqls[1], paraStr) { + dollers := strings.Split(sqls[1], paraStr) + whereStr = dollers[0] + for i, c := range dollers[1:] { + ccs := strings.SplitN(c, " ", 2) + whereStr += fmt.Sprintf(paraStr+"%v %v", i+1, ccs[1]) + } + } + } + + return sqls[0], fmt.Sprintf("SELECT %v FROM %v WHERE %v", + colstrs, statement.Engine.Quote(statement.TableName()), + whereStr) +} diff --git a/vendor/xorm.io/xorm/statement_args.go b/vendor/xorm.io/xorm/statement_args.go new file mode 100644 index 0000000000..310f24d6b9 --- /dev/null +++ b/vendor/xorm.io/xorm/statement_args.go @@ -0,0 +1,170 @@ +// Copyright 2019 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "fmt" + "reflect" + "strings" + "time" + + "xorm.io/builder" + "xorm.io/core" +) + +func quoteNeeded(a interface{}) bool { + switch a.(type) { + case int, int8, int16, int32, int64: + return false + case uint, uint8, uint16, uint32, uint64: + return false + case float32, float64: + return false + case bool: + return false + case string: + return true + case time.Time, *time.Time: + return true + case builder.Builder, *builder.Builder: + return false + } + + t := reflect.TypeOf(a) + switch t.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return false + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return false + case reflect.Float32, reflect.Float64: + return false + case reflect.Bool: + return false + case reflect.String: + return true + } + + return true +} + +func convertStringSingleQuote(arg string) string { + return "'" + strings.Replace(arg, "'", "''", -1) + "'" +} + +func convertString(arg string) string { + var buf strings.Builder + buf.WriteRune('\'') + for _, c := range arg { + if c == '\\' || c == '\'' { + buf.WriteRune('\\') + } + buf.WriteRune(c) + } + buf.WriteRune('\'') + return buf.String() +} + +func convertArg(arg interface{}, convertFunc func(string) string) string { + if quoteNeeded(arg) { + argv := fmt.Sprintf("%v", arg) + return convertFunc(argv) + } + + return fmt.Sprintf("%v", arg) +} + +const insertSelectPlaceHolder = true + +func (statement *Statement) writeArg(w *builder.BytesWriter, arg interface{}) error { + switch argv := arg.(type) { + case bool: + if statement.Engine.dialect.DBType() == core.MSSQL { + if argv { + if _, err := w.WriteString("1"); err != nil { + return err + } + } else { + if _, err := w.WriteString("0"); err != nil { + return err + } + } + } else { + if argv { + if _, err := w.WriteString("true"); err != nil { + return err + } + } else { + if _, err := w.WriteString("false"); err != nil { + return err + } + } + } + case *builder.Builder: + if _, err := w.WriteString("("); err != nil { + return err + } + if err := argv.WriteTo(w); err != nil { + return err + } + if _, err := w.WriteString(")"); err != nil { + return err + } + default: + if insertSelectPlaceHolder { + if err := w.WriteByte('?'); err != nil { + return err + } + w.Append(arg) + } else { + var convertFunc = convertStringSingleQuote + if statement.Engine.dialect.DBType() == core.MYSQL { + convertFunc = convertString + } + if _, err := w.WriteString(convertArg(arg, convertFunc)); err != nil { + return err + } + } + } + return nil +} + +func (statement *Statement) writeArgs(w *builder.BytesWriter, args []interface{}) error { + for i, arg := range args { + if err := statement.writeArg(w, arg); err != nil { + return err + } + + if i+1 != len(args) { + if _, err := w.WriteString(","); err != nil { + return err + } + } + } + return nil +} + +func writeStrings(w *builder.BytesWriter, cols []string, leftQuote, rightQuote string) error { + for i, colName := range cols { + if len(leftQuote) > 0 && colName[0] != '`' { + if _, err := w.WriteString(leftQuote); err != nil { + return err + } + } + if _, err := w.WriteString(colName); err != nil { + return err + } + if len(rightQuote) > 0 && colName[len(colName)-1] != '`' { + if _, err := w.WriteString(rightQuote); err != nil { + return err + } + } + if i+1 != len(cols) { + if _, err := w.WriteString(","); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/xorm.io/xorm/statement_columnmap.go b/vendor/xorm.io/xorm/statement_columnmap.go new file mode 100644 index 0000000000..b6523b1e7a --- /dev/null +++ b/vendor/xorm.io/xorm/statement_columnmap.go @@ -0,0 +1,35 @@ +// Copyright 2019 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import "strings" + +type columnMap []string + +func (m columnMap) contain(colName string) bool { + if len(m) == 0 { + return false + } + + n := len(colName) + for _, mk := range m { + if len(mk) != n { + continue + } + if strings.EqualFold(mk, colName) { + return true + } + } + + return false +} + +func (m *columnMap) add(colName string) bool { + if m.contain(colName) { + return false + } + *m = append(*m, colName) + return true +} diff --git a/vendor/xorm.io/xorm/statement_exprparam.go b/vendor/xorm.io/xorm/statement_exprparam.go new file mode 100644 index 0000000000..4da4f1ea12 --- /dev/null +++ b/vendor/xorm.io/xorm/statement_exprparam.go @@ -0,0 +1,117 @@ +// Copyright 2019 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "fmt" + "strings" + + "xorm.io/builder" +) + +type ErrUnsupportedExprType struct { + tp string +} + +func (err ErrUnsupportedExprType) Error() string { + return fmt.Sprintf("Unsupported expression type: %v", err.tp) +} + +type exprParam struct { + colName string + arg interface{} +} + +type exprParams struct { + colNames []string + args []interface{} +} + +func (exprs *exprParams) Len() int { + return len(exprs.colNames) +} + +func (exprs *exprParams) addParam(colName string, arg interface{}) { + exprs.colNames = append(exprs.colNames, colName) + exprs.args = append(exprs.args, arg) +} + +func (exprs *exprParams) isColExist(colName string) bool { + for _, name := range exprs.colNames { + if strings.EqualFold(trimQuote(name), trimQuote(colName)) { + return true + } + } + return false +} + +func (exprs *exprParams) getByName(colName string) (exprParam, bool) { + for i, name := range exprs.colNames { + if strings.EqualFold(name, colName) { + return exprParam{name, exprs.args[i]}, true + } + } + return exprParam{}, false +} + +func (exprs *exprParams) writeArgs(w *builder.BytesWriter) error { + for i, expr := range exprs.args { + switch arg := expr.(type) { + case *builder.Builder: + if _, err := w.WriteString("("); err != nil { + return err + } + if err := arg.WriteTo(w); err != nil { + return err + } + if _, err := w.WriteString(")"); err != nil { + return err + } + default: + if _, err := w.WriteString(fmt.Sprintf("%v", arg)); err != nil { + return err + } + } + if i != len(exprs.args)-1 { + if _, err := w.WriteString(","); err != nil { + return err + } + } + } + return nil +} + +func (exprs *exprParams) writeNameArgs(w *builder.BytesWriter) error { + for i, colName := range exprs.colNames { + if _, err := w.WriteString(colName); err != nil { + return err + } + if _, err := w.WriteString("="); err != nil { + return err + } + + switch arg := exprs.args[i].(type) { + case *builder.Builder: + if _, err := w.WriteString("("); err != nil { + return err + } + if err := arg.WriteTo(w); err != nil { + return err + } + if _, err := w.WriteString("("); err != nil { + return err + } + default: + w.Append(exprs.args[i]) + } + + if i+1 != len(exprs.colNames) { + if _, err := w.WriteString(","); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/xorm.io/xorm/statement_quote.go b/vendor/xorm.io/xorm/statement_quote.go new file mode 100644 index 0000000000..e22e0d1471 --- /dev/null +++ b/vendor/xorm.io/xorm/statement_quote.go @@ -0,0 +1,19 @@ +// Copyright 2019 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +func trimQuote(s string) string { + if len(s) == 0 { + return s + } + + if s[0] == '`' { + s = s[1:] + } + if len(s) > 0 && s[len(s)-1] == '`' { + return s[:len(s)-1] + } + return s +} diff --git a/vendor/xorm.io/xorm/syslogger.go b/vendor/xorm.io/xorm/syslogger.go new file mode 100644 index 0000000000..11ba01e7bd --- /dev/null +++ b/vendor/xorm.io/xorm/syslogger.go @@ -0,0 +1,89 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !windows,!nacl,!plan9 + +package xorm + +import ( + "fmt" + "log/syslog" + + "xorm.io/core" +) + +var _ core.ILogger = &SyslogLogger{} + +// SyslogLogger will be depricated +type SyslogLogger struct { + w *syslog.Writer + showSQL bool +} + +// NewSyslogLogger implements core.ILogger +func NewSyslogLogger(w *syslog.Writer) *SyslogLogger { + return &SyslogLogger{w: w} +} + +// Debug log content as Debug +func (s *SyslogLogger) Debug(v ...interface{}) { + s.w.Debug(fmt.Sprint(v...)) +} + +// Debugf log content as Debug and format +func (s *SyslogLogger) Debugf(format string, v ...interface{}) { + s.w.Debug(fmt.Sprintf(format, v...)) +} + +// Error log content as Error +func (s *SyslogLogger) Error(v ...interface{}) { + s.w.Err(fmt.Sprint(v...)) +} + +// Errorf log content as Errorf and format +func (s *SyslogLogger) Errorf(format string, v ...interface{}) { + s.w.Err(fmt.Sprintf(format, v...)) +} + +// Info log content as Info +func (s *SyslogLogger) Info(v ...interface{}) { + s.w.Info(fmt.Sprint(v...)) +} + +// Infof log content as Infof and format +func (s *SyslogLogger) Infof(format string, v ...interface{}) { + s.w.Info(fmt.Sprintf(format, v...)) +} + +// Warn log content as Warn +func (s *SyslogLogger) Warn(v ...interface{}) { + s.w.Warning(fmt.Sprint(v...)) +} + +// Warnf log content as Warnf and format +func (s *SyslogLogger) Warnf(format string, v ...interface{}) { + s.w.Warning(fmt.Sprintf(format, v...)) +} + +// Level shows log level +func (s *SyslogLogger) Level() core.LogLevel { + return core.LOG_UNKNOWN +} + +// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created +func (s *SyslogLogger) SetLevel(l core.LogLevel) {} + +// ShowSQL set if logging SQL +func (s *SyslogLogger) ShowSQL(show ...bool) { + if len(show) == 0 { + s.showSQL = true + return + } + s.showSQL = show[0] +} + +// IsShowSQL if logging SQL +func (s *SyslogLogger) IsShowSQL() bool { + return s.showSQL +} diff --git a/vendor/xorm.io/xorm/tag.go b/vendor/xorm.io/xorm/tag.go new file mode 100644 index 0000000000..ec8d5cf05b --- /dev/null +++ b/vendor/xorm.io/xorm/tag.go @@ -0,0 +1,311 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "xorm.io/core" +) + +type tagContext struct { + tagName string + params []string + preTag, nextTag string + table *core.Table + col *core.Column + fieldValue reflect.Value + isIndex bool + isUnique bool + indexNames map[string]int + engine *Engine + hasCacheTag bool + hasNoCacheTag bool + ignoreNext bool +} + +// tagHandler describes tag handler for XORM +type tagHandler func(ctx *tagContext) error + +var ( + // defaultTagHandlers enumerates all the default tag handler + defaultTagHandlers = map[string]tagHandler{ + "<-": OnlyFromDBTagHandler, + "->": OnlyToDBTagHandler, + "PK": PKTagHandler, + "NULL": NULLTagHandler, + "NOT": IgnoreTagHandler, + "AUTOINCR": AutoIncrTagHandler, + "DEFAULT": DefaultTagHandler, + "CREATED": CreatedTagHandler, + "UPDATED": UpdatedTagHandler, + "DELETED": DeletedTagHandler, + "VERSION": VersionTagHandler, + "UTC": UTCTagHandler, + "LOCAL": LocalTagHandler, + "NOTNULL": NotNullTagHandler, + "INDEX": IndexTagHandler, + "UNIQUE": UniqueTagHandler, + "CACHE": CacheTagHandler, + "NOCACHE": NoCacheTagHandler, + "COMMENT": CommentTagHandler, + } +) + +func init() { + for k := range core.SqlTypes { + defaultTagHandlers[k] = SQLTypeTagHandler + } +} + +// IgnoreTagHandler describes ignored tag handler +func IgnoreTagHandler(ctx *tagContext) error { + return nil +} + +// OnlyFromDBTagHandler describes mapping direction tag handler +func OnlyFromDBTagHandler(ctx *tagContext) error { + ctx.col.MapType = core.ONLYFROMDB + return nil +} + +// OnlyToDBTagHandler describes mapping direction tag handler +func OnlyToDBTagHandler(ctx *tagContext) error { + ctx.col.MapType = core.ONLYTODB + return nil +} + +// PKTagHandler decribes primary key tag handler +func PKTagHandler(ctx *tagContext) error { + ctx.col.IsPrimaryKey = true + ctx.col.Nullable = false + return nil +} + +// NULLTagHandler describes null tag handler +func NULLTagHandler(ctx *tagContext) error { + ctx.col.Nullable = (strings.ToUpper(ctx.preTag) != "NOT") + return nil +} + +// NotNullTagHandler describes notnull tag handler +func NotNullTagHandler(ctx *tagContext) error { + ctx.col.Nullable = false + return nil +} + +// AutoIncrTagHandler describes autoincr tag handler +func AutoIncrTagHandler(ctx *tagContext) error { + ctx.col.IsAutoIncrement = true + /* + if len(ctx.params) > 0 { + autoStartInt, err := strconv.Atoi(ctx.params[0]) + if err != nil { + return err + } + ctx.col.AutoIncrStart = autoStartInt + } else { + ctx.col.AutoIncrStart = 1 + } + */ + return nil +} + +// DefaultTagHandler describes default tag handler +func DefaultTagHandler(ctx *tagContext) error { + if len(ctx.params) > 0 { + ctx.col.Default = ctx.params[0] + } else { + ctx.col.Default = ctx.nextTag + ctx.ignoreNext = true + } + ctx.col.DefaultIsEmpty = false + return nil +} + +// CreatedTagHandler describes created tag handler +func CreatedTagHandler(ctx *tagContext) error { + ctx.col.IsCreated = true + return nil +} + +// VersionTagHandler describes version tag handler +func VersionTagHandler(ctx *tagContext) error { + ctx.col.IsVersion = true + ctx.col.Default = "1" + return nil +} + +// UTCTagHandler describes utc tag handler +func UTCTagHandler(ctx *tagContext) error { + ctx.col.TimeZone = time.UTC + return nil +} + +// LocalTagHandler describes local tag handler +func LocalTagHandler(ctx *tagContext) error { + if len(ctx.params) == 0 { + ctx.col.TimeZone = time.Local + } else { + var err error + ctx.col.TimeZone, err = time.LoadLocation(ctx.params[0]) + if err != nil { + return err + } + } + return nil +} + +// UpdatedTagHandler describes updated tag handler +func UpdatedTagHandler(ctx *tagContext) error { + ctx.col.IsUpdated = true + return nil +} + +// DeletedTagHandler describes deleted tag handler +func DeletedTagHandler(ctx *tagContext) error { + ctx.col.IsDeleted = true + return nil +} + +// IndexTagHandler describes index tag handler +func IndexTagHandler(ctx *tagContext) error { + if len(ctx.params) > 0 { + ctx.indexNames[ctx.params[0]] = core.IndexType + } else { + ctx.isIndex = true + } + return nil +} + +// UniqueTagHandler describes unique tag handler +func UniqueTagHandler(ctx *tagContext) error { + if len(ctx.params) > 0 { + ctx.indexNames[ctx.params[0]] = core.UniqueType + } else { + ctx.isUnique = true + } + return nil +} + +// CommentTagHandler add comment to column +func CommentTagHandler(ctx *tagContext) error { + if len(ctx.params) > 0 { + ctx.col.Comment = strings.Trim(ctx.params[0], "' ") + } + return nil +} + +// SQLTypeTagHandler describes SQL Type tag handler +func SQLTypeTagHandler(ctx *tagContext) error { + ctx.col.SQLType = core.SQLType{Name: ctx.tagName} + if len(ctx.params) > 0 { + if ctx.tagName == core.Enum { + ctx.col.EnumOptions = make(map[string]int) + for k, v := range ctx.params { + v = strings.TrimSpace(v) + v = strings.Trim(v, "'") + ctx.col.EnumOptions[v] = k + } + } else if ctx.tagName == core.Set { + ctx.col.SetOptions = make(map[string]int) + for k, v := range ctx.params { + v = strings.TrimSpace(v) + v = strings.Trim(v, "'") + ctx.col.SetOptions[v] = k + } + } else { + var err error + if len(ctx.params) == 2 { + ctx.col.Length, err = strconv.Atoi(ctx.params[0]) + if err != nil { + return err + } + ctx.col.Length2, err = strconv.Atoi(ctx.params[1]) + if err != nil { + return err + } + } else if len(ctx.params) == 1 { + ctx.col.Length, err = strconv.Atoi(ctx.params[0]) + if err != nil { + return err + } + } + } + } + return nil +} + +// ExtendsTagHandler describes extends tag handler +func ExtendsTagHandler(ctx *tagContext) error { + var fieldValue = ctx.fieldValue + var isPtr = false + switch fieldValue.Kind() { + case reflect.Ptr: + f := fieldValue.Type().Elem() + if f.Kind() == reflect.Struct { + fieldPtr := fieldValue + fieldValue = fieldValue.Elem() + if !fieldValue.IsValid() || fieldPtr.IsNil() { + fieldValue = reflect.New(f).Elem() + } + } + isPtr = true + fallthrough + case reflect.Struct: + parentTable, err := ctx.engine.mapType(fieldValue) + if err != nil { + return err + } + for _, col := range parentTable.Columns() { + col.FieldName = fmt.Sprintf("%v.%v", ctx.col.FieldName, col.FieldName) + + var tagPrefix = ctx.col.FieldName + if len(ctx.params) > 0 { + col.Nullable = isPtr + tagPrefix = ctx.params[0] + if col.IsPrimaryKey { + col.Name = ctx.col.FieldName + col.IsPrimaryKey = false + } else { + col.Name = fmt.Sprintf("%v%v", tagPrefix, col.Name) + } + } + + if col.Nullable { + col.IsAutoIncrement = false + col.IsPrimaryKey = false + } + + ctx.table.AddColumn(col) + for indexName, indexType := range col.Indexes { + addIndex(indexName, ctx.table, col, indexType) + } + } + default: + //TODO: warning + } + return nil +} + +// CacheTagHandler describes cache tag handler +func CacheTagHandler(ctx *tagContext) error { + if !ctx.hasCacheTag { + ctx.hasCacheTag = true + } + return nil +} + +// NoCacheTagHandler describes nocache tag handler +func NoCacheTagHandler(ctx *tagContext) error { + if !ctx.hasNoCacheTag { + ctx.hasNoCacheTag = true + } + return nil +} diff --git a/vendor/xorm.io/xorm/test_mssql.sh b/vendor/xorm.io/xorm/test_mssql.sh new file mode 100644 index 0000000000..7f060cff32 --- /dev/null +++ b/vendor/xorm.io/xorm/test_mssql.sh @@ -0,0 +1 @@ +go test -db=mssql -conn_str="server=localhost;user id=sa;password=yourStrong(!)Password;database=xorm_test" \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_mssql_cache.sh b/vendor/xorm.io/xorm/test_mssql_cache.sh new file mode 100644 index 0000000000..76efd6ca0a --- /dev/null +++ b/vendor/xorm.io/xorm/test_mssql_cache.sh @@ -0,0 +1 @@ +go test -db=mssql -conn_str="server=192.168.1.58;user id=sa;password=123456;database=xorm_test" -cache=true \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_mymysql.sh b/vendor/xorm.io/xorm/test_mymysql.sh new file mode 100644 index 0000000000..f7780d14fa --- /dev/null +++ b/vendor/xorm.io/xorm/test_mymysql.sh @@ -0,0 +1 @@ +go test -db=mymysql -conn_str="xorm_test/root/" \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_mymysql_cache.sh b/vendor/xorm.io/xorm/test_mymysql_cache.sh new file mode 100644 index 0000000000..0100286d65 --- /dev/null +++ b/vendor/xorm.io/xorm/test_mymysql_cache.sh @@ -0,0 +1 @@ +go test -db=mymysql -conn_str="xorm_test/root/" -cache=true \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_mysql.sh b/vendor/xorm.io/xorm/test_mysql.sh new file mode 100644 index 0000000000..650e4ee170 --- /dev/null +++ b/vendor/xorm.io/xorm/test_mysql.sh @@ -0,0 +1 @@ +go test -db=mysql -conn_str="root:@/xorm_test" \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_mysql_cache.sh b/vendor/xorm.io/xorm/test_mysql_cache.sh new file mode 100644 index 0000000000..c542e73594 --- /dev/null +++ b/vendor/xorm.io/xorm/test_mysql_cache.sh @@ -0,0 +1 @@ +go test -db=mysql -conn_str="root:@/xorm_test" -cache=true \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_postgres.sh b/vendor/xorm.io/xorm/test_postgres.sh new file mode 100644 index 0000000000..dc1152e0a6 --- /dev/null +++ b/vendor/xorm.io/xorm/test_postgres.sh @@ -0,0 +1 @@ +go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable" \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_postgres_cache.sh b/vendor/xorm.io/xorm/test_postgres_cache.sh new file mode 100644 index 0000000000..462fc948cb --- /dev/null +++ b/vendor/xorm.io/xorm/test_postgres_cache.sh @@ -0,0 +1 @@ +go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable" -cache=true \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_sqlite.sh b/vendor/xorm.io/xorm/test_sqlite.sh new file mode 100644 index 0000000000..6352b5cb5f --- /dev/null +++ b/vendor/xorm.io/xorm/test_sqlite.sh @@ -0,0 +1 @@ +go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_sqlite_cache.sh b/vendor/xorm.io/xorm/test_sqlite_cache.sh new file mode 100644 index 0000000000..75a054c3f1 --- /dev/null +++ b/vendor/xorm.io/xorm/test_sqlite_cache.sh @@ -0,0 +1 @@ +go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" -cache=true \ No newline at end of file diff --git a/vendor/xorm.io/xorm/test_tidb.sh b/vendor/xorm.io/xorm/test_tidb.sh new file mode 100644 index 0000000000..03d2d6cd82 --- /dev/null +++ b/vendor/xorm.io/xorm/test_tidb.sh @@ -0,0 +1 @@ +go test -db=mysql -conn_str="root:@tcp(localhost:4000)/xorm_test" -ignore_select_update=true \ No newline at end of file diff --git a/vendor/xorm.io/xorm/transaction.go b/vendor/xorm.io/xorm/transaction.go new file mode 100644 index 0000000000..4104103fd5 --- /dev/null +++ b/vendor/xorm.io/xorm/transaction.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +// Transaction Execute sql wrapped in a transaction(abbr as tx), tx will automatic commit if no errors occurred +func (engine *Engine) Transaction(f func(*Session) (interface{}, error)) (interface{}, error) { + session := engine.NewSession() + defer session.Close() + + if err := session.Begin(); err != nil { + return nil, err + } + + result, err := f(session) + if err != nil { + return nil, err + } + + if err := session.Commit(); err != nil { + return nil, err + } + + return result, nil +} diff --git a/vendor/xorm.io/xorm/types.go b/vendor/xorm.io/xorm/types.go new file mode 100644 index 0000000000..c76a546065 --- /dev/null +++ b/vendor/xorm.io/xorm/types.go @@ -0,0 +1,16 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "reflect" + + "xorm.io/core" +) + +var ( + ptrPkType = reflect.TypeOf(&core.PK{}) + pkType = reflect.TypeOf(core.PK{}) +) diff --git a/vendor/xorm.io/xorm/xorm.go b/vendor/xorm.io/xorm/xorm.go new file mode 100644 index 0000000000..e1c83b56f2 --- /dev/null +++ b/vendor/xorm.io/xorm/xorm.go @@ -0,0 +1,126 @@ +// Copyright 2015 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.8 + +package xorm + +import ( + "context" + "fmt" + "os" + "reflect" + "runtime" + "sync" + "time" + + "xorm.io/core" +) + +const ( + // Version show the xorm's version + Version string = "0.8.0.1015" +) + +func regDrvsNDialects() bool { + providedDrvsNDialects := map[string]struct { + dbType core.DbType + getDriver func() core.Driver + getDialect func() core.Dialect + }{ + "mssql": {"mssql", func() core.Driver { return &odbcDriver{} }, func() core.Dialect { return &mssql{} }}, + "odbc": {"mssql", func() core.Driver { return &odbcDriver{} }, func() core.Dialect { return &mssql{} }}, // !nashtsai! TODO change this when supporting MS Access + "mysql": {"mysql", func() core.Driver { return &mysqlDriver{} }, func() core.Dialect { return &mysql{} }}, + "mymysql": {"mysql", func() core.Driver { return &mymysqlDriver{} }, func() core.Dialect { return &mysql{} }}, + "postgres": {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }}, + "pgx": {"postgres", func() core.Driver { return &pqDriverPgx{} }, func() core.Dialect { return &postgres{} }}, + "sqlite3": {"sqlite3", func() core.Driver { return &sqlite3Driver{} }, func() core.Dialect { return &sqlite3{} }}, + "oci8": {"oracle", func() core.Driver { return &oci8Driver{} }, func() core.Dialect { return &oracle{} }}, + "goracle": {"oracle", func() core.Driver { return &goracleDriver{} }, func() core.Dialect { return &oracle{} }}, + } + + for driverName, v := range providedDrvsNDialects { + if driver := core.QueryDriver(driverName); driver == nil { + core.RegisterDriver(driverName, v.getDriver()) + core.RegisterDialect(v.dbType, v.getDialect) + } + } + return true +} + +func close(engine *Engine) { + engine.Close() +} + +func init() { + regDrvsNDialects() +} + +// NewEngine new a db manager according to the parameter. Currently support four +// drivers +func NewEngine(driverName string, dataSourceName string) (*Engine, error) { + driver := core.QueryDriver(driverName) + if driver == nil { + return nil, fmt.Errorf("Unsupported driver name: %v", driverName) + } + + uri, err := driver.Parse(driverName, dataSourceName) + if err != nil { + return nil, err + } + + dialect := core.QueryDialect(uri.DbType) + if dialect == nil { + return nil, fmt.Errorf("Unsupported dialect type: %v", uri.DbType) + } + + db, err := core.Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + + err = dialect.Init(db, uri, driverName, dataSourceName) + if err != nil { + return nil, err + } + + engine := &Engine{ + db: db, + dialect: dialect, + Tables: make(map[reflect.Type]*core.Table), + mutex: &sync.RWMutex{}, + TagIdentifier: "xorm", + TZLocation: time.Local, + tagHandlers: defaultTagHandlers, + cachers: make(map[string]core.Cacher), + defaultContext: context.Background(), + } + + if uri.DbType == core.SQLITE { + engine.DatabaseTZ = time.UTC + } else { + engine.DatabaseTZ = time.Local + } + + logger := NewSimpleLogger(os.Stdout) + logger.SetLevel(core.LOG_INFO) + engine.SetLogger(logger) + engine.SetMapper(core.NewCacheMapper(new(core.SnakeMapper))) + + runtime.SetFinalizer(engine, close) + + return engine, nil +} + +// NewEngineWithParams new a db manager with params. The params will be passed to dialect. +func NewEngineWithParams(driverName string, dataSourceName string, params map[string]string) (*Engine, error) { + engine, err := NewEngine(driverName, dataSourceName) + engine.dialect.SetParams(params) + return engine, err +} + +// Clone clone an engine +func (engine *Engine) Clone() (*Engine, error) { + return NewEngine(engine.DriverName(), engine.DataSourceName()) +} -- cgit v1.2.3