From 18a3373725c611c9d704e560a880b89c4d8ce7db Mon Sep 17 00:00:00 2001
From: Wang Yan
Date: Thu, 24 Nov 2022 18:07:42 +0800
Subject: [PATCH] bump beego (#17801)
* bump beego
upgrade beego version from v1.10.12 to v2.0.5
1, beego v2 vserver/web refactor
2, beego v2 context refactor
3, beego v2 session refactor
4, beego v2 cache refactor
5, beego v2 orm refactor
Signed-off-by: MinerYang
---
Makefile | 2 +-
src/chartserver/cache.go | 16 +-
src/chartserver/redis_sentinel.go | 34 +-
src/common/api/base.go | 10 +-
src/common/dao/base.go | 2 +-
src/common/dao/dao_test.go | 30 +-
src/common/dao/mysql.go | 2 +-
src/common/dao/pgsql.go | 12 +-
src/common/dao/pgsql_test.go | 2 +-
src/common/dao/resource_label.go | 2 +-
src/common/dao/sqlite.go | 2 +-
src/common/dao/testutils.go | 21 +-
src/common/models/base.go | 2 +-
.../event/handler/internal/artifact_test.go | 2 +-
.../event/handler/webhook/scan/scan.go | 2 +-
src/controller/health/checker.go | 2 +-
src/core/api/base.go | 12 +-
src/core/api/chart_repository_test.go | 2 +-
src/core/api/harborapi_test.go | 38 +-
src/core/api/internal.go | 7 +-
src/core/api/label_resource.go | 7 +-
src/core/controllers/base.go | 14 +-
src/core/controllers/controllers_test.go | 16 +-
src/core/controllers/error.go | 4 +-
src/core/controllers/oidc.go | 36 +-
src/core/main.go | 28 +-
src/core/middlewares/middlewares.go | 6 +-
src/core/service/token/token.go | 9 +-
src/core/session/codec.go | 2 +-
src/core/session/session.go | 62 +-
src/core/session/session_test.go | 50 +-
src/go.mod | 16 +-
src/go.sum | 67 +-
src/jobservice/job/impl/context.go | 2 +-
src/jobservice/job/impl/default_context.go | 2 +-
src/jobservice/sync/schedule.go | 2 +-
src/lib/config/models/model.go | 2 +-
src/lib/orm/creator.go | 2 +-
src/lib/orm/error.go | 2 +-
src/lib/orm/error_test.go | 2 +-
src/lib/orm/metadata.go | 2 +-
src/lib/orm/metadata_test.go | 2 +-
src/lib/orm/orm.go | 27 +-
src/lib/orm/query.go | 2 +-
src/lib/orm/test/orm_test.go | 2 +-
src/lib/orm/tx.go | 25 +-
src/migration/migration.go | 2 +-
src/pkg/accessory/dao/dao_test.go | 2 +-
src/pkg/accessory/dao/model.go | 2 +-
src/pkg/allowlist/dao/dao.go | 2 +-
src/pkg/artifact/dao/dao.go | 2 +-
src/pkg/artifact/dao/dao_test.go | 2 +-
src/pkg/artifact/dao/model.go | 2 +-
src/pkg/artifactrash/dao/dao_test.go | 2 +-
src/pkg/artifactrash/model/model.go | 2 +-
src/pkg/audit/dao/dao.go | 4 +-
src/pkg/audit/dao/dao_test.go | 2 +-
src/pkg/audit/model/model.go | 2 +-
src/pkg/blob/models/blob.go | 2 +-
src/pkg/immutable/dao/model/rule.go | 2 +-
src/pkg/immutable/model/rule.go | 2 +-
src/pkg/joblog/models/joblog.go | 2 +-
src/pkg/label/dao/dao_test.go | 2 +-
src/pkg/label/model/model.go | 2 +-
src/pkg/notification/job/model/model.go | 2 +-
src/pkg/notification/policy/model/model.go | 2 +-
src/pkg/p2p/preheat/dao/instance/dao.go | 5 +-
src/pkg/p2p/preheat/dao/instance/dao_test.go | 2 +-
src/pkg/p2p/preheat/dao/policy/dao.go | 17 +-
src/pkg/p2p/preheat/dao/policy/dao_test.go | 2 +-
src/pkg/p2p/preheat/models/policy/policy.go | 4 +-
.../p2p/preheat/models/policy/policy_test.go | 2 +-
.../p2p/preheat/models/provider/instance.go | 2 +-
src/pkg/project/metadata/models/metadata.go | 2 +-
src/pkg/quota/dao/model.go | 2 +-
src/pkg/rbac/model/model.go | 2 +-
src/pkg/reg/dao/dao_test.go | 2 +-
src/pkg/reg/dao/model.go | 2 +-
src/pkg/replication/dao/dao_test.go | 2 +-
src/pkg/replication/model/model.go | 2 +-
src/pkg/repository/dao/dao.go | 2 +-
src/pkg/repository/dao/dao_test.go | 2 +-
src/pkg/retention/dao/models/retention.go | 2 +-
src/pkg/retention/manager.go | 2 +-
src/pkg/retention/policy/models.go | 2 +-
src/pkg/retention/policy/models_test.go | 2 +-
src/pkg/retention/policy/rule/models.go | 2 +-
src/pkg/robot/model/model.go | 2 +-
src/pkg/scan/export/manager.go | 2 +-
src/pkg/scheduler/dao.go | 2 +-
src/pkg/tag/dao/dao.go | 2 +-
src/pkg/tag/dao/dao_test.go | 2 +-
src/pkg/task/dao/model.go | 2 +-
src/server/middleware/blob/head_blob_test.go | 2 +-
src/server/middleware/orm/orm.go | 2 +-
src/server/middleware/orm/orm_test.go | 2 +-
src/server/middleware/security/session.go | 6 +-
.../middleware/security/session_test.go | 24 +-
src/server/middleware/session/session_test.go | 24 +-
.../transaction/transaction_test.go | 89 +-
src/server/registry/manifest_test.go | 2 +-
src/server/route.go | 50 +-
src/server/router/router.go | 22 +-
src/server/router/router_test.go | 2 +-
src/server/v2.0/handler/scanexport_test.go | 2 +-
src/server/v2.0/route/legacy.go | 6 +-
src/testing/lib/orm/creator.go | 2 +-
src/testing/lib/orm/orm.go | 270 +++-
src/testing/suite.go | 2 +-
src/vendor/github.com/beego/beego/.gitignore | 6 -
src/vendor/github.com/beego/beego/.travis.yml | 73 -
.../github.com/beego/beego/CONTRIBUTING.md | 52 -
src/vendor/github.com/beego/beego/README.md | 73 -
src/vendor/github.com/beego/beego/admin.go | 458 ------
src/vendor/github.com/beego/beego/app.go | 496 ------
.../github.com/beego/beego/cache/file.go | 258 ---
.../github.com/beego/beego/cache/memory.go | 256 ---
src/vendor/github.com/beego/beego/config.go | 537 -------
.../github.com/beego/beego/config/json.go | 269 ----
.../github.com/beego/beego/context/context.go | 273 ----
src/vendor/github.com/beego/beego/filter.go | 44 -
src/vendor/github.com/beego/beego/log.go | 127 --
.../github.com/beego/beego/logs/slack.go | 60 -
.../github.com/beego/beego/orm/cmd_utils.go | 320 ----
.../github.com/beego/beego/orm/models.go | 99 --
.../github.com/beego/beego/orm/models_boot.go | 347 ----
src/vendor/github.com/beego/beego/orm/orm.go | 579 -------
.../github.com/beego/beego/orm/qb_tidb.go | 182 ---
src/vendor/github.com/beego/beego/parser.go | 590 -------
src/vendor/github.com/beego/beego/router.go | 1052 -------------
src/vendor/github.com/beego/beego/test.sh | 14 -
.../beego/beego/test_docker_compose.yaml | 39 -
.../github.com/beego/beego/toolbox/task.go | 634 --------
.../beego/beego/v2/.deepsource.toml | 12 +
.../github.com/beego/beego/v2/.gitignore | 17 +
.../github.com/beego/beego/v2/CHANGELOG.md | 136 ++
.../github.com/beego/beego/v2/CONTRIBUTING.md | 93 ++
.../beego/beego/v2/ERROR_SPECIFICATION.md | 5 +
.../github.com/beego/beego/{ => v2}/LICENSE | 2 +-
src/vendor/github.com/beego/beego/v2/Makefile | 64 +
.../github.com/beego/beego/v2/README.md | 99 ++
.../beego/beego/{ => v2}/build_info.go | 5 +
.../beego/{ => v2/client}/cache/README.md | 15 +-
.../beego/{ => v2/client}/cache/cache.go | 52 +-
.../beego/beego/v2/client/cache/calc_utils.go | 95 ++
.../beego/beego/{ => v2/client}/cache/conv.go | 10 +-
.../beego/beego/v2/client/cache/error_code.go | 176 +++
.../beego/beego/v2/client/cache/file.go | 338 ++++
.../beego/beego/v2/client/cache/memory.go | 235 +++
.../beego/beego/v2/client/cache/module.go | 17 +
.../v2/client/cache/random_expired_cache.go | 75 +
.../{ => v2/client}/cache/redis/redis.go | 137 +-
.../beego/beego/{ => v2/client}/orm/README.md | 8 +-
.../beego/v2/client/orm/clauses/const.go | 6 +
.../client/orm/clauses/order_clause/order.go | 104 ++
.../beego/beego/{ => v2/client}/orm/cmd.go | 60 +-
.../beego/beego/v2/client/orm/cmd_utils.go | 169 ++
.../beego/beego/{ => v2/client}/orm/db.go | 368 +++--
.../beego/{ => v2/client}/orm/db_alias.go | 304 ++--
.../beego/{ => v2/client}/orm/db_mysql.go | 62 +-
.../beego/{ => v2/client}/orm/db_oracle.go | 82 +-
.../beego/{ => v2/client}/orm/db_postgres.go | 56 +-
.../beego/{ => v2/client}/orm/db_sqlite.go | 71 +-
.../beego/{ => v2/client}/orm/db_tables.go | 43 +-
.../beego/{ => v2/client}/orm/db_tidb.go | 5 +-
.../beego/{ => v2/client}/orm/db_utils.go | 6 +-
.../beego/v2/client/orm/do_nothing_orm.go | 181 +++
.../beego/beego/v2/client/orm/filter.go | 40 +
.../v2/client/orm/filter_orm_decorator.go | 534 +++++++
.../beego/v2/client/orm/hints/db_hints.go | 103 ++
.../beego/beego/v2/client/orm/invocation.go | 58 +
.../beego/beego/v2/client/orm/models.go | 573 +++++++
.../beego/beego/v2/client/orm/models_boot.go | 40 +
.../{ => v2/client}/orm/models_fields.go | 0
.../{ => v2/client}/orm/models_info_f.go | 40 +-
.../{ => v2/client}/orm/models_info_m.go | 8 +-
.../beego/{ => v2/client}/orm/models_utils.go | 16 +
.../beego/beego/v2/client/orm/orm.go | 661 ++++++++
.../beego/{ => v2/client}/orm/orm_conds.go | 17 +-
.../beego/{ => v2/client}/orm/orm_log.go | 62 +-
.../beego/{ => v2/client}/orm/orm_object.go | 13 +-
.../beego/{ => v2/client}/orm/orm_querym2m.go | 35 +-
.../beego/{ => v2/client}/orm/orm_queryset.go | 146 +-
.../beego/{ => v2/client}/orm/orm_raw.go | 63 +-
.../beego/beego/{ => v2/client}/orm/qb.go | 2 +-
.../beego/{ => v2/client}/orm/qb_mysql.go | 58 +-
.../beego/beego/v2/client/orm/qb_postgres.go | 219 +++
.../beego/beego/v2/client/orm/qb_tidb.go | 21 +
.../beego/beego/{ => v2/client}/orm/types.go | 371 +++--
.../beego/beego/{ => v2/client}/orm/utils.go | 10 +-
.../beego/beego/v2/core/admin/command.go | 87 ++
.../{toolbox => v2/core/admin}/healthcheck.go | 6 +-
.../{toolbox => v2/core/admin}/profile.go | 55 +-
.../beego/beego/v2/core/berror/codes.go | 86 +
.../beego/beego/v2/core/berror/error.go | 69 +
.../beego/v2/core/berror/pre_define_code.go | 52 +
.../beego/{ => v2/core}/config/config.go | 154 +-
.../beego/beego/v2/core/config/error.go | 25 +
.../beego/beego/{ => v2/core}/config/fake.go | 56 +-
.../beego/beego/v2/core/config/global.go | 111 ++
.../beego/beego/{ => v2/core}/config/ini.go | 95 +-
.../beego/beego/{ => v2/core}/logs/README.md | 8 +-
.../core/logs/access_log.go} | 16 +-
.../beego/beego/{ => v2/core}/logs/conn.go | 48 +-
.../beego/beego/{ => v2/core}/logs/console.go | 66 +-
.../beego/beego/{ => v2/core}/logs/file.go | 93 +-
.../beego/beego/v2/core/logs/formatter.go | 91 ++
.../beego/{ => v2/core}/logs/jianliao.go | 44 +-
.../beego/beego/{ => v2/core}/logs/log.go | 289 ++--
.../beego/beego/v2/core/logs/log_msg.go | 55 +
.../beego/beego/{ => v2/core}/logs/logger.go | 18 +-
.../beego/{ => v2/core}/logs/multifile.go | 33 +-
.../beego/beego/v2/core/logs/slack.go | 84 +
.../beego/beego/{ => v2/core}/logs/smtp.go | 43 +-
.../beego/beego/{ => v2/core}/utils/caller.go | 0
.../beego/beego/{ => v2/core}/utils/debug.go | 56 +-
.../beego/beego/{ => v2/core}/utils/file.go | 0
.../beego/beego/v2/core/utils/kv.go | 87 ++
.../beego/beego/{ => v2/core}/utils/mail.go | 4 +-
.../beego/beego/{ => v2/core}/utils/rand.go | 2 +-
.../beego/{ => v2/core}/utils/safemap.go | 2 +-
.../beego/beego/{ => v2/core}/utils/slice.go | 1 +
.../beego/beego/v2/core/utils/time.go | 46 +
.../beego/beego/{ => v2/core}/utils/utils.go | 0
.../beego/{ => v2/core}/validation/README.md | 11 +-
.../beego/{ => v2/core}/validation/util.go | 0
.../{ => v2/core}/validation/validation.go | 24 +-
.../{ => v2/core}/validation/validators.go | 2 +-
src/vendor/github.com/beego/beego/v2/doc.go | 15 +
.../beego/beego/v2/server/web/LICENSE | 13 +
.../beego/beego/v2/server/web/admin.go | 122 ++
.../beego/v2/server/web/admin_controller.go | 293 ++++
.../beego/{ => v2/server/web}/adminui.go | 6 +-
.../beego/beego/{ => v2/server/web}/beego.go | 75 +-
.../beego/beego/v2/server/web/config.go | 872 +++++++++++
.../server/web}/context/acceptencoder.go | 48 +-
.../beego/v2/server/web/context/context.go | 399 +++++
.../beego/beego/v2/server/web/context/form.go | 189 +++
.../{ => v2/server/web}/context/input.go | 54 +-
.../{ => v2/server/web}/context/output.go | 88 +-
.../{ => v2/server/web}/context/param/conv.go | 4 +-
.../server/web}/context/param/methodparams.go | 6 +-
.../server/web}/context/param/options.go | 0
.../server/web}/context/param/parsers.go | 20 +-
.../{ => v2/server/web}/context/renderer.go | 2 +-
.../{ => v2/server/web}/context/response.go | 11 +-
.../beego/{ => v2/server/web}/controller.go | 169 +-
.../beego/beego/{ => v2/server/web}/doc.go | 6 +-
.../beego/beego/{ => v2/server/web}/error.go | 27 +-
.../beego/beego/v2/server/web/filter.go | 136 ++
.../beego/beego/{ => v2/server/web}/flash.go | 4 +-
.../beego/beego/{ => v2/server/web}/fs.go | 6 +-
.../beego/{ => v2/server/web}/grace/grace.go | 19 +-
.../beego/{ => v2/server/web}/grace/server.go | 105 +-
.../beego/beego/{ => v2/server/web}/hooks.go | 20 +-
.../beego/beego/{ => v2/server/web}/mime.go | 2 +-
.../beego/{ => v2/server/web}/namespace.go | 178 ++-
.../beego/beego/{ => v2/server/web}/policy.go | 6 +-
.../beego/beego/v2/server/web/router.go | 1391 +++++++++++++++++
.../beego/beego/v2/server/web/server.go | 959 ++++++++++++
.../{ => v2/server/web}/session/README.md | 71 +-
.../server/web}/session/sess_cookie.go | 37 +-
.../{ => v2/server/web}/session/sess_file.go | 68 +-
.../{ => v2/server/web}/session/sess_mem.go | 43 +-
.../{ => v2/server/web}/session/sess_utils.go | 4 +-
.../{ => v2/server/web}/session/session.go | 97 +-
.../v2/server/web/session/session_config.go | 143 ++
.../web/session/session_provider_type.go | 18 +
.../beego/{ => v2/server/web}/staticfile.go | 19 +-
.../{toolbox => v2/server/web}/statistics.go | 28 +-
.../beego/{ => v2/server/web}/template.go | 31 +-
.../beego/{ => v2/server/web}/templatefunc.go | 249 +--
.../beego/beego/{ => v2/server/web}/tree.go | 34 +-
.../beego/beego/v2/sonar-project.properties | 7 +
.../github.com/casbin/casbin/.gitignore | 5 +-
.../github.com/casbin/casbin/.travis.yml | 24 +-
src/vendor/github.com/casbin/casbin/README.md | 174 +--
.../casbin/casbin/effect/default_effector.go | 2 +-
.../github.com/casbin/casbin/enforcer.go | 101 +-
.../casbin/casbin/enforcer_cached.go | 25 +-
.../github.com/casbin/casbin/enforcer_safe.go | 98 ++
.../casbin/casbin/enforcer_synced_safe.go | 63 +
.../casbin/casbin/errors/rbac_errors.go | 24 +
.../casbin/casbin/persist/adapter.go | 9 +-
.../persist/file-adapter/adapter_filtered.go | 1 +
.../casbin/casbin/persist/watcher.go | 2 +
.../rbac/default-role-manager/role_manager.go | 57 +-
.../github.com/casbin/casbin/rbac_api.go | 99 +-
.../casbin/casbin/rbac_api_synced.go | 26 +-
.../casbin/casbin/rbac_api_with_domains.go | 6 +
.../casbin/rbac_api_with_domains_synced.go | 52 +
.../casbin/casbin/util/builtin_operators.go | 6 +-
.../github.com/casbin/casbin/util/util.go | 50 +-
.../go-sql-driver/mysql/.travis.yml | 129 --
.../github.com/go-sql-driver/mysql/AUTHORS | 12 +
.../go-sql-driver/mysql/CHANGELOG.md | 26 +
.../github.com/go-sql-driver/mysql/README.md | 43 +-
.../github.com/go-sql-driver/mysql/auth.go | 13 +-
.../go-sql-driver/mysql/collations.go | 2 +-
.../go-sql-driver/mysql/connection.go | 85 +-
.../github.com/go-sql-driver/mysql/dsn.go | 2 +-
.../github.com/go-sql-driver/mysql/fields.go | 2 +-
.../github.com/go-sql-driver/mysql/fuzz.go | 24 +
.../github.com/go-sql-driver/mysql/infile.go | 4 +-
.../go-sql-driver/mysql/nulltime.go | 4 +-
.../go-sql-driver/mysql/nulltime_go113.go | 9 +
.../go-sql-driver/mysql/nulltime_legacy.go | 5 +
.../github.com/go-sql-driver/mysql/packets.go | 23 +-
.../go-sql-driver/mysql/statement.go | 30 +-
.../github.com/go-sql-driver/mysql/utils.go | 195 ++-
.../mitchellh/mapstructure/CHANGELOG.md | 14 +-
.../mitchellh/mapstructure/decode_hooks.go | 3 +-
.../mitchellh/mapstructure/mapstructure.go | 21 +-
.../github.com/shiena/ansicolor/README.md | 3 +-
.../shiena/ansicolor/ansicolor_windows.go | 2 +-
.../go.opentelemetry.io/otel/.gitignore | 2 +-
.../go.opentelemetry.io/otel/.golangci.yml | 232 ++-
.../go.opentelemetry.io/otel/.lycheeignore | 3 +
.../otel/.markdown-link.json | 16 -
.../go.opentelemetry.io/otel/CHANGELOG.md | 249 ++-
.../go.opentelemetry.io/otel/CODEOWNERS | 2 +-
.../go.opentelemetry.io/otel/CONTRIBUTING.md | 73 +-
src/vendor/go.opentelemetry.io/otel/Makefile | 169 +-
src/vendor/go.opentelemetry.io/otel/README.md | 14 +-
.../go.opentelemetry.io/otel/RELEASING.md | 41 +-
.../otel/attribute/encoder.go | 86 +-
.../otel/attribute/iterator.go | 80 +-
.../go.opentelemetry.io/otel/attribute/kv.go | 2 +-
.../go.opentelemetry.io/otel/attribute/set.go | 160 +-
.../otel/attribute/value.go | 6 +-
.../otel/baggage/baggage.go | 117 +-
.../go.opentelemetry.io/otel/handler.go | 3 +-
.../otel/internal/baggage/context.go | 9 +-
.../otel/internal/global/internal_logging.go | 4 +-
.../otel/internal/global/state.go | 53 +-
.../otel/internal/rawhelpers.go | 2 +-
.../go.opentelemetry.io/otel/pre_release.sh | 95 --
.../otel/sdk/instrumentation/library.go | 11 +-
.../otel/sdk/instrumentation/scope.go | 33 +
.../otel/sdk/internal/env/env.go | 177 +++
.../otel/sdk/internal/sanitize.go | 50 -
.../otel/sdk/resource/auto.go | 2 +-
.../otel/sdk/resource/builtin.go | 4 +-
.../otel/sdk/resource/config.go | 38 +-
.../otel/sdk/resource/container.go | 100 ++
.../otel/sdk/resource/env.go | 6 +-
.../otel/sdk/resource/os.go | 2 +-
.../otel/sdk/resource/os_unix.go | 20 +-
.../otel/sdk/resource/process.go | 9 +-
.../otel/sdk/resource/resource.go | 25 +-
.../otel/sdk/trace/attributesmap.go | 91 --
.../otel/sdk/trace/batch_span_processor.go | 121 +-
.../otel/sdk/trace/config.go | 68 -
.../otel/sdk/trace/evictedqueue.go | 24 +-
.../otel/sdk/trace/id_generator.go | 6 +-
.../otel/sdk/trace/provider.go | 179 ++-
.../otel/sdk/trace/sampler_env.go | 108 ++
.../otel/sdk/trace/sampling.go | 24 +-
.../otel/sdk/trace/simple_span_processor.go | 11 +
.../otel/sdk/trace/snapshot.go | 40 +-
.../otel/sdk/trace/span.go | 279 +++-
.../otel/sdk/trace/span_limits.go | 125 ++
.../otel/sdk/trace/tracer.go | 32 +-
.../otel/semconv/{v1.7.0 => internal}/http.go | 127 +-
.../otel/semconv/{v1.7.0 => v1.10.0}/doc.go | 4 +-
.../semconv/{v1.7.0 => v1.10.0}/exception.go | 2 +-
.../otel/semconv/v1.10.0/http.go | 114 ++
.../semconv/{v1.7.0 => v1.10.0}/resource.go | 55 +-
.../semconv/{v1.7.0 => v1.10.0}/schema.go | 4 +-
.../otel/semconv/{v1.7.0 => v1.10.0}/trace.go | 224 ++-
.../otel/semconv/v1.4.0/http.go | 271 +---
.../otel/semconv/v1.4.0/schema.go | 2 +-
src/vendor/go.opentelemetry.io/otel/tag.sh | 178 ---
.../go.opentelemetry.io/otel/trace/config.go | 79 +-
.../go.opentelemetry.io/otel/trace/noop.go | 2 +-
.../go.opentelemetry.io/otel/trace/trace.go | 10 +-
.../otel/trace/tracestate.go | 21 +-
.../go.opentelemetry.io/otel/version.go | 2 +-
.../go.opentelemetry.io/otel/versions.yaml | 10 +-
src/vendor/modules.txt | 60 +-
tests/ci/ut_install.sh | 2 +
381 files changed, 16775 insertions(+), 11135 deletions(-)
delete mode 100644 src/vendor/github.com/beego/beego/.gitignore
delete mode 100644 src/vendor/github.com/beego/beego/.travis.yml
delete mode 100644 src/vendor/github.com/beego/beego/CONTRIBUTING.md
delete mode 100644 src/vendor/github.com/beego/beego/README.md
delete mode 100644 src/vendor/github.com/beego/beego/admin.go
delete mode 100644 src/vendor/github.com/beego/beego/app.go
delete mode 100644 src/vendor/github.com/beego/beego/cache/file.go
delete mode 100644 src/vendor/github.com/beego/beego/cache/memory.go
delete mode 100644 src/vendor/github.com/beego/beego/config.go
delete mode 100644 src/vendor/github.com/beego/beego/config/json.go
delete mode 100644 src/vendor/github.com/beego/beego/context/context.go
delete mode 100644 src/vendor/github.com/beego/beego/filter.go
delete mode 100644 src/vendor/github.com/beego/beego/log.go
delete mode 100644 src/vendor/github.com/beego/beego/logs/slack.go
delete mode 100644 src/vendor/github.com/beego/beego/orm/cmd_utils.go
delete mode 100644 src/vendor/github.com/beego/beego/orm/models.go
delete mode 100644 src/vendor/github.com/beego/beego/orm/models_boot.go
delete mode 100644 src/vendor/github.com/beego/beego/orm/orm.go
delete mode 100644 src/vendor/github.com/beego/beego/orm/qb_tidb.go
delete mode 100644 src/vendor/github.com/beego/beego/parser.go
delete mode 100644 src/vendor/github.com/beego/beego/router.go
delete mode 100644 src/vendor/github.com/beego/beego/test.sh
delete mode 100644 src/vendor/github.com/beego/beego/test_docker_compose.yaml
delete mode 100644 src/vendor/github.com/beego/beego/toolbox/task.go
create mode 100644 src/vendor/github.com/beego/beego/v2/.deepsource.toml
create mode 100644 src/vendor/github.com/beego/beego/v2/.gitignore
create mode 100644 src/vendor/github.com/beego/beego/v2/CHANGELOG.md
create mode 100644 src/vendor/github.com/beego/beego/v2/CONTRIBUTING.md
create mode 100644 src/vendor/github.com/beego/beego/v2/ERROR_SPECIFICATION.md
rename src/vendor/github.com/beego/beego/{ => v2}/LICENSE (94%)
create mode 100644 src/vendor/github.com/beego/beego/v2/Makefile
create mode 100644 src/vendor/github.com/beego/beego/v2/README.md
rename src/vendor/github.com/beego/beego/{ => v2}/build_info.go (90%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/cache/README.md (89%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/cache/cache.go (60%)
create mode 100644 src/vendor/github.com/beego/beego/v2/client/cache/calc_utils.go
rename src/vendor/github.com/beego/beego/{ => v2/client}/cache/conv.go (90%)
create mode 100644 src/vendor/github.com/beego/beego/v2/client/cache/error_code.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/cache/file.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/cache/memory.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/cache/module.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/cache/random_expired_cache.go
rename src/vendor/github.com/beego/beego/{ => v2/client}/cache/redis/redis.go (58%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/README.md (91%)
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/clauses/const.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/clauses/order_clause/order.go
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/cmd.go (79%)
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/cmd_utils.go
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db.go (81%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_alias.go (63%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_mysql.go (72%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_oracle.go (57%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_postgres.go (72%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_sqlite.go (64%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_tables.go (88%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_tidb.go (89%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/db_utils.go (98%)
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/do_nothing_orm.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/filter.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/filter_orm_decorator.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/hints/db_hints.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/invocation.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/models.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/models_boot.go
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/models_fields.go (100%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/models_info_f.go (96%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/models_info_m.go (97%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/models_utils.go (93%)
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/orm.go
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/orm_conds.go (92%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/orm_log.go (80%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/orm_object.go (82%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/orm_querym2m.go (76%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/orm_queryset.go (61%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/orm_raw.go (92%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/qb.go (96%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/qb_mysql.go (71%)
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/qb_postgres.go
create mode 100644 src/vendor/github.com/beego/beego/v2/client/orm/qb_tidb.go
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/types.go (61%)
rename src/vendor/github.com/beego/beego/{ => v2/client}/orm/utils.go (97%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/admin/command.go
rename src/vendor/github.com/beego/beego/{toolbox => v2/core/admin}/healthcheck.go (92%)
rename src/vendor/github.com/beego/beego/{toolbox => v2/core/admin}/profile.go (79%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/berror/codes.go
create mode 100644 src/vendor/github.com/beego/beego/v2/core/berror/error.go
create mode 100644 src/vendor/github.com/beego/beego/v2/core/berror/pre_define_code.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/config/config.go (63%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/config/error.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/config/fake.go (71%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/config/global.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/config/ini.go (84%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/README.md (93%)
rename src/vendor/github.com/beego/beego/{logs/accesslog.go => v2/core/logs/access_log.go} (89%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/conn.go (66%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/console.go (58%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/file.go (82%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/logs/formatter.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/jianliao.go (56%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/log.go (73%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/logs/log_msg.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/logger.go (93%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/multifile.go (83%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/logs/slack.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/logs/smtp.go (77%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/caller.go (100%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/debug.go (90%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/file.go (100%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/utils/kv.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/mail.go (99%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/rand.go (97%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/safemap.go (98%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/slice.go (99%)
create mode 100644 src/vendor/github.com/beego/beego/v2/core/utils/time.go
rename src/vendor/github.com/beego/beego/{ => v2/core}/utils/utils.go (100%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/validation/README.md (90%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/validation/util.go (100%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/validation/validation.go (95%)
rename src/vendor/github.com/beego/beego/{ => v2/core}/validation/validators.go (99%)
create mode 100644 src/vendor/github.com/beego/beego/v2/doc.go
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/LICENSE
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/admin.go
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/admin_controller.go
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/adminui.go (98%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/beego.go (65%)
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/config.go
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/acceptencoder.go (81%)
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/context/context.go
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/context/form.go
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/input.go (92%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/output.go (81%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/param/conv.go (95%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/param/methodparams.go (85%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/param/options.go (100%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/param/parsers.go (93%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/renderer.go (77%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/context/response.go (66%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/controller.go (83%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/doc.go (82%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/error.go (95%)
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/filter.go
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/flash.go (98%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/fs.go (97%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/grace/grace.go (89%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/grace/server.go (79%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/hooks.go (88%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/mime.go (99%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/namespace.go (63%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/policy.go (96%)
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/router.go
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/server.go
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/session/README.md (61%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/session/sess_cookie.go (75%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/session/sess_file.go (77%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/session/sess_mem.go (75%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/session/sess_utils.go (98%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/session/session.go (76%)
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/session/session_config.go
create mode 100644 src/vendor/github.com/beego/beego/v2/server/web/session/session_provider_type.go
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/staticfile.go (94%)
rename src/vendor/github.com/beego/beego/{toolbox => v2/server/web}/statistics.go (80%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/template.go (94%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/templatefunc.go (75%)
rename src/vendor/github.com/beego/beego/{ => v2/server/web}/tree.go (95%)
create mode 100644 src/vendor/github.com/beego/beego/v2/sonar-project.properties
create mode 100644 src/vendor/github.com/casbin/casbin/enforcer_synced_safe.go
create mode 100644 src/vendor/github.com/casbin/casbin/errors/rbac_errors.go
create mode 100644 src/vendor/github.com/casbin/casbin/rbac_api_with_domains_synced.go
delete mode 100644 src/vendor/github.com/go-sql-driver/mysql/.travis.yml
create mode 100644 src/vendor/github.com/go-sql-driver/mysql/fuzz.go
create mode 100644 src/vendor/go.opentelemetry.io/otel/.lycheeignore
delete mode 100644 src/vendor/go.opentelemetry.io/otel/.markdown-link.json
delete mode 100644 src/vendor/go.opentelemetry.io/otel/pre_release.sh
create mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go
create mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go
delete mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/internal/sanitize.go
create mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/resource/container.go
delete mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/trace/attributesmap.go
delete mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/trace/config.go
create mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go
create mode 100644 src/vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go
rename src/vendor/go.opentelemetry.io/otel/semconv/{v1.7.0 => internal}/http.go (60%)
rename src/vendor/go.opentelemetry.io/otel/semconv/{v1.7.0 => v1.10.0}/doc.go (85%)
rename src/vendor/go.opentelemetry.io/otel/semconv/{v1.7.0 => v1.10.0}/exception.go (91%)
create mode 100644 src/vendor/go.opentelemetry.io/otel/semconv/v1.10.0/http.go
rename src/vendor/go.opentelemetry.io/otel/semconv/{v1.7.0 => v1.10.0}/resource.go (93%)
rename src/vendor/go.opentelemetry.io/otel/semconv/{v1.7.0 => v1.10.0}/schema.go (86%)
rename src/vendor/go.opentelemetry.io/otel/semconv/{v1.7.0 => v1.10.0}/trace.go (88%)
delete mode 100644 src/vendor/go.opentelemetry.io/otel/tag.sh
diff --git a/Makefile b/Makefile
index af94edd59..58d4936d1 100644
--- a/Makefile
+++ b/Makefile
@@ -523,7 +523,7 @@ GOLANGCI_LINT := $(shell go env GOPATH)/bin/golangci-lint
lint:
@echo checking lint
@echo $(GOLANGCI_LINT)
- @cd ./src/; $(GOLANGCI_LINT) -v run ./...;
+ @cd ./src/; $(GOLANGCI_LINT) -v run ./... --timeout=10m;
# go install golang.org/x/vuln/cmd/govulncheck@latest
GOVULNCHECK := $(shell go env GOPATH)/bin/govulncheck
diff --git a/src/chartserver/cache.go b/src/chartserver/cache.go
index 4cffef5b8..db27c2f7f 100644
--- a/src/chartserver/cache.go
+++ b/src/chartserver/cache.go
@@ -1,14 +1,15 @@
package chartserver
import (
+ "context"
"encoding/json"
"errors"
"math"
"time"
- beego_cache "github.com/beego/beego/cache"
+ beego_cache "github.com/beego/beego/v2/client/cache"
// Enable redis cache adaptor
- _ "github.com/beego/beego/cache/redis"
+ _ "github.com/beego/beego/v2/client/cache/redis"
hlog "github.com/goharbor/harbor/src/lib/log"
)
@@ -94,6 +95,7 @@ func (chc *ChartCache) IsEnabled() bool {
// PutChart caches the detailed data of chart version
func (chc *ChartCache) PutChart(chart *ChartVersionDetails) {
+ ctx := context.Background()
// If cache is not enabled, do nothing
if !chc.IsEnabled() {
return
@@ -107,12 +109,12 @@ func (chc *ChartCache) PutChart(chart *ChartVersionDetails) {
switch chc.driverType {
case cacheDriverMem:
// Directly put object in
- err = chc.cache.Put(chart.Metadata.Digest, chart, standardExpireTime)
+ err = chc.cache.Put(ctx, chart.Metadata.Digest, chart, standardExpireTime)
case cacheDriverRedis, cacheDriverRedisSentinel:
// Marshal to json data before saving
var jsonData []byte
if jsonData, err = json.Marshal(chart); err == nil {
- err = chc.cache.Put(chart.Metadata.Digest, jsonData, standardExpireTime)
+ err = chc.cache.Put(ctx, chart.Metadata.Digest, jsonData, standardExpireTime)
}
default:
// Should not reach here, but still put guard code here
@@ -132,11 +134,15 @@ func (chc *ChartCache) PutChart(chart *ChartVersionDetails) {
// otherwise, nil object is returned
func (chc *ChartCache) GetChart(chartDigest string) *ChartVersionDetails {
// If cache is not enabled, do nothing
+ ctx := context.Background()
if !chc.IsEnabled() {
return nil
}
- object := chc.cache.Get(chartDigest)
+ object, err := chc.cache.Get(ctx, chartDigest)
+ if err != nil {
+ hlog.Warningf("Failed to get cache value by key with error: %s", err)
+ }
if object != nil {
// Try to convert data
// First try the normal way
diff --git a/src/chartserver/redis_sentinel.go b/src/chartserver/redis_sentinel.go
index 34a08fd10..4e2b984b7 100644
--- a/src/chartserver/redis_sentinel.go
+++ b/src/chartserver/redis_sentinel.go
@@ -1,6 +1,7 @@
package chartserver
import (
+ "context"
"encoding/json"
"errors"
"fmt"
@@ -9,7 +10,7 @@ import (
"time"
"github.com/FZambia/sentinel"
- "github.com/beego/beego/cache"
+ "github.com/beego/beego/v2/client/cache"
"github.com/gomodule/redigo/redis"
)
@@ -52,15 +53,16 @@ func (rc *Cache) associate(originKey interface{}) string {
}
// Get cache from redis.
-func (rc *Cache) Get(key string) interface{} {
- if v, err := rc.do("GET", key); err == nil {
- return v
+func (rc *Cache) Get(ctx context.Context, key string) (interface{}, error) {
+ v, err := rc.do("GET", key)
+ if err != nil {
+ return nil, err
}
- return nil
+ return v, err
}
// GetMulti get cache from redis.
-func (rc *Cache) GetMulti(keys []string) []interface{} {
+func (rc *Cache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
c := rc.p.Get()
defer c.Close()
var args []interface{}
@@ -69,46 +71,46 @@ func (rc *Cache) GetMulti(keys []string) []interface{} {
}
values, err := redis.Values(c.Do("MGET", args...))
if err != nil {
- return nil
+ return nil, err
}
- return values
+ return values, nil
}
// Put put cache to redis.
-func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
+func (rc *Cache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
_, err := rc.do("SETEX", key, int64(timeout/time.Second), val)
return err
}
// Delete delete cache in redis.
-func (rc *Cache) Delete(key string) error {
+func (rc *Cache) Delete(ctx context.Context, key string) error {
_, err := rc.do("DEL", key)
return err
}
// IsExist check cache's existence in redis.
-func (rc *Cache) IsExist(key string) bool {
+func (rc *Cache) IsExist(ctx context.Context, key string) (bool, error) {
v, err := redis.Bool(rc.do("EXISTS", key))
if err != nil {
- return false
+ return false, err
}
- return v
+ return v, nil
}
// Incr increase counter in redis.
-func (rc *Cache) Incr(key string) error {
+func (rc *Cache) Incr(ctx context.Context, key string) error {
_, err := redis.Bool(rc.do("INCRBY", key, 1))
return err
}
// Decr decrease counter in redis.
-func (rc *Cache) Decr(key string) error {
+func (rc *Cache) Decr(ctx context.Context, key string) error {
_, err := redis.Bool(rc.do("INCRBY", key, -1))
return err
}
// ClearAll clean all cache in redis. delete this redis collection.
-func (rc *Cache) ClearAll() error {
+func (rc *Cache) ClearAll(ctx context.Context) error {
c := rc.p.Get()
defer c.Close()
cachedKeys, err := redis.Strings(c.Do("KEYS", rc.key+":*"))
diff --git a/src/common/api/base.go b/src/common/api/base.go
index 84d6ea637..116883ae7 100644
--- a/src/common/api/base.go
+++ b/src/common/api/base.go
@@ -22,8 +22,8 @@ import (
"net/http"
"strconv"
- "github.com/beego/beego"
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
+ "github.com/beego/beego/v2/server/web"
commonhttp "github.com/goharbor/harbor/src/common/http"
lib_http "github.com/goharbor/harbor/src/lib/http"
@@ -40,7 +40,7 @@ const (
// BaseAPI wraps common methods for controllers to host API
type BaseAPI struct {
- beego.Controller
+ web.Controller
}
// Context returns the context.Context from http.Request
@@ -79,10 +79,10 @@ func (b *BaseAPI) RenderError(code int, text string) {
// DecodeJSONReq decodes a json request
func (b *BaseAPI) DecodeJSONReq(v interface{}) error {
- err := json.Unmarshal(b.Ctx.Input.CopyBody(1<<32), v)
+ err := json.Unmarshal(b.Ctx.Input.CopyBody(1<<35), v)
if err != nil {
log.Errorf("Error while decoding the json request, error: %v, %v",
- err, string(b.Ctx.Input.CopyBody(1 << 32)[:]))
+ err, string(b.Ctx.Input.CopyBody(1 << 35)[:]))
return errors.New("invalid json request")
}
return nil
diff --git a/src/common/dao/base.go b/src/common/dao/base.go
index eeccb2525..cf9bba282 100644
--- a/src/common/dao/base.go
+++ b/src/common/dao/base.go
@@ -20,7 +20,7 @@ import (
"strconv"
"sync"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/log"
diff --git a/src/common/dao/dao_test.go b/src/common/dao/dao_test.go
index a1248dbf8..6efa0f86f 100644
--- a/src/common/dao/dao_test.go
+++ b/src/common/dao/dao_test.go
@@ -19,8 +19,8 @@ import (
"os"
"testing"
- "github.com/beego/beego/orm"
-
+ "github.com/beego/beego/v2/client/orm"
+
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/log"
libOrm "github.com/goharbor/harbor/src/lib/orm"
@@ -29,7 +29,7 @@ import (
var testCtx context.Context
-func execUpdate(o orm.Ormer, sql string, params ...interface{}) error {
+func execUpdate(o orm.TxOrmer, sql string, params ...interface{}) error {
p, err := o.Raw(sql).Prepare()
if err != nil {
return err
@@ -46,9 +46,9 @@ func cleanByUser(username string) {
var err error
o := GetOrmer()
- o.Begin()
+ txOrm, err := o.Begin()
- err = execUpdate(o, `delete
+ err = execUpdate(txOrm, `delete
from project_member
where entity_id = (
select user_id
@@ -56,11 +56,11 @@ func cleanByUser(username string) {
where username = ?
) `, username)
if err != nil {
- o.Rollback()
+ txOrm.Rollback()
log.Error(err)
}
- err = execUpdate(o, `delete
+ err = execUpdate(txOrm, `delete
from project_member
where project_id = (
select project_id
@@ -68,30 +68,30 @@ func cleanByUser(username string) {
where name = ?
)`, projectName)
if err != nil {
- o.Rollback()
+ txOrm.Rollback()
log.Error(err)
}
- err = execUpdate(o, `delete from project where name = ?`, projectName)
+ err = execUpdate(txOrm, `delete from project where name = ?`, projectName)
if err != nil {
- o.Rollback()
+ txOrm.Rollback()
log.Error(err)
}
- err = execUpdate(o, `delete from harbor_user where username = ?`, username)
+ err = execUpdate(txOrm, `delete from harbor_user where username = ?`, username)
if err != nil {
- o.Rollback()
+ txOrm.Rollback()
log.Error(err)
}
- err = execUpdate(o, `delete from replication_policy where id < 99`)
+ err = execUpdate(txOrm, `delete from replication_policy where id < 99`)
if err != nil {
log.Error(err)
}
- err = execUpdate(o, `delete from registry where id < 99`)
+ err = execUpdate(txOrm, `delete from registry where id < 99`)
if err != nil {
log.Error(err)
}
- o.Commit()
+ txOrm.Commit()
}
const username string = "Tester01"
diff --git a/src/common/dao/mysql.go b/src/common/dao/mysql.go
index 5222272cb..9c78755fd 100644
--- a/src/common/dao/mysql.go
+++ b/src/common/dao/mysql.go
@@ -18,7 +18,7 @@ import (
"fmt"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
_ "github.com/go-sql-driver/mysql" // register mysql driver
"github.com/goharbor/harbor/src/common/utils"
diff --git a/src/common/dao/pgsql.go b/src/common/dao/pgsql.go
index 592357e08..665e8c2e9 100644
--- a/src/common/dao/pgsql.go
+++ b/src/common/dao/pgsql.go
@@ -22,7 +22,7 @@ import (
"strconv"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
migrate "github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/pgx" // import pgx driver for migrator
_ "github.com/golang-migrate/migrate/v4/source/file" // import local file driver for migrator
@@ -91,17 +91,11 @@ func (p *pgsql) Register(alias ...string) error {
info := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s timezone=UTC",
p.host, p.port, p.usr, p.pwd, p.database, p.sslmode)
- if err := orm.RegisterDataBase(an, "pgx", info, p.maxIdleConns, p.maxOpenConns); err != nil {
+ if err := orm.RegisterDataBase(an, "pgx", info, orm.MaxIdleConnections(p.maxIdleConns),
+ orm.MaxOpenConnections(p.maxOpenConns), orm.ConnMaxLifetime(5*time.Minute)); err != nil {
return err
}
- // Due to the issues of beego v1.12.1 and v1.12.2, we set the max open conns ourselves.
- // See https://github.com/goharbor/harbor/issues/12403
- // and https://github.com/beego/beego/issues/4059 for more info.
- db, _ := orm.GetDB(an)
- db.SetMaxOpenConns(p.maxOpenConns)
- db.SetConnMaxLifetime(5 * time.Minute)
-
return nil
}
diff --git a/src/common/dao/pgsql_test.go b/src/common/dao/pgsql_test.go
index 2a2aa635c..2e0461151 100644
--- a/src/common/dao/pgsql_test.go
+++ b/src/common/dao/pgsql_test.go
@@ -19,7 +19,7 @@ import (
"sync"
"testing"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func TestMaxOpenConns(t *testing.T) {
diff --git a/src/common/dao/resource_label.go b/src/common/dao/resource_label.go
index 6f3f68acb..721b7b46b 100644
--- a/src/common/dao/resource_label.go
+++ b/src/common/dao/resource_label.go
@@ -17,7 +17,7 @@ package dao
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/pkg/label/model"
diff --git a/src/common/dao/sqlite.go b/src/common/dao/sqlite.go
index 15ee7bb02..36702d2ad 100644
--- a/src/common/dao/sqlite.go
+++ b/src/common/dao/sqlite.go
@@ -17,7 +17,7 @@ package dao
import (
"fmt"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
// _ "github.com/mattn/go-sqlite3" // register sqlite driver
)
diff --git a/src/common/dao/testutils.go b/src/common/dao/testutils.go
index a0d7101b0..0e7f4f5d2 100644
--- a/src/common/dao/testutils.go
+++ b/src/common/dao/testutils.go
@@ -19,11 +19,14 @@ import (
"os"
"strconv"
+ "github.com/beego/beego/v2/client/orm"
+
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/log"
)
var defaultRegistered = false
+var o orm.Ormer
// PrepareTestForMySQL is for test only.
func PrepareTestForMySQL() {
@@ -72,13 +75,14 @@ func PrepareTestForPostgresSQL() {
}
log.Infof("POSTGRES_HOST: %s, POSTGRES_USR: %s, POSTGRES_PORT: %d, POSTGRES_PWD: %s\n", dbHost, dbUser, dbPort, dbPassword)
- initDatabaseForTest(database)
+ o = initDatabaseForTest(database)
}
-func initDatabaseForTest(db *models.Database) {
+func initDatabaseForTest(db *models.Database) orm.Ormer {
database, err := getDatabase(db)
if err != nil {
- panic(err)
+ log.Fatal(err)
+ return nil
}
log.Infof("initializing database: %s", database.String())
@@ -89,17 +93,18 @@ func initDatabaseForTest(db *models.Database) {
alias = "default"
}
if err := database.Register(alias); err != nil {
- panic(err)
+ log.Fatal(err)
+ return nil
}
if err := database.UpgradeSchema(); err != nil {
- panic(err)
+ log.Fatal(err)
+ return nil
}
if alias != "default" {
- if err = GetOrmer().Using(alias); err != nil {
- log.Fatalf("failed to create new orm: %v", err)
- }
+ return orm.NewOrmUsingDB(alias)
}
+ return GetOrmer()
}
// PrepareTestData -- Clean and Create data
diff --git a/src/common/models/base.go b/src/common/models/base.go
index 45720443f..4380c78e2 100644
--- a/src/common/models/base.go
+++ b/src/common/models/base.go
@@ -15,7 +15,7 @@
package models
import (
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/controller/event/handler/internal/artifact_test.go b/src/controller/event/handler/internal/artifact_test.go
index eb6fa7925..07887e22b 100644
--- a/src/controller/event/handler/internal/artifact_test.go
+++ b/src/controller/event/handler/internal/artifact_test.go
@@ -19,7 +19,7 @@ import (
"testing"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
common_dao "github.com/goharbor/harbor/src/common/dao"
diff --git a/src/controller/event/handler/webhook/scan/scan.go b/src/controller/event/handler/webhook/scan/scan.go
index 64f666094..ee3c56ad7 100644
--- a/src/controller/event/handler/webhook/scan/scan.go
+++ b/src/controller/event/handler/webhook/scan/scan.go
@@ -18,7 +18,7 @@ import (
"context"
"time"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/event"
diff --git a/src/controller/health/checker.go b/src/controller/health/checker.go
index 45f53d554..0843cf4f0 100644
--- a/src/controller/health/checker.go
+++ b/src/controller/health/checker.go
@@ -23,7 +23,7 @@ import (
"sync"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/docker/distribution/health"
httputil "github.com/goharbor/harbor/src/common/http"
diff --git a/src/core/api/base.go b/src/core/api/base.go
index 273d06cb8..ce8b5430c 100644
--- a/src/core/api/base.go
+++ b/src/core/api/base.go
@@ -137,7 +137,11 @@ func (b *BaseController) SendPermissionError() {
// WriteJSONData writes the JSON data to the client.
func (b *BaseController) WriteJSONData(object interface{}) {
b.Data["json"] = object
- b.ServeJSON()
+ if err := b.ServeJSON(); err != nil {
+ log.Errorf("failed to serve json, %v", err)
+ b.SendInternalServerError(err)
+ return
+ }
}
// WriteYamlData writes the yaml data to the client.
@@ -162,7 +166,11 @@ func (b *BaseController) PopulateUserSession(u models.User) {
b.SendError(err)
return
}
- b.SetSession(userSessionKey, u)
+ if err := b.SetSession(userSessionKey, u); err != nil {
+ log.Errorf("failed to set user into session, error: %v", err)
+ b.SendError(err)
+ return
+ }
}
// Init related objects/configurations for the API controllers
diff --git a/src/core/api/chart_repository_test.go b/src/core/api/chart_repository_test.go
index 48fe9b9e4..fc3a66862 100644
--- a/src/core/api/chart_repository_test.go
+++ b/src/core/api/chart_repository_test.go
@@ -7,7 +7,7 @@ import (
"net/http/httptest"
"testing"
- bcontext "github.com/beego/beego/context"
+ bcontext "github.com/beego/beego/v2/server/web/context"
"github.com/goharbor/harbor/src/chartserver"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
diff --git a/src/core/api/harborapi_test.go b/src/core/api/harborapi_test.go
index 7c9cd08d9..fe35bc898 100644
--- a/src/core/api/harborapi_test.go
+++ b/src/core/api/harborapi_test.go
@@ -22,7 +22,7 @@ import (
"path/filepath"
"runtime"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/dghubble/sling"
"github.com/goharbor/harbor/src/common/api"
@@ -84,31 +84,31 @@ func init() {
dir := filepath.Dir(file)
dir = filepath.Join(dir, "..")
apppath, _ := filepath.Abs(dir)
- beego.BConfig.WebConfig.Session.SessionOn = true
- beego.TestBeegoInit(apppath)
+ web.BConfig.WebConfig.Session.SessionOn = true
+ web.TestBeegoInit(apppath)
// Charts are controlled under projects
chartRepositoryAPIType := &ChartRepositoryAPI{}
- beego.Router("/api/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus")
- beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts")
- beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions")
- beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart")
- beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion")
- beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion")
- beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
- beego.Router("/api/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile")
- beego.Router("/api/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
+ web.Router("/api/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus")
+ web.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts")
+ web.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions")
+ web.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart")
+ web.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion")
+ web.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion")
+ web.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
+ web.Router("/api/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile")
+ web.Router("/api/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
// Repository services
- beego.Router("/chartrepo/:repo/index.yaml", chartRepositoryAPIType, "get:GetIndexByRepo")
- beego.Router("/chartrepo/index.yaml", chartRepositoryAPIType, "get:GetIndex")
- beego.Router("/chartrepo/:repo/charts/:filename", chartRepositoryAPIType, "get:DownloadChart")
+ web.Router("/chartrepo/:repo/index.yaml", chartRepositoryAPIType, "get:GetIndexByRepo")
+ web.Router("/chartrepo/index.yaml", chartRepositoryAPIType, "get:GetIndex")
+ web.Router("/chartrepo/:repo/charts/:filename", chartRepositoryAPIType, "get:DownloadChart")
// Labels for chart
chartLabelAPIType := &ChartLabelAPI{}
- beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version/labels", chartLabelAPIType, "get:GetLabels;post:MarkLabel")
- beego.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version/labels/:id([0-9]+)", chartLabelAPIType, "delete:RemoveLabel")
+ web.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version/labels", chartLabelAPIType, "get:GetLabels;post:MarkLabel")
+ web.Router("/api/"+api.APIVersion+"/chartrepo/:repo/charts/:name/:version/labels/:id([0-9]+)", chartLabelAPIType, "delete:RemoveLabel")
- beego.Router("/api/internal/syncquota", &InternalAPI{}, "post:SyncQuota")
+ web.Router("/api/internal/syncquota", &InternalAPI{}, "post:SyncQuota")
// Init user Info
admin = &usrInfo{adminName, adminPwd}
@@ -120,7 +120,7 @@ func init() {
defer mockServer.Close()
chain := middleware.Chain(orm.Middleware(), security.Middleware(), security.UnauthorizedMiddleware())
- handler = chain(beego.BeeApp.Handlers)
+ handler = chain(web.BeeApp.Handlers)
}
func request0(_sling *sling.Sling, acceptHeader string, authInfo ...usrInfo) (int, http.Header, []byte, error) {
diff --git a/src/core/api/internal.go b/src/core/api/internal.go
index e804e6452..db0ea6b0b 100644
--- a/src/core/api/internal.go
+++ b/src/core/api/internal.go
@@ -17,7 +17,7 @@ package api
import (
"context"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/models"
@@ -66,7 +66,10 @@ func (ia *InternalAPI) RenameAdmin() {
return
}
log.Debugf("The super user has been renamed to: %s", newName)
- ia.DestroySession()
+ if err := ia.DestroySession(); err != nil {
+ log.Errorf("failed to destroy session for admin user, error: %v", err)
+ return
+ }
}
// SyncQuota ...
diff --git a/src/core/api/label_resource.go b/src/core/api/label_resource.go
index 01eec065b..86e985327 100644
--- a/src/core/api/label_resource.go
+++ b/src/core/api/label_resource.go
@@ -6,6 +6,7 @@ import (
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/core/label"
+ "github.com/goharbor/harbor/src/lib/log"
pkg_label "github.com/goharbor/harbor/src/pkg/label"
"github.com/goharbor/harbor/src/pkg/label/model"
)
@@ -34,7 +35,11 @@ func (lra *LabelResourceAPI) getLabelsOfResource(rType string, rIDOrName interfa
}
lra.Data["json"] = labels
- lra.ServeJSON()
+ if err := lra.ServeJSON(); err != nil {
+ log.Errorf("failed to serve json, %v", err)
+ lra.handleErrors(err)
+ return
+ }
}
func (lra *LabelResourceAPI) markLabelToResource(rl *models.ResourceLabel) {
diff --git a/src/core/controllers/base.go b/src/core/controllers/base.go
index 3dd09fe46..800122192 100644
--- a/src/core/controllers/base.go
+++ b/src/core/controllers/base.go
@@ -20,7 +20,7 @@ import (
"os"
"strings"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/beego/i18n"
"github.com/goharbor/harbor/src/common"
@@ -110,7 +110,10 @@ func (cc *CommonController) Login() {
// LogOut Habor UI
func (cc *CommonController) LogOut() {
- cc.DestroySession()
+ if err := cc.DestroySession(); err != nil {
+ log.Errorf("Error occurred in LogOut: %v", err)
+ cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
+ }
}
// UserExists checks if user exists when user input value in sign in form.
@@ -143,7 +146,10 @@ func (cc *CommonController) UserExists() {
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
cc.Data["json"] = n > 0
- cc.ServeJSON()
+ if err := cc.ServeJSON(); err != nil {
+ log.Errorf("failed to serve json: %v", err)
+ cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
+ }
}
func init() {
@@ -151,7 +157,7 @@ func init() {
configPath := os.Getenv("CONFIG_PATH")
if len(configPath) != 0 {
log.Infof("Config path: %s", configPath)
- if err := beego.LoadAppConfig("ini", configPath); err != nil {
+ if err := web.LoadAppConfig("ini", configPath); err != nil {
log.Errorf("failed to load app config: %v", err)
}
}
diff --git a/src/core/controllers/controllers_test.go b/src/core/controllers/controllers_test.go
index 1467399b5..f59439a41 100644
--- a/src/core/controllers/controllers_test.go
+++ b/src/core/controllers/controllers_test.go
@@ -23,7 +23,7 @@ import (
"strings"
"testing"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/stretchr/testify/assert"
"github.com/goharbor/harbor/src/common"
@@ -41,13 +41,13 @@ func init() {
dir := filepath.Dir(file)
dir = filepath.Join(dir, "..")
apppath, _ := filepath.Abs(dir)
- beego.BConfig.WebConfig.Session.SessionOn = true
- beego.TestBeegoInit(apppath)
- beego.AddTemplateExt("htm")
+ web.BConfig.WebConfig.Session.SessionOn = true
+ web.TestBeegoInit(apppath)
+ web.AddTemplateExt("htm")
- beego.Router("/c/login", &CommonController{}, "post:Login")
- beego.Router("/c/log_out", &CommonController{}, "get:LogOut")
- beego.Router("/c/userExists", &CommonController{}, "post:UserExists")
+ web.Router("/c/login", &CommonController{}, "post:Login")
+ web.Router("/c/log_out", &CommonController{}, "get:LogOut")
+ web.Router("/c/userExists", &CommonController{}, "post:UserExists")
}
func TestMain(m *testing.M) {
@@ -71,7 +71,7 @@ func TestRedirectForOIDC(t *testing.T) {
func TestAll(t *testing.T) {
config.InitWithSettings(utilstest.GetUnitTestConfig())
assert := assert.New(t)
- handler := http.Handler(beego.BeeApp.Handlers)
+ handler := http.Handler(web.BeeApp.Handlers)
mws := middlewares.MiddleWares()
for i := len(mws) - 1; i >= 0; i-- {
if mws[i] == nil {
diff --git a/src/core/controllers/error.go b/src/core/controllers/error.go
index a5aa37056..644977423 100644
--- a/src/core/controllers/error.go
+++ b/src/core/controllers/error.go
@@ -15,12 +15,12 @@
package controllers
import (
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
)
// ErrorController handles beego error pages
type ErrorController struct {
- beego.Controller
+ web.Controller
}
// Error404 renders the 404 page
diff --git a/src/core/controllers/oidc.go b/src/core/controllers/oidc.go
index 14d0dc34e..1f4f040b3 100644
--- a/src/core/controllers/oidc.go
+++ b/src/core/controllers/oidc.go
@@ -63,8 +63,16 @@ func (oc *OIDCController) RedirectLogin() {
oc.SendInternalServerError(err)
return
}
- oc.SetSession(redirectURLKey, oc.Ctx.Request.URL.Query().Get("redirect_url"))
- oc.SetSession(stateKey, state)
+ if err := oc.SetSession(redirectURLKey, oc.Ctx.Request.URL.Query().Get("redirect_url")); err != nil {
+ log.Errorf("failed to set session for key: %s, error: %v", redirectURLKey, err)
+ oc.SendInternalServerError(err)
+ return
+ }
+ if err := oc.SetSession(stateKey, state); err != nil {
+ log.Errorf("failed to set session for key: %s, error: %v", stateKey, err)
+ oc.SendInternalServerError(err)
+ return
+ }
log.Debugf("State dumped to session: %s", state)
// Force to use the func 'Redirect' of beego.Controller
oc.Controller.Redirect(url, http.StatusFound)
@@ -91,7 +99,11 @@ func (oc *OIDCController) Callback() {
redirectURL := oc.GetSession(redirectURLKey)
if redirectURL != nil {
redirectURLStr = redirectURL.(string)
- oc.DelSession(redirectURLKey)
+ if err := oc.DelSession(redirectURLKey); err != nil {
+ log.Errorf("failed to delete session for key:%s, error: %v", redirectURLKey, err)
+ oc.SendInternalServerError(err)
+ return
+ }
}
code := oc.Ctx.Request.URL.Query().Get("code")
ctx := oc.Ctx.Request.Context()
@@ -122,7 +134,11 @@ func (oc *OIDCController) Callback() {
oc.SendInternalServerError(err)
return
}
- oc.SetSession(tokenKey, tokenBytes)
+ if err := oc.SetSession(tokenKey, tokenBytes); err != nil {
+ log.Errorf("failed to set session for key: %s, error: %v", tokenKey, err)
+ oc.SendInternalServerError(err)
+ return
+ }
u, err := ctluser.Ctl.GetBySubIss(ctx, info.Subject, info.Issuer)
if errors.IsNotFoundErr(err) { // User is not onboarded, kickoff the onboard flow
// Recover the username from d.Username by default
@@ -150,7 +166,11 @@ func (oc *OIDCController) Callback() {
log.Debug("User automatically onboarded\n")
u = userRec
} else {
- oc.SetSession(userInfoKey, string(ouDataStr))
+ if err := oc.SetSession(userInfoKey, string(ouDataStr)); err != nil {
+ log.Errorf("failed to set session for key: %s, error: %v", userInfoKey, err)
+ oc.SendInternalServerError(err)
+ return
+ }
oc.Controller.Redirect(fmt.Sprintf("/oidc-onboard?username=%s&redirect_url=%s", username, redirectURLStr), http.StatusFound)
// Once redirected, no further actions are done
return
@@ -253,7 +273,11 @@ func (oc *OIDCController) Onboard() {
ctx := oc.Ctx.Request.Context()
if user, onboarded := userOnboard(ctx, oc, d, username, tb); onboarded {
user.OIDCUserMeta = nil
- oc.DelSession(userInfoKey)
+ if err := oc.DelSession(userInfoKey); err != nil {
+ log.Errorf("failed to delete session for key:%s, error: %v", userInfoKey, err)
+ oc.SendInternalServerError(err)
+ return
+ }
oc.PopulateUserSession(*user)
}
}
diff --git a/src/core/main.go b/src/core/main.go
index bcb59c02c..2f97034d4 100755
--- a/src/core/main.go
+++ b/src/core/main.go
@@ -26,7 +26,7 @@ import (
"syscall"
"time"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/goharbor/harbor/src/common/dao"
common_http "github.com/goharbor/harbor/src/common/http"
@@ -120,8 +120,10 @@ func main() {
runMode := flag.String("mode", "normal", "The harbor-core container run mode, it could be normal, migrate or skip-migrate, default is normal")
flag.Parse()
- beego.BConfig.WebConfig.Session.SessionOn = true
- beego.BConfig.WebConfig.Session.SessionName = config.SessionCookieName
+ web.BConfig.WebConfig.Session.SessionOn = true
+ web.BConfig.WebConfig.Session.SessionName = config.SessionCookieName
+ web.BConfig.MaxMemory = 1 << 35 // (32GB)
+ web.BConfig.MaxUploadSize = 1 << 35 // (32GB)
redisURL := os.Getenv("_REDIS_URL_CORE")
if len(redisURL) > 0 {
@@ -130,8 +132,8 @@ func main() {
panic("bad _REDIS_URL")
}
- beego.BConfig.WebConfig.Session.SessionProvider = session.HarborProviderName
- beego.BConfig.WebConfig.Session.SessionProviderConfig = redisURL
+ web.BConfig.WebConfig.Session.SessionProvider = session.HarborProviderName
+ web.BConfig.WebConfig.Session.SessionProviderConfig = redisURL
log.Info("initializing cache ...")
if err := cache.Initialize(u.Scheme, redisURL); err != nil {
@@ -141,7 +143,7 @@ func main() {
// enable config cache explicitly when the cache is ready
dbCfg.EnableConfigCache()
}
- beego.AddTemplateExt("htm")
+ web.AddTemplateExt("htm")
log.Info("initializing configurations...")
config.Init()
@@ -223,12 +225,12 @@ func main() {
iTLSCertPath := os.Getenv("INTERNAL_TLS_CERT_PATH")
log.Infof("load client key: %s client cert: %s", iTLSKeyPath, iTLSCertPath)
- beego.BConfig.Listen.EnableHTTP = false
- beego.BConfig.Listen.EnableHTTPS = true
- beego.BConfig.Listen.HTTPSPort = 8443
- beego.BConfig.Listen.HTTPSKeyFile = iTLSKeyPath
- beego.BConfig.Listen.HTTPSCertFile = iTLSCertPath
- beego.BeeApp.Server.TLSConfig = common_http.NewServerTLSConfig()
+ web.BConfig.Listen.EnableHTTP = false
+ web.BConfig.Listen.EnableHTTPS = true
+ web.BConfig.Listen.HTTPSPort = 8443
+ web.BConfig.Listen.HTTPSKeyFile = iTLSKeyPath
+ web.BConfig.Listen.HTTPSCertFile = iTLSCertPath
+ web.BeeApp.Server.TLSConfig = common_http.NewServerTLSConfig()
}
log.Infof("Version: %s, Git commit: %s", version.ReleaseVersion, version.GitCommit)
@@ -257,7 +259,7 @@ func main() {
}
systemartifact.ScheduleCleanupTask(ctx)
}()
- beego.RunWithMiddleWares("", middlewares.MiddleWares()...)
+ web.RunWithMiddleWares("", middlewares.MiddleWares()...)
}
const (
diff --git a/src/core/middlewares/middlewares.go b/src/core/middlewares/middlewares.go
index 2e85b2a4d..62a1c13d2 100644
--- a/src/core/middlewares/middlewares.go
+++ b/src/core/middlewares/middlewares.go
@@ -18,7 +18,7 @@ import (
"net/http"
"regexp"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/goharbor/harbor/src/pkg/distribution"
"github.com/goharbor/harbor/src/server/middleware"
@@ -79,8 +79,8 @@ var (
)
// MiddleWares returns global middlewares
-func MiddleWares() []beego.MiddleWare {
- return []beego.MiddleWare{
+func MiddleWares() []web.MiddleWare {
+ return []web.MiddleWare{
url.Middleware(),
mergeslash.Middleware(),
trace.Middleware(),
diff --git a/src/core/service/token/token.go b/src/core/service/token/token.go
index f0f817d26..b2cd40ae5 100644
--- a/src/core/service/token/token.go
+++ b/src/core/service/token/token.go
@@ -19,14 +19,14 @@ import (
"html/template"
"net/http"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/goharbor/harbor/src/lib/log"
)
// Handler handles request on /service/token, which is the auth provider for registry.
type Handler struct {
- beego.Controller
+ web.Controller
}
// Get handles GET request, it checks the http header for user credentials
@@ -51,5 +51,8 @@ func (h *Handler) Get() {
h.CustomAbort(http.StatusInternalServerError, "")
}
h.Data["json"] = token
- h.ServeJSON()
+ if err := h.ServeJSON(); err != nil {
+ log.Errorf("failed to serve json on /service/token, %v", err)
+ h.CustomAbort(http.StatusInternalServerError, "")
+ }
}
diff --git a/src/core/session/codec.go b/src/core/session/codec.go
index fac99fd99..4fc10c044 100644
--- a/src/core/session/codec.go
+++ b/src/core/session/codec.go
@@ -17,7 +17,7 @@ package session
import (
"encoding/gob"
- "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/server/web/session"
commonmodels "github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/lib/cache"
diff --git a/src/core/session/session.go b/src/core/session/session.go
index bca0c2f72..80d4b389c 100644
--- a/src/core/session/session.go
+++ b/src/core/session/session.go
@@ -21,7 +21,7 @@ import (
"sync"
"time"
- "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/server/web/session"
goredis "github.com/go-redis/redis/v8"
"github.com/goharbor/harbor/src/lib/cache"
@@ -47,7 +47,7 @@ type Store struct {
}
// Set value in redis session
-func (rs *Store) Set(key, value interface{}) error {
+func (rs *Store) Set(ctx context.Context, key, value interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values[key] = value
@@ -55,7 +55,7 @@ func (rs *Store) Set(key, value interface{}) error {
}
// Get value in redis session
-func (rs *Store) Get(key interface{}) interface{} {
+func (rs *Store) Get(ctx context.Context, key interface{}) interface{} {
rs.lock.RLock()
defer rs.lock.RUnlock()
if v, ok := rs.values[key]; ok {
@@ -65,7 +65,7 @@ func (rs *Store) Get(key interface{}) interface{} {
}
// Delete value in redis session
-func (rs *Store) Delete(key interface{}) error {
+func (rs *Store) Delete(ctx context.Context, key interface{}) error {
rs.lock.Lock()
defer rs.lock.Unlock()
delete(rs.values, key)
@@ -73,7 +73,7 @@ func (rs *Store) Delete(key interface{}) error {
}
// Flush clear all values in redis session
-func (rs *Store) Flush() error {
+func (rs *Store) Flush(ctx context.Context) error {
rs.lock.Lock()
defer rs.lock.Unlock()
rs.values = make(map[interface{}]interface{})
@@ -81,18 +81,20 @@ func (rs *Store) Flush() error {
}
// SessionID get redis session id
-func (rs *Store) SessionID() string {
+func (rs *Store) SessionID(ctx context.Context) string {
return rs.sid
}
// SessionRelease save session values to redis
-func (rs *Store) SessionRelease(w http.ResponseWriter) {
+func (rs *Store) SessionRelease(ctx context.Context, w http.ResponseWriter) {
b, err := session.EncodeGob(rs.values)
if err != nil {
return
}
- ctx := context.TODO()
+ if ctx == nil {
+ ctx = context.TODO()
+ }
maxlifetime := time.Duration(systemSessionTimeout(ctx, rs.maxlifetime))
if rdb, ok := rs.c.(*redis.Cache); ok {
cmd := rdb.Client.Set(ctx, rs.sid, string(b), maxlifetime)
@@ -109,20 +111,26 @@ type Provider struct {
}
// SessionInit init redis session
-func (rp *Provider) SessionInit(maxlifetime int64, url string) (err error) {
+func (rp *Provider) SessionInit(ctx context.Context, maxlifetime int64, url string) (err error) {
rp.maxlifetime = maxlifetime * int64(time.Second)
rp.c, err = redis.New(cache.Options{Address: url, Codec: codec})
if err != nil {
return err
}
- return rp.c.Ping(context.TODO())
+ if ctx == nil {
+ ctx = context.TODO()
+ }
+ return rp.c.Ping(ctx)
}
// SessionRead read redis session by sid
-func (rp *Provider) SessionRead(sid string) (session.Store, error) {
+func (rp *Provider) SessionRead(ctx context.Context, sid string) (session.Store, error) {
kv := make(map[interface{}]interface{})
- err := rp.c.Fetch(context.TODO(), sid, &kv)
+ if ctx == nil {
+ ctx = context.TODO()
+ }
+ err := rp.c.Fetch(ctx, sid, &kv)
if err != nil && !strings.Contains(err.Error(), goredis.Nil.Error()) {
return nil, err
}
@@ -132,16 +140,21 @@ func (rp *Provider) SessionRead(sid string) (session.Store, error) {
}
// SessionExist check redis session exist by sid
-func (rp *Provider) SessionExist(sid string) bool {
- return rp.c.Contains(context.TODO(), sid)
+func (rp *Provider) SessionExist(ctx context.Context, sid string) (bool, error) {
+ if ctx == nil {
+ ctx = context.TODO()
+ }
+ return rp.c.Contains(ctx, sid), nil
}
// SessionRegenerate generate new sid for redis session
-func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
- ctx := context.TODO()
+func (rp *Provider) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
+ if ctx == nil {
+ ctx = context.TODO()
+ }
maxlifetime := time.Duration(systemSessionTimeout(ctx, rp.maxlifetime))
- if !rp.SessionExist(oldsid) {
- err := rp.c.Save(ctx, sid, "", maxlifetime)
+ if isExist, _ := rp.SessionExist(ctx, oldsid); !isExist {
+ err := rp.c.Save(ctx, sid, "", time.Duration(rp.maxlifetime))
if err != nil {
log.Debugf("failed to save sid=%s, where oldsid=%s, error: %s", sid, oldsid, err)
}
@@ -168,20 +181,23 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error)
}
}
- return rp.SessionRead(sid)
+ return rp.SessionRead(ctx, sid)
}
// SessionDestroy delete redis session by id
-func (rp *Provider) SessionDestroy(sid string) error {
- return rp.c.Delete(context.TODO(), sid)
+func (rp *Provider) SessionDestroy(ctx context.Context, sid string) error {
+ if ctx == nil {
+ ctx = context.TODO()
+ }
+ return rp.c.Delete(ctx, sid)
}
// SessionGC Implement method, no used.
-func (rp *Provider) SessionGC() {
+func (rp *Provider) SessionGC(ctx context.Context) {
}
// SessionAll return all activeSession
-func (rp *Provider) SessionAll() int {
+func (rp *Provider) SessionAll(ctx context.Context) int {
return 0
}
diff --git a/src/core/session/session_test.go b/src/core/session/session_test.go
index 85b0c2e81..41bc0d41a 100644
--- a/src/core/session/session_test.go
+++ b/src/core/session/session_test.go
@@ -15,9 +15,10 @@
package session
import (
+ "context"
"testing"
- "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/server/web/session"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/lib/config"
@@ -39,78 +40,83 @@ func (s *sessionTestSuite) SetupSuite() {
s.NoError(err, "should get harbor provider")
s.NotNil(s.provider, "provider should not nil")
- err = s.provider.SessionInit(3600, "redis://127.0.0.1:6379/0")
+ err = s.provider.SessionInit(context.Background(), 3600, "redis://127.0.0.1:6379/0")
s.NoError(err, "session init should not error")
}
func (s *sessionTestSuite) TestSessionRead() {
- store, err := s.provider.SessionRead("session-001")
+ store, err := s.provider.SessionRead(context.Background(), "session-001")
s.NoError(err, "session read should not error")
s.NotNil(store)
}
func (s *sessionTestSuite) TestSessionExist() {
// prepare session
- store, err := s.provider.SessionRead("session-001")
+ ctx := context.Background()
+ store, err := s.provider.SessionRead(ctx, "session-001")
s.NoError(err, "session read should not error")
s.NotNil(store)
- store.SessionRelease(nil)
+ store.SessionRelease(context.Background(), nil)
defer func() {
// clean session
- err = s.provider.SessionDestroy("session-001")
+ err = s.provider.SessionDestroy(ctx, "session-001")
s.NoError(err)
}()
- exist := s.provider.SessionExist("session-001")
+ exist, _ := s.provider.SessionExist(ctx, "session-001")
s.True(exist, "session-001 should exist")
- exist = s.provider.SessionExist("session-002")
+ exist, _ = s.provider.SessionExist(ctx, "session-002")
s.False(exist, "session-002 should not exist")
}
func (s *sessionTestSuite) TestSessionRegenerate() {
// prepare session
- store, err := s.provider.SessionRead("session-001")
+ ctx := context.Background()
+ store, err := s.provider.SessionRead(ctx, "session-001")
s.NoError(err, "session read should not error")
s.NotNil(store)
- store.SessionRelease(nil)
+ store.SessionRelease(ctx, nil)
defer func() {
// clean session
- err = s.provider.SessionDestroy("session-001")
+ err = s.provider.SessionDestroy(ctx, "session-001")
s.NoError(err)
- err = s.provider.SessionDestroy("session-003")
+ err = s.provider.SessionDestroy(ctx, "session-003")
s.NoError(err)
}()
- _, err = s.provider.SessionRegenerate("session-001", "session-003")
+ _, err = s.provider.SessionRegenerate(ctx, "session-001", "session-003")
s.NoError(err, "session regenerate should not error")
- s.True(s.provider.SessionExist("session-003"))
- s.False(s.provider.SessionExist("session-001"))
+ s.True(s.provider.SessionExist(ctx, "session-003"))
+ s.False(s.provider.SessionExist(ctx, "session-001"))
}
func (s *sessionTestSuite) TestSessionDestroy() {
// prepare session
- store, err := s.provider.SessionRead("session-004")
+ ctx := context.Background()
+ store, err := s.provider.SessionRead(ctx, "session-004")
s.NoError(err, "session read should not error")
s.NotNil(store)
- store.SessionRelease(nil)
- s.True(s.provider.SessionExist("session-004"), "session-004 should exist")
+ store.SessionRelease(ctx, nil)
+ isExist, _ := s.provider.SessionExist(ctx, "session-004")
+ s.True(isExist, "session-004 should exist")
- err = s.provider.SessionDestroy("session-004")
+ err = s.provider.SessionDestroy(ctx, "session-004")
s.NoError(err, "session destroy should not error")
- s.False(s.provider.SessionExist("session-004"), "session-004 should not exist")
+ isExist, _ = s.provider.SessionExist(ctx, "session-004")
+ s.False(isExist, "session-004 should not exist")
}
func (s *sessionTestSuite) TestSessionGC() {
- s.provider.SessionGC()
+ s.provider.SessionGC(context.Background())
}
func (s *sessionTestSuite) TestSessionAll() {
- c := s.provider.SessionAll()
+ c := s.provider.SessionAll(context.Background())
s.Equal(0, c)
}
diff --git a/src/go.mod b/src/go.mod
index f9ff97699..245baf000 100644
--- a/src/go.mod
+++ b/src/go.mod
@@ -10,7 +10,7 @@ require (
github.com/aws/aws-sdk-go v1.34.28
github.com/beego/i18n v0.0.0-20140604031826-e87155e8f0c0
github.com/bmatcuk/doublestar v1.1.1
- github.com/casbin/casbin v1.7.0
+ github.com/casbin/casbin v1.9.1
github.com/cenkalti/backoff/v4 v4.1.2
github.com/coreos/go-oidc/v3 v3.0.0
github.com/dghubble/sling v1.1.0
@@ -27,7 +27,7 @@ require (
github.com/go-openapi/swag v0.19.14
github.com/go-openapi/validate v0.19.10
github.com/go-redis/redis/v8 v8.11.4
- github.com/go-sql-driver/mysql v1.5.0
+ github.com/go-sql-driver/mysql v1.6.0
github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8
github.com/gocraft/work v0.5.1
github.com/golang-jwt/jwt/v4 v4.2.0
@@ -59,11 +59,11 @@ require (
github.com/vmihailenco/msgpack/v5 v5.0.0-rc.2
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.22.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.22.0
- go.opentelemetry.io/otel v1.3.0
+ go.opentelemetry.io/otel v1.8.0
go.opentelemetry.io/otel/exporters/jaeger v1.0.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0
- go.opentelemetry.io/otel/sdk v1.3.0
- go.opentelemetry.io/otel/trace v1.3.0
+ go.opentelemetry.io/otel/sdk v1.8.0
+ go.opentelemetry.io/otel/trace v1.8.0
go.uber.org/ratelimit v0.2.0
golang.org/x/crypto v0.1.0
golang.org/x/net v0.1.0
@@ -78,7 +78,7 @@ require (
)
require (
- github.com/beego/beego v1.12.11
+ github.com/beego/beego/v2 v2.0.6
golang.org/x/text v0.4.0
)
@@ -165,7 +165,7 @@ require (
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
- github.com/mitchellh/mapstructure v1.4.1 // indirect
+ github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
@@ -182,7 +182,7 @@ require (
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
- github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
+ github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
diff --git a/src/go.sum b/src/go.sum
index 160085e33..d5fcd1593 100644
--- a/src/go.sum
+++ b/src/go.sum
@@ -83,7 +83,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/FZambia/sentinel v1.1.0 h1:qrCBfxc8SvJihYNjBWgwUI93ZCvFe/PJIPTHKmlp8a8=
github.com/FZambia/sentinel v1.1.0/go.mod h1:ytL1Am/RLlAoAXG6Kj5LNuw/TRRQrv2rt2FT26vP5gI=
-github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
@@ -134,8 +133,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
-github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
-github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190726115642-cd293c93fd97 h1:bNE5ID4C3YOkROfvBjXJUG53gyb+8az3TQN02LqnGBk=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190726115642-cd293c93fd97/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ=
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
@@ -190,12 +187,10 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
-github.com/beego/beego v1.12.11 h1:MWKcnpavb7iAIS0m6uuEq6pHKkYvGNw/5umIUKqL7jM=
-github.com/beego/beego v1.12.11/go.mod h1:QURFL1HldOcCZAxnc1cZ7wrplsYR5dKPHFjmk6WkLAs=
-github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
+github.com/beego/beego/v2 v2.0.6 h1:21Aqz3+RzUE1yP9a5xdU6LK54n9Z7NLEJtR4PE7NrPQ=
+github.com/beego/beego/v2 v2.0.6/go.mod h1:CH2/JIaB4ceGYVQlYqTAFft4pVk/ol1ZkakUrUvAyns=
github.com/beego/i18n v0.0.0-20140604031826-e87155e8f0c0 h1:fQaDnUQvBXHHQdGBu9hz8nPznB4BeiPQokvmQVjmNEw=
github.com/beego/i18n v0.0.0-20140604031826-e87155e8f0c0/go.mod h1:KLeFCpAMq2+50NkXC8iiJxLLiiTfTqrGtKEVm+2fk7s=
-github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -211,15 +206,14 @@ github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTS
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
-github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bugsnag/bugsnag-go v1.5.2 h1:fdaGJJEReigPzSE6HajOhpJwE2IEP/TdHDHXKGeOJtc=
github.com/bugsnag/bugsnag-go v1.5.2/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA=
github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
-github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ=
-github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
+github.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=
+github.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
@@ -362,9 +356,6 @@ github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/couchbase/go-couchbase v0.0.0-20201216133707-c04035124b17/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
-github.com/couchbase/gomemcached v0.1.2-0.20201224031647-c432ccf49f32/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo=
-github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -372,7 +363,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
@@ -432,9 +422,7 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
-github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
-github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
-github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
+github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
@@ -475,7 +463,6 @@ github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmx
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
@@ -578,13 +565,13 @@ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2K
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
github.com/go-openapi/validate v0.19.10 h1:tG3SZ5DC5KF4cyt7nqLVcQXGj5A7mpaYkAcNPlDK+Yk=
github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8=
-github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
@@ -949,7 +936,6 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
-github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@@ -996,8 +982,7 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
-github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
-github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
@@ -1018,8 +1003,9 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
+github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@@ -1136,7 +1122,6 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
-github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
@@ -1146,7 +1131,6 @@ github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
@@ -1172,7 +1156,6 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
-github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
@@ -1238,16 +1221,13 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
-github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
-github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
+github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
+github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
-github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
-github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
-github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -1292,7 +1272,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
-github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@@ -1319,7 +1298,6 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tencentcloud/tencentcloud-sdk-go v1.0.62 h1:Vnr3IqaafEuQUciG6D6EaeLJm26Mg8sjAfbI4OoeauM=
github.com/tencentcloud/tencentcloud-sdk-go v1.0.62/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI=
@@ -1329,7 +1307,6 @@ github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
@@ -1345,7 +1322,6 @@ github.com/vmihailenco/msgpack/v5 v5.0.0-rc.2 h1:ognci8XPlosGhIHK1OLYSpSpnlhSFeB
github.com/vmihailenco/msgpack/v5 v5.0.0-rc.2/go.mod h1:HVxBVPUK/+fZMonk4bi1islLa8V3cfnBug0+4dykPzo=
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
-github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
@@ -1371,7 +1347,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=
@@ -1411,8 +1386,9 @@ go.opentelemetry.io/contrib/propagators v0.22.0/go.mod h1:xGOuXr6lLIF9BXipA4pm6U
go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I=
go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
-go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
+go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg=
+go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
go.opentelemetry.io/otel/exporters/jaeger v1.0.0 h1:cLhx8llHw02h5JTqGqaRbYn+QVKHmrzD9vEbKnSPk5U=
go.opentelemetry.io/otel/exporters/jaeger v1.0.0/go.mod h1:q10N1AolE1JjqKrFJK2tYw0iZpmX+HBaXBtuCzRnBGQ=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0 h1:R/OBkMoGgfy2fLhs2QhkCI1w4HLEQX92GCcJB6SSdNk=
@@ -1429,13 +1405,15 @@ go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1G
go.opentelemetry.io/otel/oteltest v1.0.0-RC2 h1:xNKqMhlZYkASSyvF4JwObZFMq0jhFN3c3SP+2rCzVPk=
go.opentelemetry.io/otel/oteltest v1.0.0-RC2/go.mod h1:kiQ4tw5tAL4JLTbcOYwK1CWI1HkT5aiLzHovgOVnz/A=
go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
-go.opentelemetry.io/otel/sdk v1.3.0 h1:3278edCoH89MEJ0Ky8WQXVmDQv3FX4ZJ3Pp+9fJreAI=
go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
+go.opentelemetry.io/otel/sdk v1.8.0 h1:xwu69/fNuwbSHWe/0PGS888RmjWY181OmcXDQKu7ZQk=
+go.opentelemetry.io/otel/sdk v1.8.0/go.mod h1:uPSfc+yfDH2StDM/Rm35WE8gXSNdvCg023J6HeGNO0c=
go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg=
go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
-go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
+go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY=
+go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU=
go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ=
@@ -1483,7 +1461,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
-golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -1934,14 +1911,18 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/dancannon/gorethink.v3 v3.0.5 h1:/g7PWP7zUS6vSNmHSDbjCHQh1Rqn8Jy6zSMQxAsBSMQ=
gopkg.in/dancannon/gorethink.v3 v3.0.5/go.mod h1:GXsi1e3N2OcKhcP6nsYABTiUejbWMFO4GY5a4pEaeEc=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fatih/pool.v2 v2.0.0 h1:xIFeWtxifuQJGk/IEPKsTduEKcKvPmhoiVDGpC40nKg=
gopkg.in/fatih/pool.v2 v2.0.0/go.mod h1:8xVGeu1/2jr2wm5V9SPuMht2H5AEmf5aFMGSQixtjTY=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
+gopkg.in/gorethink/gorethink.v3 v3.0.5 h1:e2Uc/Xe+hpcVQFsj6MuHlYog3r0JYpnTzwDj/y2O4MU=
gopkg.in/gorethink/gorethink.v3 v3.0.5/go.mod h1:+3yIIHJUGMBK+wyPH+iN5TP+88ikFDfZdqTlK3Y9q8I=
gopkg.in/h2non/gentleman.v1 v1.0.4/go.mod h1:JYuHVdFzS4MKOXe0o+chKJ4hCe6tqKKw9XH9YP6WFrg=
gopkg.in/h2non/gock.v1 v1.0.16 h1:F11k+OafeuFENsjei5t2vMTSTs9L62AdyTe4E1cgdG8=
@@ -1952,13 +1933,13 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
@@ -1981,8 +1962,10 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg=
gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
+gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
helm.sh/helm/v3 v3.10.1 h1:uTnNlYx8QcTSNA4ZJ50Llwife4CSohUY4ehumyVf2QE=
helm.sh/helm/v3 v3.10.1/go.mod h1:CXOcs02AYvrlPMWARNYNRgf2rNP7gLJQsi/Ubd4EDrI=
diff --git a/src/jobservice/job/impl/context.go b/src/jobservice/job/impl/context.go
index 0a4bf9219..ed4a0beb6 100644
--- a/src/jobservice/job/impl/context.go
+++ b/src/jobservice/job/impl/context.go
@@ -22,7 +22,7 @@ import (
"sync"
"time"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/jobservice/config"
diff --git a/src/jobservice/job/impl/default_context.go b/src/jobservice/job/impl/default_context.go
index 34824df40..9b8da36c7 100644
--- a/src/jobservice/job/impl/default_context.go
+++ b/src/jobservice/job/impl/default_context.go
@@ -18,7 +18,7 @@ import (
"context"
"errors"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/jobservice/job"
"github.com/goharbor/harbor/src/jobservice/logger"
diff --git a/src/jobservice/sync/schedule.go b/src/jobservice/sync/schedule.go
index 5801369c2..67ef3ede9 100644
--- a/src/jobservice/sync/schedule.go
+++ b/src/jobservice/sync/schedule.go
@@ -19,7 +19,7 @@ import (
"fmt"
"time"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/jobservice/config"
"github.com/goharbor/harbor/src/jobservice/env"
diff --git a/src/lib/config/models/model.go b/src/lib/config/models/model.go
index 780c5577e..ad1d1c844 100644
--- a/src/lib/config/models/model.go
+++ b/src/lib/config/models/model.go
@@ -15,7 +15,7 @@
package models
import (
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
// HTTPAuthProxy wraps the settings for HTTP auth proxy
diff --git a/src/lib/orm/creator.go b/src/lib/orm/creator.go
index 5867ff17c..099298b4a 100644
--- a/src/lib/orm/creator.go
+++ b/src/lib/orm/creator.go
@@ -14,7 +14,7 @@
package orm
-import "github.com/beego/beego/orm"
+import "github.com/beego/beego/v2/client/orm"
var (
// Crt is a global instance of ORM creator
diff --git a/src/lib/orm/error.go b/src/lib/orm/error.go
index 1c5cd8aa1..0d8ea034d 100644
--- a/src/lib/orm/error.go
+++ b/src/lib/orm/error.go
@@ -15,7 +15,7 @@
package orm
import (
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/jackc/pgconn"
"github.com/goharbor/harbor/src/lib/errors"
diff --git a/src/lib/orm/error_test.go b/src/lib/orm/error_test.go
index 67e772504..826678ccf 100644
--- a/src/lib/orm/error_test.go
+++ b/src/lib/orm/error_test.go
@@ -17,7 +17,7 @@ package orm
import (
"testing"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/jackc/pgconn"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/src/lib/orm/metadata.go b/src/lib/orm/metadata.go
index 433f38c8a..505aee5c0 100644
--- a/src/lib/orm/metadata.go
+++ b/src/lib/orm/metadata.go
@@ -21,7 +21,7 @@ import (
"sync"
"unicode"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/q"
)
diff --git a/src/lib/orm/metadata_test.go b/src/lib/orm/metadata_test.go
index f00c2f207..87e918692 100644
--- a/src/lib/orm/metadata_test.go
+++ b/src/lib/orm/metadata_test.go
@@ -18,7 +18,7 @@ import (
"context"
"testing"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/src/lib/orm/orm.go b/src/lib/orm/orm.go
index 26ac3bc74..a04d48319 100644
--- a/src/lib/orm/orm.go
+++ b/src/lib/orm/orm.go
@@ -16,15 +16,15 @@ package orm
import (
"context"
- "errors"
"fmt"
"os"
"strconv"
"strings"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
+ "github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
tracelib "github.com/goharbor/harbor/src/lib/trace"
)
@@ -71,8 +71,8 @@ func init() {
}
// FromContext returns orm from context
-func FromContext(ctx context.Context) (orm.Ormer, error) {
- o, ok := ctx.Value(ormKey{}).(orm.Ormer)
+func FromContext(ctx context.Context) (orm.QueryExecutor, error) {
+ o, ok := ctx.Value(ormKey{}).(orm.QueryExecutor)
if !ok {
return nil, errors.New("cannot get the ORM from context")
}
@@ -80,7 +80,7 @@ func FromContext(ctx context.Context) (orm.Ormer, error) {
}
// NewContext returns new context with orm
-func NewContext(ctx context.Context, o orm.Ormer) context.Context {
+func NewContext(ctx context.Context, o orm.QueryExecutor) context.Context {
if ctx == nil {
ctx = context.Background()
}
@@ -105,7 +105,7 @@ func Copy(ctx context.Context) context.Context {
type operationNameKey struct{}
-// SetTransactionOpName sets the transaction operation name
+// SetTransactionOpNameToContext sets the transaction operation name
func SetTransactionOpNameToContext(ctx context.Context, name string) context.Context {
if ctx == nil {
ctx = context.Background()
@@ -136,13 +136,24 @@ func WithTransaction(f func(ctx context.Context) error) func(ctx context.Context
return err
}
- tx := ormerTx{Ormer: o}
+ var tx ormerTx
+ if _, ok := o.(orm.Ormer); ok {
+ tx = ormerTx{Ormer: o.(orm.Ormer)}
+ } else if _, ok := o.(orm.TxOrmer); ok {
+ tx = ormerTx{TxOrmer: o.(orm.TxOrmer)}
+ } else {
+ return errors.New("no orm found in the context")
+ }
+
if err := tx.Begin(); err != nil {
tracelib.RecordError(span, err, "begin transaction failed")
log.Errorf("begin transaction failed: %v", err)
return err
}
+ // When set multiple times, context.WithValue returns only the last ormer.
+ // To ensure that the rollback works, set TxOrmer as the ormer in the transaction.
+ cx = NewContext(cx, tx.TxOrmer)
if err := f(cx); err != nil {
span.AddEvent("rollback transaction")
if e := tx.Rollback(); e != nil {
@@ -164,7 +175,7 @@ func WithTransaction(f func(ctx context.Context) error) func(ctx context.Context
}
}
-// ReadOrCreate read or create instance to datebase, retry to read when met a duplicate key error after the creating
+// ReadOrCreate read or create instance to database, retry to read when met a duplicate key error after the creating
func ReadOrCreate(ctx context.Context, md interface{}, col1 string, cols ...string) (created bool, id int64, err error) {
getter, ok := md.(interface {
GetID() int64
diff --git a/src/lib/orm/query.go b/src/lib/orm/query.go
index 815d3c582..6a2233d9c 100644
--- a/src/lib/orm/query.go
+++ b/src/lib/orm/query.go
@@ -20,7 +20,7 @@ import (
"reflect"
"strings"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/q"
)
diff --git a/src/lib/orm/test/orm_test.go b/src/lib/orm/test/orm_test.go
index ce36d5ed3..b9046c931 100644
--- a/src/lib/orm/test/orm_test.go
+++ b/src/lib/orm/test/orm_test.go
@@ -20,7 +20,7 @@ import (
"sync"
"testing"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/common/dao"
diff --git a/src/lib/orm/tx.go b/src/lib/orm/tx.go
index 0bfb69ce6..546a66463 100644
--- a/src/lib/orm/tx.go
+++ b/src/lib/orm/tx.go
@@ -19,7 +19,7 @@ import (
"encoding/hex"
"fmt"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/google/uuid"
)
@@ -37,6 +37,7 @@ func HasCommittedKey(ctx context.Context) bool {
// ormerTx transaction which support savepoint
type ormerTx struct {
orm.Ormer
+ orm.TxOrmer
savepoint string
}
@@ -48,28 +49,30 @@ func (o *ormerTx) createSavepoint() error {
val := uuid.New()
o.savepoint = fmt.Sprintf("p%s", hex.EncodeToString(val[:]))
- _, err := o.Raw(fmt.Sprintf("SAVEPOINT %s", o.savepoint)).Exec()
+ _, err := o.TxOrmer.Raw(fmt.Sprintf("SAVEPOINT %s", o.savepoint)).Exec()
return err
}
func (o *ormerTx) releaseSavepoint() error {
- _, err := o.Raw(fmt.Sprintf("RELEASE SAVEPOINT %s", o.savepoint)).Exec()
+ _, err := o.TxOrmer.Raw(fmt.Sprintf("RELEASE SAVEPOINT %s", o.savepoint)).Exec()
return err
}
func (o *ormerTx) rollbackToSavepoint() error {
- _, err := o.Raw(fmt.Sprintf("ROLLBACK TO SAVEPOINT %s", o.savepoint)).Exec()
+ _, err := o.TxOrmer.Raw(fmt.Sprintf("ROLLBACK TO SAVEPOINT %s", o.savepoint)).Exec()
return err
}
func (o *ormerTx) Begin() error {
- err := o.Ormer.Begin()
- if err == orm.ErrTxHasBegan {
- // transaction has began for the ormer, so begin nested transaction by savepoint
+ if o.TxOrmer != nil {
return o.createSavepoint()
}
-
- return err
+ txOrmer, err := o.Ormer.Begin()
+ if err != nil {
+ return err
+ }
+ o.TxOrmer = txOrmer
+ return nil
}
func (o *ormerTx) Commit() error {
@@ -77,7 +80,7 @@ func (o *ormerTx) Commit() error {
return o.releaseSavepoint()
}
- return o.Ormer.Commit()
+ return o.TxOrmer.Commit()
}
func (o *ormerTx) Rollback() error {
@@ -85,5 +88,5 @@ func (o *ormerTx) Rollback() error {
return o.rollbackToSavepoint()
}
- return o.Ormer.Rollback()
+ return o.TxOrmer.Rollback()
}
diff --git a/src/migration/migration.go b/src/migration/migration.go
index 396dcf543..9f08c3236 100644
--- a/src/migration/migration.go
+++ b/src/migration/migration.go
@@ -19,7 +19,7 @@ import (
"fmt"
"time"
- beegorm "github.com/beego/beego/orm"
+ beegorm "github.com/beego/beego/v2/client/orm"
"github.com/golang-migrate/migrate/v4"
"github.com/goharbor/harbor/src/common/dao"
diff --git a/src/pkg/accessory/dao/dao_test.go b/src/pkg/accessory/dao/dao_test.go
index aa1b02750..660224f60 100644
--- a/src/pkg/accessory/dao/dao_test.go
+++ b/src/pkg/accessory/dao/dao_test.go
@@ -19,7 +19,7 @@ import (
"fmt"
"testing"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
common_dao "github.com/goharbor/harbor/src/common/dao"
diff --git a/src/pkg/accessory/dao/model.go b/src/pkg/accessory/dao/model.go
index 810de4643..1c0f64e4a 100644
--- a/src/pkg/accessory/dao/model.go
+++ b/src/pkg/accessory/dao/model.go
@@ -17,7 +17,7 @@ package dao
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/allowlist/dao/dao.go b/src/pkg/allowlist/dao/dao.go
index c9d4a3916..404511fda 100644
--- a/src/pkg/allowlist/dao/dao.go
+++ b/src/pkg/allowlist/dao/dao.go
@@ -6,7 +6,7 @@ import (
"fmt"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/lib/orm"
diff --git a/src/pkg/artifact/dao/dao.go b/src/pkg/artifact/dao/dao.go
index 7dac2a83f..aaa87c7a6 100644
--- a/src/pkg/artifact/dao/dao.go
+++ b/src/pkg/artifact/dao/dao.go
@@ -20,7 +20,7 @@ import (
"strings"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
diff --git a/src/pkg/artifact/dao/dao_test.go b/src/pkg/artifact/dao/dao_test.go
index e92f5bd3a..adefcfff7 100644
--- a/src/pkg/artifact/dao/dao_test.go
+++ b/src/pkg/artifact/dao/dao_test.go
@@ -19,7 +19,7 @@ import (
"testing"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/suite"
diff --git a/src/pkg/artifact/dao/model.go b/src/pkg/artifact/dao/model.go
index 1de3a171e..4ce548619 100644
--- a/src/pkg/artifact/dao/model.go
+++ b/src/pkg/artifact/dao/model.go
@@ -17,7 +17,7 @@ package dao
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/q"
)
diff --git a/src/pkg/artifactrash/dao/dao_test.go b/src/pkg/artifactrash/dao/dao_test.go
index 6e53ebb2d..e4099e8fe 100644
--- a/src/pkg/artifactrash/dao/dao_test.go
+++ b/src/pkg/artifactrash/dao/dao_test.go
@@ -5,7 +5,7 @@ import (
"testing"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/suite"
diff --git a/src/pkg/artifactrash/model/model.go b/src/pkg/artifactrash/model/model.go
index ad654d5c0..fc94dafff 100644
--- a/src/pkg/artifactrash/model/model.go
+++ b/src/pkg/artifactrash/model/model.go
@@ -18,7 +18,7 @@ import (
"fmt"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/audit/dao/dao.go b/src/pkg/audit/dao/dao.go
index e771a1848..019ffe6d5 100644
--- a/src/pkg/audit/dao/dao.go
+++ b/src/pkg/audit/dao/dao.go
@@ -18,7 +18,7 @@ import (
"context"
"strings"
- beegorm "github.com/beego/beego/orm"
+ beegorm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/lib/errors"
@@ -90,7 +90,7 @@ func (*dao) Purge(ctx context.Context, retentionHour int, includeOperations []st
return delRows, err
}
-func dryRunPurge(ormer beegorm.Ormer, retentionHour int, includeOperations []string) (int64, error) {
+func dryRunPurge(ormer beegorm.QueryExecutor, retentionHour int, includeOperations []string) (int64, error) {
sql := "SELECT count(1) cnt FROM audit_log WHERE op_time < NOW() - ? * interval '1 hour' "
filterOps := permitOps(includeOperations)
if len(filterOps) == 0 {
diff --git a/src/pkg/audit/dao/dao_test.go b/src/pkg/audit/dao/dao_test.go
index 95d8f3641..b1103adb4 100644
--- a/src/pkg/audit/dao/dao_test.go
+++ b/src/pkg/audit/dao/dao_test.go
@@ -20,7 +20,7 @@ import (
"testing"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
common_dao "github.com/goharbor/harbor/src/common/dao"
diff --git a/src/pkg/audit/model/model.go b/src/pkg/audit/model/model.go
index 6d624fe19..0e477276a 100644
--- a/src/pkg/audit/model/model.go
+++ b/src/pkg/audit/model/model.go
@@ -3,7 +3,7 @@ package model
import (
"time"
- beego_orm "github.com/beego/beego/orm"
+ beego_orm "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/blob/models/blob.go b/src/pkg/blob/models/blob.go
index cdb93516b..24c55f2d2 100644
--- a/src/pkg/blob/models/blob.go
+++ b/src/pkg/blob/models/blob.go
@@ -20,7 +20,7 @@ import (
"strings"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/manifest/schema2"
diff --git a/src/pkg/immutable/dao/model/rule.go b/src/pkg/immutable/dao/model/rule.go
index 94d1db141..19bc80e19 100644
--- a/src/pkg/immutable/dao/model/rule.go
+++ b/src/pkg/immutable/dao/model/rule.go
@@ -1,7 +1,7 @@
package model
import (
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/immutable/model/rule.go b/src/pkg/immutable/model/rule.go
index 8c3e6ed7e..65136507d 100644
--- a/src/pkg/immutable/model/rule.go
+++ b/src/pkg/immutable/model/rule.go
@@ -1,7 +1,7 @@
package model
import (
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
)
// Metadata of the immutable rule
diff --git a/src/pkg/joblog/models/joblog.go b/src/pkg/joblog/models/joblog.go
index 9576d6ee9..ba6c00cb1 100644
--- a/src/pkg/joblog/models/joblog.go
+++ b/src/pkg/joblog/models/joblog.go
@@ -3,7 +3,7 @@ package models
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/label/dao/dao_test.go b/src/pkg/label/dao/dao_test.go
index 371aa43cc..7049f0db1 100644
--- a/src/pkg/label/dao/dao_test.go
+++ b/src/pkg/label/dao/dao_test.go
@@ -18,7 +18,7 @@ import (
"context"
"testing"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/suite"
diff --git a/src/pkg/label/model/model.go b/src/pkg/label/model/model.go
index 258298610..2d1128f6a 100644
--- a/src/pkg/label/model/model.go
+++ b/src/pkg/label/model/model.go
@@ -3,7 +3,7 @@ package model
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/lib/errors"
diff --git a/src/pkg/notification/job/model/model.go b/src/pkg/notification/job/model/model.go
index bf7830177..8d96c5a3a 100644
--- a/src/pkg/notification/job/model/model.go
+++ b/src/pkg/notification/job/model/model.go
@@ -3,7 +3,7 @@ package model
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/notification/policy/model/model.go b/src/pkg/notification/policy/model/model.go
index 581772d2b..c7a531bb9 100644
--- a/src/pkg/notification/policy/model/model.go
+++ b/src/pkg/notification/policy/model/model.go
@@ -4,7 +4,7 @@ import (
"encoding/json"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/p2p/preheat/dao/instance/dao.go b/src/pkg/p2p/preheat/dao/instance/dao.go
index 4acb211f4..32b8606da 100644
--- a/src/pkg/p2p/preheat/dao/instance/dao.go
+++ b/src/pkg/p2p/preheat/dao/instance/dao.go
@@ -4,8 +4,6 @@ import (
"context"
"fmt"
- beego_orm "github.com/beego/beego/orm"
-
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/p2p/preheat/models/provider"
@@ -40,8 +38,7 @@ var _ DAO = (*dao)(nil)
// Create adds a new distribution instance.
func (d *dao) Create(ctx context.Context, instance *provider.Instance) (id int64, err error) {
- var o beego_orm.Ormer
- o, err = orm.FromContext(ctx)
+ o, err := orm.FromContext(ctx)
if err != nil {
return
}
diff --git a/src/pkg/p2p/preheat/dao/instance/dao_test.go b/src/pkg/p2p/preheat/dao/instance/dao_test.go
index 1ce525232..cc2b6e4ca 100644
--- a/src/pkg/p2p/preheat/dao/instance/dao_test.go
+++ b/src/pkg/p2p/preheat/dao/instance/dao_test.go
@@ -4,7 +4,7 @@ import (
"context"
"testing"
- beego_orm "github.com/beego/beego/orm"
+ beego_orm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
diff --git a/src/pkg/p2p/preheat/dao/policy/dao.go b/src/pkg/p2p/preheat/dao/policy/dao.go
index f1e4da130..25b44b460 100644
--- a/src/pkg/p2p/preheat/dao/policy/dao.go
+++ b/src/pkg/p2p/preheat/dao/policy/dao.go
@@ -17,7 +17,7 @@ package policy
import (
"context"
- beego_orm "github.com/beego/beego/orm"
+ beego_orm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
@@ -62,8 +62,7 @@ func (d *dao) Count(ctx context.Context, query *q.Query) (total int64, err error
// Create a policy schema.
func (d *dao) Create(ctx context.Context, schema *policy.Schema) (id int64, err error) {
- var ormer beego_orm.Ormer
- ormer, err = orm.FromContext(ctx)
+ ormer, err := orm.FromContext(ctx)
if err != nil {
return
}
@@ -81,8 +80,7 @@ func (d *dao) Create(ctx context.Context, schema *policy.Schema) (id int64, err
// Update a policy schema.
func (d *dao) Update(ctx context.Context, schema *policy.Schema, props ...string) (err error) {
- var ormer beego_orm.Ormer
- ormer, err = orm.FromContext(ctx)
+ ormer, err := orm.FromContext(ctx)
if err != nil {
return err
}
@@ -101,8 +99,7 @@ func (d *dao) Update(ctx context.Context, schema *policy.Schema, props ...string
// Get a policy schema by id.
func (d *dao) Get(ctx context.Context, id int64) (schema *policy.Schema, err error) {
- var ormer beego_orm.Ormer
- ormer, err = orm.FromContext(ctx)
+ ormer, err := orm.FromContext(ctx)
if err != nil {
return
}
@@ -120,8 +117,7 @@ func (d *dao) Get(ctx context.Context, id int64) (schema *policy.Schema, err err
// GetByName gets a policy schema by name.
func (d *dao) GetByName(ctx context.Context, projectID int64, name string) (schema *policy.Schema, err error) {
- var ormer beego_orm.Ormer
- ormer, err = orm.FromContext(ctx)
+ ormer, err := orm.FromContext(ctx)
if err != nil {
return
}
@@ -139,8 +135,7 @@ func (d *dao) GetByName(ctx context.Context, projectID int64, name string) (sche
// Delete a policy schema by id.
func (d *dao) Delete(ctx context.Context, id int64) (err error) {
- var ormer beego_orm.Ormer
- ormer, err = orm.FromContext(ctx)
+ ormer, err := orm.FromContext(ctx)
if err != nil {
return
}
diff --git a/src/pkg/p2p/preheat/dao/policy/dao_test.go b/src/pkg/p2p/preheat/dao/policy/dao_test.go
index cf9bc542a..fb6161bc4 100644
--- a/src/pkg/p2p/preheat/dao/policy/dao_test.go
+++ b/src/pkg/p2p/preheat/dao/policy/dao_test.go
@@ -19,7 +19,7 @@ import (
"testing"
"time"
- beego_orm "github.com/beego/beego/orm"
+ beego_orm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
common_dao "github.com/goharbor/harbor/src/common/dao"
diff --git a/src/pkg/p2p/preheat/models/policy/policy.go b/src/pkg/p2p/preheat/models/policy/policy.go
index 420dd9e7c..aab0e789d 100644
--- a/src/pkg/p2p/preheat/models/policy/policy.go
+++ b/src/pkg/p2p/preheat/models/policy/policy.go
@@ -20,8 +20,8 @@ import (
"strconv"
"time"
- beego_orm "github.com/beego/beego/orm"
- "github.com/beego/beego/validation"
+ beego_orm "github.com/beego/beego/v2/client/orm"
+ "github.com/beego/beego/v2/core/validation"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/lib/errors"
diff --git a/src/pkg/p2p/preheat/models/policy/policy_test.go b/src/pkg/p2p/preheat/models/policy/policy_test.go
index 985300423..6c39b42e1 100644
--- a/src/pkg/p2p/preheat/models/policy/policy_test.go
+++ b/src/pkg/p2p/preheat/models/policy/policy_test.go
@@ -17,7 +17,7 @@ package policy
import (
"testing"
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
diff --git a/src/pkg/p2p/preheat/models/provider/instance.go b/src/pkg/p2p/preheat/models/provider/instance.go
index b42010f8c..407daf0ad 100644
--- a/src/pkg/p2p/preheat/models/provider/instance.go
+++ b/src/pkg/p2p/preheat/models/provider/instance.go
@@ -17,7 +17,7 @@ package provider
import (
"encoding/json"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
)
diff --git a/src/pkg/project/metadata/models/metadata.go b/src/pkg/project/metadata/models/metadata.go
index 70c2b7c11..cf7142968 100644
--- a/src/pkg/project/metadata/models/metadata.go
+++ b/src/pkg/project/metadata/models/metadata.go
@@ -17,7 +17,7 @@ package models
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/quota/dao/model.go b/src/pkg/quota/dao/model.go
index 73a43092c..6c05dbe4b 100644
--- a/src/pkg/quota/dao/model.go
+++ b/src/pkg/quota/dao/model.go
@@ -17,7 +17,7 @@ package dao
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/rbac/model/model.go b/src/pkg/rbac/model/model.go
index db9a4157a..24ce458af 100644
--- a/src/pkg/rbac/model/model.go
+++ b/src/pkg/rbac/model/model.go
@@ -3,7 +3,7 @@ package model
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/reg/dao/dao_test.go b/src/pkg/reg/dao/dao_test.go
index 890a4a26c..fa357e56a 100644
--- a/src/pkg/reg/dao/dao_test.go
+++ b/src/pkg/reg/dao/dao_test.go
@@ -18,7 +18,7 @@ import (
"context"
"testing"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
common_dao "github.com/goharbor/harbor/src/common/dao"
diff --git a/src/pkg/reg/dao/model.go b/src/pkg/reg/dao/model.go
index 20181590d..840f168eb 100644
--- a/src/pkg/reg/dao/model.go
+++ b/src/pkg/reg/dao/model.go
@@ -17,7 +17,7 @@ package dao
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/replication/dao/dao_test.go b/src/pkg/replication/dao/dao_test.go
index cf6b87a39..e8c061d33 100644
--- a/src/pkg/replication/dao/dao_test.go
+++ b/src/pkg/replication/dao/dao_test.go
@@ -18,7 +18,7 @@ import (
"context"
"testing"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
common_dao "github.com/goharbor/harbor/src/common/dao"
diff --git a/src/pkg/replication/model/model.go b/src/pkg/replication/model/model.go
index 492371edd..04d17237c 100644
--- a/src/pkg/replication/model/model.go
+++ b/src/pkg/replication/model/model.go
@@ -17,7 +17,7 @@ package model
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
func init() {
diff --git a/src/pkg/repository/dao/dao.go b/src/pkg/repository/dao/dao.go
index dd629fae0..864761ef7 100644
--- a/src/pkg/repository/dao/dao.go
+++ b/src/pkg/repository/dao/dao.go
@@ -18,7 +18,7 @@ import (
"context"
"time"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
diff --git a/src/pkg/repository/dao/dao_test.go b/src/pkg/repository/dao/dao_test.go
index f00a48c8d..ed630dcc6 100644
--- a/src/pkg/repository/dao/dao_test.go
+++ b/src/pkg/repository/dao/dao_test.go
@@ -20,7 +20,7 @@ import (
"testing"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/suite"
diff --git a/src/pkg/retention/dao/models/retention.go b/src/pkg/retention/dao/models/retention.go
index 7c25fec28..d573a0366 100644
--- a/src/pkg/retention/dao/models/retention.go
+++ b/src/pkg/retention/dao/models/retention.go
@@ -3,7 +3,7 @@ package models
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
// const definitions
diff --git a/src/pkg/retention/manager.go b/src/pkg/retention/manager.go
index 8006d747d..8b36d0a93 100644
--- a/src/pkg/retention/manager.go
+++ b/src/pkg/retention/manager.go
@@ -20,7 +20,7 @@ import (
"fmt"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/pkg/retention/dao"
"github.com/goharbor/harbor/src/pkg/retention/dao/models"
diff --git a/src/pkg/retention/policy/models.go b/src/pkg/retention/policy/models.go
index e4147890b..c58daf63f 100644
--- a/src/pkg/retention/policy/models.go
+++ b/src/pkg/retention/policy/models.go
@@ -15,7 +15,7 @@
package policy
import (
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
"github.com/goharbor/harbor/src/lib/selector/selectors/doublestar"
"github.com/goharbor/harbor/src/pkg/retention/policy/rule"
diff --git a/src/pkg/retention/policy/models_test.go b/src/pkg/retention/policy/models_test.go
index eb3037dd4..5ca55ab9e 100644
--- a/src/pkg/retention/policy/models_test.go
+++ b/src/pkg/retention/policy/models_test.go
@@ -4,7 +4,7 @@ import (
"fmt"
"testing"
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
"github.com/stretchr/testify/require"
"github.com/goharbor/harbor/src/pkg/retention/policy/rule"
diff --git a/src/pkg/retention/policy/rule/models.go b/src/pkg/retention/policy/rule/models.go
index 88294bdf4..0c55abe52 100644
--- a/src/pkg/retention/policy/rule/models.go
+++ b/src/pkg/retention/policy/rule/models.go
@@ -15,7 +15,7 @@
package rule
import (
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
)
// Metadata of the retention rule
diff --git a/src/pkg/robot/model/model.go b/src/pkg/robot/model/model.go
index 9064bc77d..4c2c52ef6 100644
--- a/src/pkg/robot/model/model.go
+++ b/src/pkg/robot/model/model.go
@@ -4,7 +4,7 @@ import (
"encoding/json"
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
)
diff --git a/src/pkg/scan/export/manager.go b/src/pkg/scan/export/manager.go
index 5b74abc13..61d531488 100644
--- a/src/pkg/scan/export/manager.go
+++ b/src/pkg/scan/export/manager.go
@@ -6,7 +6,7 @@ import (
"errors"
"fmt"
- beego_orm "github.com/beego/beego/orm"
+ beego_orm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/orm"
q2 "github.com/goharbor/harbor/src/lib/q"
diff --git a/src/pkg/scheduler/dao.go b/src/pkg/scheduler/dao.go
index 14cbf806f..e061d7ed7 100644
--- a/src/pkg/scheduler/dao.go
+++ b/src/pkg/scheduler/dao.go
@@ -18,7 +18,7 @@ import (
"context"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
diff --git a/src/pkg/tag/dao/dao.go b/src/pkg/tag/dao/dao.go
index bbe9e03c2..79acf00de 100644
--- a/src/pkg/tag/dao/dao.go
+++ b/src/pkg/tag/dao/dao.go
@@ -17,7 +17,7 @@ package dao
import (
"context"
- beego_orm "github.com/beego/beego/orm"
+ beego_orm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
diff --git a/src/pkg/tag/dao/dao_test.go b/src/pkg/tag/dao/dao_test.go
index 1ab0a03ff..7b5a20dcd 100644
--- a/src/pkg/tag/dao/dao_test.go
+++ b/src/pkg/tag/dao/dao_test.go
@@ -19,7 +19,7 @@ import (
"testing"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
common_dao "github.com/goharbor/harbor/src/common/dao"
diff --git a/src/pkg/task/dao/model.go b/src/pkg/task/dao/model.go
index 27ea36f32..e43cfd7e8 100644
--- a/src/pkg/task/dao/model.go
+++ b/src/pkg/task/dao/model.go
@@ -17,7 +17,7 @@ package dao
import (
"time"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/q"
)
diff --git a/src/server/middleware/blob/head_blob_test.go b/src/server/middleware/blob/head_blob_test.go
index f24ccf785..e6c41a07c 100644
--- a/src/server/middleware/blob/head_blob_test.go
+++ b/src/server/middleware/blob/head_blob_test.go
@@ -6,7 +6,7 @@ import (
"net/http/httptest"
"testing"
- beego_orm "github.com/beego/beego/orm"
+ beego_orm "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/controller/blob"
diff --git a/src/server/middleware/orm/orm.go b/src/server/middleware/orm/orm.go
index 16463e5f2..29db17a7a 100644
--- a/src/server/middleware/orm/orm.go
+++ b/src/server/middleware/orm/orm.go
@@ -17,7 +17,7 @@ package orm
import (
"net/http"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/server/middleware"
diff --git a/src/server/middleware/orm/orm_test.go b/src/server/middleware/orm/orm_test.go
index fead4b93e..505716024 100644
--- a/src/server/middleware/orm/orm_test.go
+++ b/src/server/middleware/orm/orm_test.go
@@ -19,7 +19,7 @@ import (
"net/http/httptest"
"testing"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/assert"
"github.com/goharbor/harbor/src/lib/orm"
diff --git a/src/server/middleware/security/session.go b/src/server/middleware/security/session.go
index 6425fdf76..e8bc29591 100644
--- a/src/server/middleware/security/session.go
+++ b/src/server/middleware/security/session.go
@@ -18,7 +18,7 @@ import (
"net/http"
"net/http/httptest"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/security"
@@ -30,12 +30,12 @@ type session struct{}
func (s *session) Generate(req *http.Request) security.Context {
log := log.G(req.Context())
- store, err := beego.GlobalSessions.SessionStart(httptest.NewRecorder(), req)
+ store, err := web.GlobalSessions.SessionStart(httptest.NewRecorder(), req)
if err != nil {
log.Errorf("failed to get the session store for request: %v", err)
return nil
}
- userInterface := store.Get("user")
+ userInterface := store.Get(req.Context(), "user")
if userInterface == nil {
return nil
}
diff --git a/src/server/middleware/security/session_test.go b/src/server/middleware/security/session_test.go
index 149618e6c..28ceae0d1 100644
--- a/src/server/middleware/security/session_test.go
+++ b/src/server/middleware/security/session_test.go
@@ -20,8 +20,8 @@ import (
"path/filepath"
"testing"
- "github.com/beego/beego"
- beegosession "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/server/web"
+ beegosession "github.com/beego/beego/v2/server/web/session"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -32,15 +32,15 @@ func TestSession(t *testing.T) {
var err error
// initialize beego session manager
conf := &beegosession.ManagerConfig{
- CookieName: beego.BConfig.WebConfig.Session.SessionName,
- Gclifetime: beego.BConfig.WebConfig.Session.SessionGCMaxLifetime,
- ProviderConfig: filepath.ToSlash(beego.BConfig.WebConfig.Session.SessionProviderConfig),
- Secure: beego.BConfig.Listen.EnableHTTPS,
- EnableSetCookie: beego.BConfig.WebConfig.Session.SessionAutoSetCookie,
- Domain: beego.BConfig.WebConfig.Session.SessionDomain,
- CookieLifeTime: beego.BConfig.WebConfig.Session.SessionCookieLifeTime,
+ CookieName: web.BConfig.WebConfig.Session.SessionName,
+ Gclifetime: web.BConfig.WebConfig.Session.SessionGCMaxLifetime,
+ ProviderConfig: filepath.ToSlash(web.BConfig.WebConfig.Session.SessionProviderConfig),
+ Secure: web.BConfig.Listen.EnableHTTPS,
+ EnableSetCookie: web.BConfig.WebConfig.Session.SessionAutoSetCookie,
+ Domain: web.BConfig.WebConfig.Session.SessionDomain,
+ CookieLifeTime: web.BConfig.WebConfig.Session.SessionCookieLifeTime,
}
- beego.GlobalSessions, err = beegosession.NewManager("memory", conf)
+ web.GlobalSessions, err = beegosession.NewManager("memory", conf)
require.Nil(t, err)
user := models.User{
@@ -51,9 +51,9 @@ func TestSession(t *testing.T) {
}
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1/api/projects/", nil)
require.Nil(t, err)
- store, err := beego.GlobalSessions.SessionStart(httptest.NewRecorder(), req)
+ store, err := web.GlobalSessions.SessionStart(httptest.NewRecorder(), req)
require.Nil(t, err)
- err = store.Set("user", user)
+ err = store.Set(req.Context(), "user", user)
require.Nil(t, err)
session := &session{}
diff --git a/src/server/middleware/session/session_test.go b/src/server/middleware/session/session_test.go
index 72f1f56aa..771646e84 100644
--- a/src/server/middleware/session/session_test.go
+++ b/src/server/middleware/session/session_test.go
@@ -20,8 +20,8 @@ import (
"path/filepath"
"testing"
- "github.com/beego/beego"
- beegosession "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/server/web"
+ beegosession "github.com/beego/beego/v2/server/web/session"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -41,19 +41,19 @@ func TestSession(t *testing.T) {
assert.False(t, carrySession)
// contains session
- beego.BConfig.WebConfig.Session.SessionName = config.SessionCookieName
+ web.BConfig.WebConfig.Session.SessionName = config.SessionCookieName
conf := &beegosession.ManagerConfig{
- CookieName: beego.BConfig.WebConfig.Session.SessionName,
- Gclifetime: beego.BConfig.WebConfig.Session.SessionGCMaxLifetime,
- ProviderConfig: filepath.ToSlash(beego.BConfig.WebConfig.Session.SessionProviderConfig),
- Secure: beego.BConfig.Listen.EnableHTTPS,
- EnableSetCookie: beego.BConfig.WebConfig.Session.SessionAutoSetCookie,
- Domain: beego.BConfig.WebConfig.Session.SessionDomain,
- CookieLifeTime: beego.BConfig.WebConfig.Session.SessionCookieLifeTime,
+ CookieName: web.BConfig.WebConfig.Session.SessionName,
+ Gclifetime: web.BConfig.WebConfig.Session.SessionGCMaxLifetime,
+ ProviderConfig: filepath.ToSlash(web.BConfig.WebConfig.Session.SessionProviderConfig),
+ Secure: web.BConfig.Listen.EnableHTTPS,
+ EnableSetCookie: web.BConfig.WebConfig.Session.SessionAutoSetCookie,
+ Domain: web.BConfig.WebConfig.Session.SessionDomain,
+ CookieLifeTime: web.BConfig.WebConfig.Session.SessionCookieLifeTime,
}
- beego.GlobalSessions, err = beegosession.NewManager("memory", conf)
+ web.GlobalSessions, err = beegosession.NewManager("memory", conf)
require.Nil(t, err)
- _, err = beego.GlobalSessions.SessionStart(httptest.NewRecorder(), req)
+ _, err = web.GlobalSessions.SessionStart(httptest.NewRecorder(), req)
require.Nil(t, err)
Middleware()(handler).ServeHTTP(nil, req)
assert.True(t, carrySession)
diff --git a/src/server/middleware/transaction/transaction_test.go b/src/server/middleware/transaction/transaction_test.go
index c925fc80a..994947a6c 100644
--- a/src/server/middleware/transaction/transaction_test.go
+++ b/src/server/middleware/transaction/transaction_test.go
@@ -16,61 +16,70 @@ package transaction
import (
"context"
- "errors"
"io"
"net/http"
"net/http/httptest"
"testing"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/stretchr/testify/assert"
+ "github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/server/middleware"
)
type mockOrmer struct {
o.Ormer
- records []interface{}
- beginErr error
- commitErr error
+ tx mockTxOrmer
+ beginErr error
}
-func (m *mockOrmer) Insert(i interface{}) (int64, error) {
- m.records = append(m.records, i)
-
- return int64(len(m.records)), nil
-}
-
-func (m *mockOrmer) Begin() error {
- return m.beginErr
-}
-
-func (m *mockOrmer) Commit() error {
- return m.commitErr
-}
-
-func (m *mockOrmer) Rollback() error {
- m.ResetRecords()
-
- return nil
-}
-
-func (m *mockOrmer) ResetRecords() {
- m.records = nil
+func (m *mockOrmer) Begin() (o.TxOrmer, error) {
+ return &m.tx, m.beginErr
}
func (m *mockOrmer) Reset() {
- m.ResetRecords()
-
+ m.tx.Reset()
m.beginErr = nil
+}
+
+type mockTxOrmer struct {
+ o.TxOrmer
+ commitErr error
+ records []interface{}
+}
+
+func (m *mockTxOrmer) Insert(i interface{}) (int64, error) {
+ m.records = append(m.records, i)
+ return int64(len(m.records)), nil
+}
+
+func (m *mockTxOrmer) Commit() error {
+ return m.commitErr
+}
+
+func (m *mockTxOrmer) Rollback() error {
+ m.ResetRecords()
+ return nil
+}
+
+func (m *mockTxOrmer) ResetRecords() {
+ m.records = nil
+}
+
+func (m *mockTxOrmer) Reset() {
+ m.ResetRecords()
m.commitErr = nil
}
func TestTransaction(t *testing.T) {
assert := assert.New(t)
- mo := &mockOrmer{}
+ tx := mockTxOrmer{}
+ mo := &mockOrmer{
+ tx: tx,
+ }
newRequest := func(method, target string, body io.Reader) *http.Request {
req := httptest.NewRequest(http.MethodGet, "/req1", nil)
@@ -79,7 +88,7 @@ func TestTransaction(t *testing.T) {
next := func(status int) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- mo.Insert("record1")
+ mo.tx.Insert("record1")
w.WriteHeader(status)
})
}
@@ -89,17 +98,17 @@ func TestTransaction(t *testing.T) {
rec1 := httptest.NewRecorder()
Middleware()(next(http.StatusOK)).ServeHTTP(rec1, req1)
assert.Equal(http.StatusOK, rec1.Code)
- assert.NotEmpty(mo.records)
+ assert.NotEmpty(mo.tx.records)
- mo.ResetRecords()
- assert.Empty(mo.records)
+ mo.tx.ResetRecords()
+ assert.Empty(mo.tx.records)
// test response status code not accepted
req2 := newRequest(http.MethodGet, "/req", nil)
rec2 := httptest.NewRecorder()
Middleware()(next(http.StatusBadRequest)).ServeHTTP(rec2, req2)
assert.Equal(http.StatusBadRequest, rec2.Code)
- assert.Empty(mo.records)
+ assert.Empty(mo.tx.records)
// test begin transaction failed
mo.beginErr = errors.New("begin tx failed")
@@ -107,11 +116,11 @@ func TestTransaction(t *testing.T) {
rec3 := httptest.NewRecorder()
Middleware()(next(http.StatusBadRequest)).ServeHTTP(rec3, req3)
assert.Equal(http.StatusInternalServerError, rec3.Code)
- assert.Empty(mo.records)
+ assert.Empty(mo.tx.records)
// test commit transaction failed
mo.beginErr = nil
- mo.commitErr = errors.New("commit tx failed")
+ mo.tx.commitErr = errors.New("commit tx failed")
req4 := newRequest(http.MethodGet, "/req", nil)
rec4 := httptest.NewRecorder()
Middleware()(next(http.StatusOK)).ServeHTTP(rec4, req4)
@@ -119,12 +128,12 @@ func TestTransaction(t *testing.T) {
// test MustCommit
mo.Reset()
- assert.Empty(mo.records)
+ assert.Empty(mo.tx.records)
txMustCommit := func(status int) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer MustCommit(r)
- mo.Insert("record1")
+ mo.tx.Insert("record1")
w.WriteHeader(status)
})
}
@@ -139,7 +148,7 @@ func TestTransaction(t *testing.T) {
Middleware()(m1((txMustCommit(http.StatusBadRequest)))).ServeHTTP(rec5, req5)
assert.Equal(http.StatusBadRequest, rec2.Code)
- assert.NotEmpty(mo.records)
+ assert.NotEmpty(mo.tx.records)
}
func TestMustCommit(t *testing.T) {
diff --git a/src/server/registry/manifest_test.go b/src/server/registry/manifest_test.go
index bdea36dac..39af2f660 100644
--- a/src/server/registry/manifest_test.go
+++ b/src/server/registry/manifest_test.go
@@ -20,7 +20,7 @@ import (
"net/http/httptest"
"testing"
- beegocontext "github.com/beego/beego/context"
+ beegocontext "github.com/beego/beego/v2/server/web/context"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/controller/artifact"
diff --git a/src/server/route.go b/src/server/route.go
index 6dce4ddf9..a57210ea8 100644
--- a/src/server/route.go
+++ b/src/server/route.go
@@ -17,7 +17,7 @@ package server
import (
"net/http"
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/core/api"
@@ -38,18 +38,18 @@ func registerRoutes() {
router.NewRoute().Method(http.MethodGet).Path("/api/version").HandlerFunc(GetAPIVersion)
// Controller API:
- beego.Router("/c/login", &controllers.CommonController{}, "post:Login")
- beego.Router("/c/log_out", &controllers.CommonController{}, "get:LogOut")
- beego.Router("/c/userExists", &controllers.CommonController{}, "post:UserExists")
- beego.Router(common.OIDCLoginPath, &controllers.OIDCController{}, "get:RedirectLogin")
- beego.Router("/c/oidc/onboard", &controllers.OIDCController{}, "post:Onboard")
- beego.Router(common.OIDCCallbackPath, &controllers.OIDCController{}, "get:Callback")
- beego.Router(common.AuthProxyRediretPath, &controllers.AuthProxyController{}, "get:HandleRedirect")
+ web.Router("/c/login", &controllers.CommonController{}, "post:Login")
+ web.Router("/c/log_out", &controllers.CommonController{}, "get:LogOut")
+ web.Router("/c/userExists", &controllers.CommonController{}, "post:UserExists")
+ web.Router(common.OIDCLoginPath, &controllers.OIDCController{}, "get:RedirectLogin")
+ web.Router("/c/oidc/onboard", &controllers.OIDCController{}, "post:Onboard")
+ web.Router(common.OIDCCallbackPath, &controllers.OIDCController{}, "get:Callback")
+ web.Router(common.AuthProxyRediretPath, &controllers.AuthProxyController{}, "get:HandleRedirect")
- beego.Router("/api/internal/renameadmin", &api.InternalAPI{}, "post:RenameAdmin")
- beego.Router("/api/internal/syncquota", &api.InternalAPI{}, "post:SyncQuota")
+ web.Router("/api/internal/renameadmin", &api.InternalAPI{}, "post:RenameAdmin")
+ web.Router("/api/internal/syncquota", &api.InternalAPI{}, "post:SyncQuota")
- beego.Router("/service/notifications/jobs/webhook/:id([0-9]+)", &jobs.Handler{}, "post:HandleNotificationJob")
+ web.Router("/service/notifications/jobs/webhook/:id([0-9]+)", &jobs.Handler{}, "post:HandleNotificationJob")
router.NewRoute().Method(http.MethodPost).Path("/service/notifications/jobs/adminjob/:id([0-9]+)").Handler(handler.NewJobStatusHandler()) // legacy job status hook endpoint for adminjob
router.NewRoute().Method(http.MethodPost).Path("/service/notifications/jobs/scan/:uuid").HandlerFunc(ignoreNotification) // ignore legacy scan job notifaction
router.NewRoute().Method(http.MethodPost).Path("/service/notifications/schedules/:id([0-9]+)").Handler(handler.NewJobStatusHandler()) // legacy job status hook endpoint for scheduler
@@ -58,25 +58,25 @@ func registerRoutes() {
router.NewRoute().Method(http.MethodPost).Path("/service/notifications/jobs/retention/task/:id([0-9]+)").Handler(handler.NewJobStatusHandler())
router.NewRoute().Method(http.MethodPost).Path("/service/notifications/tasks/:id").Handler(handler.NewJobStatusHandler())
- beego.Router("/service/token", &token.Handler{})
+ web.Router("/service/token", &token.Handler{})
// chart repository services
if config.WithChartMuseum() {
chartRepositoryAPIType := &api.ChartRepositoryAPI{}
- beego.Router("/chartrepo/:repo/index.yaml", chartRepositoryAPIType, "get:GetIndexByRepo")
- beego.Router("/chartrepo/index.yaml", chartRepositoryAPIType, "get:GetIndex")
- beego.Router("/chartrepo/:repo/charts/:filename", chartRepositoryAPIType, "get:DownloadChart")
- beego.Router("/api/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus")
- beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts")
- beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions")
- beego.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart")
- beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion")
- beego.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion")
- beego.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
- beego.Router("/api/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile")
- beego.Router("/api/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
+ web.Router("/chartrepo/:repo/index.yaml", chartRepositoryAPIType, "get:GetIndexByRepo")
+ web.Router("/chartrepo/index.yaml", chartRepositoryAPIType, "get:GetIndex")
+ web.Router("/chartrepo/:repo/charts/:filename", chartRepositoryAPIType, "get:DownloadChart")
+ web.Router("/api/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus")
+ web.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "get:ListCharts")
+ web.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "get:ListChartVersions")
+ web.Router("/api/chartrepo/:repo/charts/:name", chartRepositoryAPIType, "delete:DeleteChart")
+ web.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "get:GetChartVersion")
+ web.Router("/api/chartrepo/:repo/charts/:name/:version", chartRepositoryAPIType, "delete:DeleteChartVersion")
+ web.Router("/api/chartrepo/:repo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
+ web.Router("/api/chartrepo/:repo/prov", chartRepositoryAPIType, "post:UploadChartProvFile")
+ web.Router("/api/chartrepo/charts", chartRepositoryAPIType, "post:UploadChartVersion")
}
// Error pages
- beego.ErrorController(&controllers.ErrorController{})
+ web.ErrorController(&controllers.ErrorController{})
}
diff --git a/src/server/router/router.go b/src/server/router/router.go
index 0b9611ea1..78b1ad3d7 100644
--- a/src/server/router/router.go
+++ b/src/server/router/router.go
@@ -19,8 +19,8 @@ import (
"net/http"
"path/filepath"
- "github.com/beego/beego"
- beegocontext "github.com/beego/beego/context"
+ "github.com/beego/beego/v2/server/web"
+ beegocontext "github.com/beego/beego/v2/server/web/context"
"github.com/goharbor/harbor/src/server/middleware"
)
@@ -84,7 +84,7 @@ func (r *Route) Handler(handler http.Handler) {
}
middlewares = append(middlewares, r.middlewares...)
- filterFunc := beego.FilterFunc(func(ctx *beegocontext.Context) {
+ filterFunc := web.FilterFunc(func(ctx *beegocontext.Context) {
ctx.Request = ctx.Request.WithContext(
context.WithValue(ctx.Request.Context(), ContextKeyInput{}, ctx.Input))
// TODO remove the WithMiddlewares?
@@ -93,25 +93,25 @@ func (r *Route) Handler(handler http.Handler) {
})
if len(methods) == 0 {
- beego.Any(path, filterFunc)
+ web.Any(path, filterFunc)
return
}
for _, method := range methods {
switch method {
case http.MethodGet:
- beego.Get(path, filterFunc)
+ web.Get(path, filterFunc)
case http.MethodHead:
- beego.Head(path, filterFunc)
+ web.Head(path, filterFunc)
case http.MethodPut:
- beego.Put(path, filterFunc)
+ web.Put(path, filterFunc)
case http.MethodPatch:
- beego.Patch(path, filterFunc)
+ web.Patch(path, filterFunc)
case http.MethodPost:
- beego.Post(path, filterFunc)
+ web.Post(path, filterFunc)
case http.MethodDelete:
- beego.Delete(path, filterFunc)
+ web.Delete(path, filterFunc)
case http.MethodOptions:
- beego.Options(path, filterFunc)
+ web.Options(path, filterFunc)
}
}
}
diff --git a/src/server/router/router_test.go b/src/server/router/router_test.go
index af65072b7..3eac69b58 100644
--- a/src/server/router/router_test.go
+++ b/src/server/router/router_test.go
@@ -19,7 +19,7 @@ import (
"net/http"
"testing"
- beegocontext "github.com/beego/beego/context"
+ beegocontext "github.com/beego/beego/v2/server/web/context"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/server/middleware"
diff --git a/src/server/v2.0/handler/scanexport_test.go b/src/server/v2.0/handler/scanexport_test.go
index da59da0ab..76008c20b 100644
--- a/src/server/v2.0/handler/scanexport_test.go
+++ b/src/server/v2.0/handler/scanexport_test.go
@@ -12,7 +12,7 @@ import (
"testing"
"time"
- beegoorm "github.com/beego/beego/orm"
+ beegoorm "github.com/beego/beego/v2/client/orm"
"github.com/goharbor/harbor/src/lib/errors"
testifymock "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
diff --git a/src/server/v2.0/route/legacy.go b/src/server/v2.0/route/legacy.go
index 696ee1a55..c31b02ec4 100755
--- a/src/server/v2.0/route/legacy.go
+++ b/src/server/v2.0/route/legacy.go
@@ -15,7 +15,7 @@
package route
import (
- "github.com/beego/beego"
+ "github.com/beego/beego/v2/server/web"
"github.com/goharbor/harbor/src/core/api"
"github.com/goharbor/harbor/src/lib/config"
@@ -29,7 +29,7 @@ func registerLegacyRoutes() {
if config.WithChartMuseum() {
// Labels for chart
chartLabelAPIType := &api.ChartLabelAPI{}
- beego.Router("/api/"+version+"/chartrepo/:repo/charts/:name/:version/labels", chartLabelAPIType, "get:GetLabels;post:MarkLabel")
- beego.Router("/api/"+version+"/chartrepo/:repo/charts/:name/:version/labels/:id([0-9]+)", chartLabelAPIType, "delete:RemoveLabel")
+ web.Router("/api/"+version+"/chartrepo/:repo/charts/:name/:version/labels", chartLabelAPIType, "get:GetLabels;post:MarkLabel")
+ web.Router("/api/"+version+"/chartrepo/:repo/charts/:name/:version/labels/:id([0-9]+)", chartLabelAPIType, "delete:RemoveLabel")
}
}
diff --git a/src/testing/lib/orm/creator.go b/src/testing/lib/orm/creator.go
index 7bbcb9ad9..a19a1cf29 100644
--- a/src/testing/lib/orm/creator.go
+++ b/src/testing/lib/orm/creator.go
@@ -3,7 +3,7 @@
package orm
import (
- orm "github.com/beego/beego/orm"
+ orm "github.com/beego/beego/v2/client/orm"
mock "github.com/stretchr/testify/mock"
)
diff --git a/src/testing/lib/orm/orm.go b/src/testing/lib/orm/orm.go
index 0f05f835e..34bec811d 100644
--- a/src/testing/lib/orm/orm.go
+++ b/src/testing/lib/orm/orm.go
@@ -17,18 +17,104 @@ package orm
import (
"context"
"database/sql"
+ "github.com/beego/beego/v2/core/utils"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
)
// FakeOrmer ...
-type FakeOrmer struct{}
+type FakeOrmer struct {
+}
+
+func (f *FakeOrmer) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeOrmer) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) orm.QueryM2Mer {
+ return nil
+}
+
+func (f *FakeOrmer) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) orm.QuerySeter {
+ return nil
+}
+
+func (f *FakeOrmer) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeOrmer) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeOrmer) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeOrmer) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeOrmer) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeOrmer) RawWithCtx(ctx context.Context, query string, args ...interface{}) orm.RawSeter {
+ return nil
+}
+
+func (f *FakeOrmer) Begin() (orm.TxOrmer, error) {
+ return &FakeTxOrmer{}, nil
+}
+
+func (f *FakeOrmer) BeginWithCtx(ctx context.Context) (orm.TxOrmer, error) {
+ return nil, nil
+}
+
+func (f *FakeOrmer) BeginWithOpts(opts *sql.TxOptions) (orm.TxOrmer, error) {
+ return nil, nil
+}
+
+func (f *FakeOrmer) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (orm.TxOrmer, error) {
+ return nil, nil
+}
+
+func (f *FakeOrmer) DoTx(task func(ctx context.Context, txOrm orm.TxOrmer) error) error {
+ return nil
+}
+
+func (f *FakeOrmer) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm orm.TxOrmer) error) error {
+ return nil
+}
+
+func (f *FakeOrmer) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm orm.TxOrmer) error) error {
+ return nil
+}
+
+func (f *FakeOrmer) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm orm.TxOrmer) error) error {
+ return nil
+}
// Read ...
func (f *FakeOrmer) Read(md interface{}, cols ...string) error {
return nil
}
+func (f *FakeOrmer) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ return nil
+}
+
+func (f *FakeOrmer) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ return nil
+}
+
+func (f *FakeOrmer) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ return false, 0, nil
+}
+
+func (f *FakeOrmer) LoadRelatedWithCtx(_ context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
+ return 0, nil
+}
+
// ReadForUpdate ...
func (f *FakeOrmer) ReadForUpdate(md interface{}, cols ...string) error {
return nil
@@ -64,11 +150,6 @@ func (f *FakeOrmer) Delete(md interface{}, cols ...string) (int64, error) {
return 0, nil
}
-// LoadRelated ...
-func (f *FakeOrmer) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
- return 0, nil
-}
-
// QueryM2M ...
func (f *FakeOrmer) QueryM2M(md interface{}, name string) orm.QueryM2Mer {
return nil
@@ -84,11 +165,6 @@ func (f *FakeOrmer) Using(name string) error {
return nil
}
-// Begin ...
-func (f *FakeOrmer) Begin() error {
- return nil
-}
-
// BeginTx ...
func (f *FakeOrmer) BeginTx(ctx context.Context, opts *sql.TxOptions) error {
return nil
@@ -96,17 +172,17 @@ func (f *FakeOrmer) BeginTx(ctx context.Context, opts *sql.TxOptions) error {
// Commit ...
func (f *FakeOrmer) Commit() error {
- return nil
+ return f.Commit()
}
// Rollback ...
func (f *FakeOrmer) Rollback() error {
- return nil
+ return f.Rollback()
}
// Raw ...
func (f *FakeOrmer) Raw(query string, args ...interface{}) orm.RawSeter {
- return nil
+ return &FakeRawSeter{}
}
// Driver ...
@@ -118,3 +194,167 @@ func (f *FakeOrmer) Driver() orm.Driver {
func (f *FakeOrmer) DBStats() *sql.DBStats {
return nil
}
+
+// FakeTxOrmer ...
+type FakeTxOrmer struct {
+}
+
+func (f *FakeTxOrmer) Read(md interface{}, cols ...string) error {
+ return nil
+}
+
+func (f *FakeTxOrmer) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ return nil
+}
+
+func (f *FakeTxOrmer) ReadForUpdate(md interface{}, cols ...string) error {
+ return nil
+}
+
+func (f *FakeTxOrmer) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ return nil
+}
+
+func (f *FakeTxOrmer) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ return false, 0, nil
+}
+
+func (f *FakeTxOrmer) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ return false, 0, nil
+}
+
+func (f *FakeTxOrmer) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) QueryM2M(md interface{}, name string) orm.QueryM2Mer {
+ return nil
+}
+
+func (f *FakeTxOrmer) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) orm.QueryM2Mer {
+ return nil
+}
+
+func (f *FakeTxOrmer) QueryTable(ptrStructOrTableName interface{}) orm.QuerySeter {
+ return nil
+}
+
+func (f *FakeTxOrmer) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) orm.QuerySeter {
+ return nil
+}
+
+func (f *FakeTxOrmer) DBStats() *sql.DBStats {
+ return nil
+}
+
+func (f *FakeTxOrmer) Insert(md interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) InsertMulti(bulk int, mds interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) Update(md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) Delete(md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f *FakeTxOrmer) Raw(query string, args ...interface{}) orm.RawSeter {
+ return &FakeRawSeter{}
+}
+
+func (f *FakeTxOrmer) RawWithCtx(ctx context.Context, query string, args ...interface{}) orm.RawSeter {
+ return nil
+}
+
+func (f *FakeTxOrmer) Driver() orm.Driver {
+ return nil
+}
+
+func (f *FakeTxOrmer) Commit() error {
+ return nil
+}
+
+func (f *FakeTxOrmer) Rollback() error {
+ return nil
+}
+
+func (f *FakeTxOrmer) RollbackUnlessCommit() error {
+ return nil
+}
+
+// FakeTxOrmer ...
+type FakeRawSeter struct {
+}
+
+func (f FakeRawSeter) Exec() (sql.Result, error) {
+ return nil, nil
+}
+
+func (f FakeRawSeter) QueryRow(containers ...interface{}) error {
+ return nil
+}
+
+func (f FakeRawSeter) QueryRows(containers ...interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (f FakeRawSeter) SetArgs(i ...interface{}) orm.RawSeter {
+ return nil
+}
+
+func (f FakeRawSeter) Values(container *[]orm.Params, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f FakeRawSeter) ValuesList(container *[]orm.ParamsList, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f FakeRawSeter) ValuesFlat(container *orm.ParamsList, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (f FakeRawSeter) RowsToMap(result *orm.Params, keyCol, valueCol string) (int64, error) {
+ return 0, nil
+}
+
+func (f FakeRawSeter) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) {
+ return 0, nil
+}
+
+func (f FakeRawSeter) Prepare() (orm.RawPreparer, error) {
+ return nil, nil
+}
diff --git a/src/testing/suite.go b/src/testing/suite.go
index 31cd1e0d7..51fcb6e9f 100644
--- a/src/testing/suite.go
+++ b/src/testing/suite.go
@@ -24,7 +24,7 @@ import (
"sync"
"time"
- o "github.com/beego/beego/orm"
+ o "github.com/beego/beego/v2/client/orm"
"github.com/opencontainers/go-digest"
"github.com/stretchr/testify/suite"
diff --git a/src/vendor/github.com/beego/beego/.gitignore b/src/vendor/github.com/beego/beego/.gitignore
deleted file mode 100644
index e1b652910..000000000
--- a/src/vendor/github.com/beego/beego/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.idea
-.vscode
-.DS_Store
-*.swp
-*.swo
-beego.iml
diff --git a/src/vendor/github.com/beego/beego/.travis.yml b/src/vendor/github.com/beego/beego/.travis.yml
deleted file mode 100644
index 05b206701..000000000
--- a/src/vendor/github.com/beego/beego/.travis.yml
+++ /dev/null
@@ -1,73 +0,0 @@
-language: go
-
-go:
- - "1.13.x"
-services:
- - redis-server
- - mysql
- - postgresql
- - memcached
-env:
- global:
- - GO_REPO_FULLNAME="github.com/beego/beego"
- matrix:
- - ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db
- - ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
-before_install:
- # link the local repo with ${GOPATH}/src//
- - GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*}
- # relies on GOPATH to contain only one directory...
- - mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE}
- - ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME}
- - cd ${GOPATH}/src/${GO_REPO_FULLNAME}
- # get and build ssdb
- - git clone git://github.com/ideawu/ssdb.git
- - cd ssdb
- - make
- - cd ..
-install:
- - go get github.com/lib/pq
- - go get github.com/go-sql-driver/mysql
- - go get github.com/mattn/go-sqlite3
- - go get github.com/bradfitz/gomemcache/memcache
- - go get github.com/gomodule/redigo/redis
- - go get github.com/beego/x2j
- - go get github.com/couchbase/go-couchbase
- - go get github.com/beego/goyaml2
- - go get gopkg.in/yaml.v2
- - go get github.com/belogik/goes
- - go get github.com/ledisdb/ledisdb
- - go get github.com/ssdb/gossdb/ssdb
- - go get github.com/cloudflare/golz4
- - go get github.com/gogo/protobuf/proto
- - go get github.com/Knetic/govaluate
- - go get github.com/casbin/casbin
- - go get github.com/elazarl/go-bindata-assetfs
- - go get github.com/OwnLocal/goes
- - go get github.com/shiena/ansicolor
- - go get -u honnef.co/go/tools/cmd/staticcheck
- - go get -u github.com/mdempsky/unconvert
- - go get -u github.com/gordonklaus/ineffassign
- - go get -u golang.org/x/lint/golint
- - go get -u github.com/go-redis/redis
-before_script:
- - psql --version
- - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"
- - sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi"
- - sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi"
- - sh -c "go get github.com/golang/lint/golint; golint ./...;"
- - sh -c "go list ./... | grep -v vendor | xargs go vet -v"
- - mkdir -p res/var
- - ./ssdb/ssdb-server ./ssdb/ssdb.conf -d
-after_script:
- - killall -w ssdb-server
- - rm -rf ./res/var/*
-script:
- - go test -v ./...
- - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024"
- - unconvert $(go list ./... | grep -v /vendor/)
- - ineffassign .
- - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s
- - golint ./...
-addons:
- postgresql: "9.6"
diff --git a/src/vendor/github.com/beego/beego/CONTRIBUTING.md b/src/vendor/github.com/beego/beego/CONTRIBUTING.md
deleted file mode 100644
index f21f5e5a9..000000000
--- a/src/vendor/github.com/beego/beego/CONTRIBUTING.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Contributing to beego
-
-beego is an open source project.
-
-It is the work of hundreds of contributors. We appreciate your help!
-
-Here are instructions to get you started. They are probably not perfect,
-please let us know if anything feels wrong or incomplete.
-
-## Contribution guidelines
-
-### Pull requests
-
-First of all. beego follow the gitflow. So please send you pull request
-to **develop** branch. We will close the pull request to master branch.
-
-We are always happy to receive pull requests, and do our best to
-review them as fast as possible. Not sure if that typo is worth a pull
-request? Do it! We will appreciate it.
-
-If your pull request is not accepted on the first try, don't be
-discouraged! Sometimes we can make a mistake, please do more explaining
-for us. We will appreciate it.
-
-We're trying very hard to keep beego simple and fast. We don't want it
-to do everything for everybody. This means that we might decide against
-incorporating a new feature. But we will give you some advice on how to
-do it in other way.
-
-### Create issues
-
-Any significant improvement should be documented as [a GitHub
-issue](https://github.com/beego/beego/issues) before anybody
-starts working on it.
-
-Also when filing an issue, make sure to answer these five questions:
-
-- What version of beego are you using (bee version)?
-- What operating system and processor architecture are you using?
-- What did you do?
-- What did you expect to see?
-- What did you see instead?
-
-### but check existing issues and docs first!
-
-Please take a moment to check that an issue doesn't already exist
-documenting your bug report or improvement proposal. If it does, it
-never hurts to add a quick "+1" or "I have this problem too". This will
-help prioritize the most common problems and requests.
-
-Also if you don't know how to use it. please make sure you have read though
-the docs in http://beego.me/docs
\ No newline at end of file
diff --git a/src/vendor/github.com/beego/beego/README.md b/src/vendor/github.com/beego/beego/README.md
deleted file mode 100644
index f7d3a0772..000000000
--- a/src/vendor/github.com/beego/beego/README.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Beego [](https://travis-ci.org/astaxie/beego) [](http://godoc.org/github.com/beego/beego) [](http://golangfoundation.org) [](https://goreportcard.com/report/github.com/beego/beego)
-
-
-beego is used for rapid development of RESTful APIs, web apps and backend services in Go.
-It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding.
-
-###### More info at [beego.me](http://beego.me).
-
-## Quick Start
-
-#### Create `hello` directory, cd `hello` directory
-
- mkdir hello
- cd hello
-
-#### Init module
-
- go mod init
-
-#### Download and install
-
- go get github.com/beego/beego
-
-#### Create file `hello.go`
-```go
-package main
-
-import "github.com/beego/beego"
-
-func main(){
- beego.Run()
-}
-```
-#### Build and run
-
- go build hello.go
- ./hello
-
-#### Go to [http://localhost:8080](http://localhost:8080)
-
-Congratulations! You've just built your first **beego** app.
-
-###### Please see [Documentation](http://beego.me/docs) for more.
-
-###### [beego-example](https://github.com/beego-dev/beego-example)
-
-## Features
-
-* RESTful support
-* MVC architecture
-* Modularity
-* Auto API documents
-* Annotation router
-* Namespace
-* Powerful development tools
-* Full stack for Web & API
-
-## Documentation
-
-* [English](http://beego.me/docs/intro/)
-* [中文文档](http://beego.me/docs/intro/)
-* [Русский](http://beego.me/docs/intro/)
-
-## Community
-
-* [http://beego.me/community](http://beego.me/community)
-* Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited from [here](https://github.com/beego/beedoc/issues/232)
-* QQ Group Group ID:523992905
-
-## License
-
-beego source code is licensed under the Apache Licence, Version 2.0
-(http://www.apache.org/licenses/LICENSE-2.0.html).
diff --git a/src/vendor/github.com/beego/beego/admin.go b/src/vendor/github.com/beego/beego/admin.go
deleted file mode 100644
index 08991ff8b..000000000
--- a/src/vendor/github.com/beego/beego/admin.go
+++ /dev/null
@@ -1,458 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beego
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "net/http"
- "os"
- "reflect"
- "strconv"
- "text/template"
- "time"
-
- "github.com/prometheus/client_golang/prometheus/promhttp"
-
- "github.com/beego/beego/grace"
- "github.com/beego/beego/logs"
- "github.com/beego/beego/toolbox"
- "github.com/beego/beego/utils"
-)
-
-// BeeAdminApp is the default adminApp used by admin module.
-var beeAdminApp *adminApp
-
-// FilterMonitorFunc is default monitor filter when admin module is enable.
-// if this func returns, admin module records qps for this request by condition of this function logic.
-// usage:
-// func MyFilterMonitor(method, requestPath string, t time.Duration, pattern string, statusCode int) bool {
-// if method == "POST" {
-// return false
-// }
-// if t.Nanoseconds() < 100 {
-// return false
-// }
-// if strings.HasPrefix(requestPath, "/astaxie") {
-// return false
-// }
-// return true
-// }
-// beego.FilterMonitorFunc = MyFilterMonitor.
-var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
-
-func init() {
- beeAdminApp = &adminApp{
- routers: make(map[string]http.HandlerFunc),
- }
- // keep in mind that all data should be html escaped to avoid XSS attack
- beeAdminApp.Route("/", adminIndex)
- beeAdminApp.Route("/qps", qpsIndex)
- beeAdminApp.Route("/prof", profIndex)
- beeAdminApp.Route("/healthcheck", healthcheck)
- beeAdminApp.Route("/task", taskStatus)
- beeAdminApp.Route("/listconf", listConf)
- beeAdminApp.Route("/metrics", promhttp.Handler().ServeHTTP)
- FilterMonitorFunc = func(string, string, time.Duration, string, int) bool { return true }
-}
-
-// AdminIndex is the default http.Handler for admin module.
-// it matches url pattern "/".
-func adminIndex(rw http.ResponseWriter, _ *http.Request) {
- writeTemplate(rw, map[interface{}]interface{}{}, indexTpl, defaultScriptsTpl)
-}
-
-// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
-// it's registered with url pattern "/qps" in admin module.
-func qpsIndex(rw http.ResponseWriter, _ *http.Request) {
- data := make(map[interface{}]interface{})
- data["Content"] = toolbox.StatisticsMap.GetMap()
-
- // do html escape before display path, avoid xss
- if content, ok := (data["Content"]).(M); ok {
- if resultLists, ok := (content["Data"]).([][]string); ok {
- for i := range resultLists {
- if len(resultLists[i]) > 0 {
- resultLists[i][0] = template.HTMLEscapeString(resultLists[i][0])
- }
- }
- }
- }
-
- writeTemplate(rw, data, qpsTpl, defaultScriptsTpl)
-}
-
-// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
-// it's registered with url pattern "/listconf" in admin module.
-func listConf(rw http.ResponseWriter, r *http.Request) {
- r.ParseForm()
- command := r.Form.Get("command")
- if command == "" {
- rw.Write([]byte("command not support"))
- return
- }
-
- data := make(map[interface{}]interface{})
- switch command {
- case "conf":
- m := make(M)
- list("BConfig", BConfig, m)
- m["AppConfigPath"] = template.HTMLEscapeString(appConfigPath)
- m["AppConfigProvider"] = template.HTMLEscapeString(appConfigProvider)
- tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
- tmpl = template.Must(tmpl.Parse(configTpl))
- tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
-
- data["Content"] = m
-
- tmpl.Execute(rw, data)
-
- case "router":
- content := PrintTree()
- content["Fields"] = []string{
- "Router Pattern",
- "Methods",
- "Controller",
- }
- data["Content"] = content
- data["Title"] = "Routers"
- writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
- case "filter":
- var (
- content = M{
- "Fields": []string{
- "Router Pattern",
- "Filter Function",
- },
- }
- filterTypes = []string{}
- filterTypeData = make(M)
- )
-
- if BeeApp.Handlers.enableFilter {
- var filterType string
- for k, fr := range map[int]string{
- BeforeStatic: "Before Static",
- BeforeRouter: "Before Router",
- BeforeExec: "Before Exec",
- AfterExec: "After Exec",
- FinishRouter: "Finish Router"} {
- if bf := BeeApp.Handlers.filters[k]; len(bf) > 0 {
- filterType = fr
- filterTypes = append(filterTypes, filterType)
- resultList := new([][]string)
- for _, f := range bf {
- var result = []string{
- // void xss
- template.HTMLEscapeString(f.pattern),
- template.HTMLEscapeString(utils.GetFuncName(f.filterFunc)),
- }
- *resultList = append(*resultList, result)
- }
- filterTypeData[filterType] = resultList
- }
- }
- }
-
- content["Data"] = filterTypeData
- content["Methods"] = filterTypes
-
- data["Content"] = content
- data["Title"] = "Filters"
- writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
- default:
- rw.Write([]byte("command not support"))
- }
-}
-
-func list(root string, p interface{}, m M) {
- pt := reflect.TypeOf(p)
- pv := reflect.ValueOf(p)
- if pt.Kind() == reflect.Ptr {
- pt = pt.Elem()
- pv = pv.Elem()
- }
- for i := 0; i < pv.NumField(); i++ {
- var key string
- if root == "" {
- key = pt.Field(i).Name
- } else {
- key = root + "." + pt.Field(i).Name
- }
- if pv.Field(i).Kind() == reflect.Struct {
- list(key, pv.Field(i).Interface(), m)
- } else {
- m[key] = pv.Field(i).Interface()
- }
- }
-}
-
-// PrintTree prints all registered routers.
-func PrintTree() M {
- var (
- content = M{}
- methods = []string{}
- methodsData = make(M)
- )
- for method, t := range BeeApp.Handlers.routers {
-
- resultList := new([][]string)
-
- printTree(resultList, t)
-
- methods = append(methods, template.HTMLEscapeString(method))
- methodsData[template.HTMLEscapeString(method)] = resultList
- }
-
- content["Data"] = methodsData
- content["Methods"] = methods
- return content
-}
-
-func printTree(resultList *[][]string, t *Tree) {
- for _, tr := range t.fixrouters {
- printTree(resultList, tr)
- }
- if t.wildcard != nil {
- printTree(resultList, t.wildcard)
- }
- for _, l := range t.leaves {
- if v, ok := l.runObject.(*ControllerInfo); ok {
- if v.routerType == routerTypeBeego {
- var result = []string{
- template.HTMLEscapeString(v.pattern),
- template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
- template.HTMLEscapeString(v.controllerType.String()),
- }
- *resultList = append(*resultList, result)
- } else if v.routerType == routerTypeRESTFul {
- var result = []string{
- template.HTMLEscapeString(v.pattern),
- template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
- "",
- }
- *resultList = append(*resultList, result)
- } else if v.routerType == routerTypeHandler {
- var result = []string{
- template.HTMLEscapeString(v.pattern),
- "",
- "",
- }
- *resultList = append(*resultList, result)
- }
- }
- }
-}
-
-// ProfIndex is a http.Handler for showing profile command.
-// it's in url pattern "/prof" in admin module.
-func profIndex(rw http.ResponseWriter, r *http.Request) {
- r.ParseForm()
- command := r.Form.Get("command")
- if command == "" {
- return
- }
-
- var (
- format = r.Form.Get("format")
- data = make(map[interface{}]interface{})
- result bytes.Buffer
- )
- toolbox.ProcessInput(command, &result)
- data["Content"] = template.HTMLEscapeString(result.String())
-
- if format == "json" && command == "gc summary" {
- dataJSON, err := json.Marshal(data)
- if err != nil {
- http.Error(rw, err.Error(), http.StatusInternalServerError)
- return
- }
- writeJSON(rw, dataJSON)
- return
- }
-
- data["Title"] = template.HTMLEscapeString(command)
- defaultTpl := defaultScriptsTpl
- if command == "gc summary" {
- defaultTpl = gcAjaxTpl
- }
- writeTemplate(rw, data, profillingTpl, defaultTpl)
-}
-
-// Healthcheck is a http.Handler calling health checking and showing the result.
-// it's in "/healthcheck" pattern in admin module.
-func healthcheck(rw http.ResponseWriter, r *http.Request) {
- var (
- result []string
- data = make(map[interface{}]interface{})
- resultList = new([][]string)
- content = M{
- "Fields": []string{"Name", "Message", "Status"},
- }
- )
-
- for name, h := range toolbox.AdminCheckList {
- if err := h.Check(); err != nil {
- result = []string{
- "error",
- template.HTMLEscapeString(name),
- template.HTMLEscapeString(err.Error()),
- }
- } else {
- result = []string{
- "success",
- template.HTMLEscapeString(name),
- "OK",
- }
- }
- *resultList = append(*resultList, result)
- }
-
- queryParams := r.URL.Query()
- jsonFlag := queryParams.Get("json")
- shouldReturnJSON, _ := strconv.ParseBool(jsonFlag)
-
- if shouldReturnJSON {
- response := buildHealthCheckResponseList(resultList)
- jsonResponse, err := json.Marshal(response)
-
- if err != nil {
- http.Error(rw, err.Error(), http.StatusInternalServerError)
- } else {
- writeJSON(rw, jsonResponse)
- }
- return
- }
-
- content["Data"] = resultList
- data["Content"] = content
- data["Title"] = "Health Check"
-
- writeTemplate(rw, data, healthCheckTpl, defaultScriptsTpl)
-}
-
-func buildHealthCheckResponseList(healthCheckResults *[][]string) []map[string]interface{} {
- response := make([]map[string]interface{}, len(*healthCheckResults))
-
- for i, healthCheckResult := range *healthCheckResults {
- currentResultMap := make(map[string]interface{})
-
- currentResultMap["name"] = healthCheckResult[0]
- currentResultMap["message"] = healthCheckResult[1]
- currentResultMap["status"] = healthCheckResult[2]
-
- response[i] = currentResultMap
- }
-
- return response
-
-}
-
-func writeJSON(rw http.ResponseWriter, jsonData []byte) {
- rw.Header().Set("Content-Type", "application/json")
- rw.Write(jsonData)
-}
-
-// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
-// it's in "/task" pattern in admin module.
-func taskStatus(rw http.ResponseWriter, req *http.Request) {
- data := make(map[interface{}]interface{})
-
- // Run Task
- req.ParseForm()
- taskname := req.Form.Get("taskname")
- if taskname != "" {
- if t, ok := toolbox.AdminTaskList[taskname]; ok {
- if err := t.Run(); err != nil {
- data["Message"] = []string{"error", template.HTMLEscapeString(fmt.Sprintf("%s", err))}
- }
- data["Message"] = []string{"success", template.HTMLEscapeString(fmt.Sprintf("%s run success,Now the Status is
%s", taskname, t.GetStatus()))}
- } else {
- data["Message"] = []string{"warning", template.HTMLEscapeString(fmt.Sprintf("there's no task which named: %s", taskname))}
- }
- }
-
- // List Tasks
- content := make(M)
- resultList := new([][]string)
- var fields = []string{
- "Task Name",
- "Task Spec",
- "Task Status",
- "Last Time",
- "",
- }
- for tname, tk := range toolbox.AdminTaskList {
- result := []string{
- template.HTMLEscapeString(tname),
- template.HTMLEscapeString(tk.GetSpec()),
- template.HTMLEscapeString(tk.GetStatus()),
- template.HTMLEscapeString(tk.GetPrev().String()),
- }
- *resultList = append(*resultList, result)
- }
-
- content["Fields"] = fields
- content["Data"] = resultList
- data["Content"] = content
- data["Title"] = "Tasks"
- writeTemplate(rw, data, tasksTpl, defaultScriptsTpl)
-}
-
-func writeTemplate(rw http.ResponseWriter, data map[interface{}]interface{}, tpls ...string) {
- tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
- for _, tpl := range tpls {
- tmpl = template.Must(tmpl.Parse(tpl))
- }
- tmpl.Execute(rw, data)
-}
-
-// adminApp is an http.HandlerFunc map used as beeAdminApp.
-type adminApp struct {
- routers map[string]http.HandlerFunc
-}
-
-// Route adds http.HandlerFunc to adminApp with url pattern.
-func (admin *adminApp) Route(pattern string, f http.HandlerFunc) {
- admin.routers[pattern] = f
-}
-
-// Run adminApp http server.
-// Its addr is defined in configuration file as adminhttpaddr and adminhttpport.
-func (admin *adminApp) Run() {
- if len(toolbox.AdminTaskList) > 0 {
- toolbox.StartTask()
- }
- addr := BConfig.Listen.AdminAddr
-
- if BConfig.Listen.AdminPort != 0 {
- addr = fmt.Sprintf("%s:%d", BConfig.Listen.AdminAddr, BConfig.Listen.AdminPort)
- }
- for p, f := range admin.routers {
- http.Handle(p, f)
- }
- logs.Info("Admin server Running on %s", addr)
-
- var err error
- if BConfig.Listen.Graceful {
- err = grace.ListenAndServe(addr, nil)
- } else {
- err = http.ListenAndServe(addr, nil)
- }
- if err != nil {
- logs.Critical("Admin ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
- }
-}
diff --git a/src/vendor/github.com/beego/beego/app.go b/src/vendor/github.com/beego/beego/app.go
deleted file mode 100644
index 6dc185e7a..000000000
--- a/src/vendor/github.com/beego/beego/app.go
+++ /dev/null
@@ -1,496 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beego
-
-import (
- "crypto/tls"
- "crypto/x509"
- "fmt"
- "io/ioutil"
- "net"
- "net/http"
- "net/http/fcgi"
- "os"
- "path"
- "strings"
- "time"
-
- "github.com/beego/beego/grace"
- "github.com/beego/beego/logs"
- "github.com/beego/beego/utils"
- "golang.org/x/crypto/acme/autocert"
-)
-
-var (
- // BeeApp is an application instance
- BeeApp *App
-)
-
-func init() {
- // create beego application
- BeeApp = NewApp()
-}
-
-// App defines beego application with a new PatternServeMux.
-type App struct {
- Handlers *ControllerRegister
- Server *http.Server
-}
-
-// NewApp returns a new beego application.
-func NewApp() *App {
- cr := NewControllerRegister()
- app := &App{Handlers: cr, Server: &http.Server{}}
- return app
-}
-
-// MiddleWare function for http.Handler
-type MiddleWare func(http.Handler) http.Handler
-
-// Run beego application.
-func (app *App) Run(mws ...MiddleWare) {
- addr := BConfig.Listen.HTTPAddr
-
- if BConfig.Listen.HTTPPort != 0 {
- addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPAddr, BConfig.Listen.HTTPPort)
- }
-
- var (
- err error
- l net.Listener
- endRunning = make(chan bool, 1)
- )
-
- // run cgi server
- if BConfig.Listen.EnableFcgi {
- if BConfig.Listen.EnableStdIo {
- if err = fcgi.Serve(nil, app.Handlers); err == nil { // standard I/O
- logs.Info("Use FCGI via standard I/O")
- } else {
- logs.Critical("Cannot use FCGI via standard I/O", err)
- }
- return
- }
- if BConfig.Listen.HTTPPort == 0 {
- // remove the Socket file before start
- if utils.FileExists(addr) {
- os.Remove(addr)
- }
- l, err = net.Listen("unix", addr)
- } else {
- l, err = net.Listen("tcp", addr)
- }
- if err != nil {
- logs.Critical("Listen: ", err)
- }
- if err = fcgi.Serve(l, app.Handlers); err != nil {
- logs.Critical("fcgi.Serve: ", err)
- }
- return
- }
-
- app.Server.Handler = app.Handlers
- for i := len(mws) - 1; i >= 0; i-- {
- if mws[i] == nil {
- continue
- }
- app.Server.Handler = mws[i](app.Server.Handler)
- }
- app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
- app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
- app.Server.ErrorLog = logs.GetLogger("HTTP")
-
- // run graceful mode
- if BConfig.Listen.Graceful {
- httpsAddr := BConfig.Listen.HTTPSAddr
- app.Server.Addr = httpsAddr
- if BConfig.Listen.EnableHTTPS || BConfig.Listen.EnableMutualHTTPS {
- go func() {
- time.Sleep(1000 * time.Microsecond)
- if BConfig.Listen.HTTPSPort != 0 {
- httpsAddr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
- app.Server.Addr = httpsAddr
- }
- server := grace.NewServer(httpsAddr, app.Server.Handler)
- server.Server.ReadTimeout = app.Server.ReadTimeout
- server.Server.WriteTimeout = app.Server.WriteTimeout
- if BConfig.Listen.EnableMutualHTTPS {
- if err := server.ListenAndServeMutualTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile, BConfig.Listen.TrustCaFile); err != nil {
- logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
- time.Sleep(100 * time.Microsecond)
- }
- } else {
- if BConfig.Listen.AutoTLS {
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist(BConfig.Listen.Domains...),
- Cache: autocert.DirCache(BConfig.Listen.TLSCacheDir),
- }
- app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
- BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile = "", ""
- }
- if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
- logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
- time.Sleep(100 * time.Microsecond)
- }
- }
- endRunning <- true
- }()
- }
- if BConfig.Listen.EnableHTTP {
- go func() {
- server := grace.NewServer(addr, app.Server.Handler)
- server.Server.ReadTimeout = app.Server.ReadTimeout
- server.Server.WriteTimeout = app.Server.WriteTimeout
- if BConfig.Listen.ListenTCP4 {
- server.Network = "tcp4"
- }
- if err := server.ListenAndServe(); err != nil {
- logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
- time.Sleep(100 * time.Microsecond)
- }
- endRunning <- true
- }()
- }
- <-endRunning
- return
- }
-
- // run normal mode
- if BConfig.Listen.EnableHTTPS || BConfig.Listen.EnableMutualHTTPS {
- go func() {
- time.Sleep(1000 * time.Microsecond)
- if BConfig.Listen.HTTPSPort != 0 {
- app.Server.Addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
- } else if BConfig.Listen.EnableHTTP {
- logs.Info("Start https server error, conflict with http. Please reset https port")
- return
- }
- logs.Info("https server Running on https://%s", app.Server.Addr)
- if BConfig.Listen.AutoTLS {
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist(BConfig.Listen.Domains...),
- Cache: autocert.DirCache(BConfig.Listen.TLSCacheDir),
- }
- app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
- BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile = "", ""
- } else if BConfig.Listen.EnableMutualHTTPS {
- pool := x509.NewCertPool()
- data, err := ioutil.ReadFile(BConfig.Listen.TrustCaFile)
- if err != nil {
- logs.Info("MutualHTTPS should provide TrustCaFile")
- return
- }
- pool.AppendCertsFromPEM(data)
- app.Server.TLSConfig = &tls.Config{
- ClientCAs: pool,
- ClientAuth: BConfig.Listen.ClientAuth,
- }
- }
- if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
- logs.Critical("ListenAndServeTLS: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- }
- }()
-
- }
- if BConfig.Listen.EnableHTTP {
- go func() {
- app.Server.Addr = addr
- logs.Info("http server Running on http://%s", app.Server.Addr)
- if BConfig.Listen.ListenTCP4 {
- ln, err := net.Listen("tcp4", app.Server.Addr)
- if err != nil {
- logs.Critical("ListenAndServe: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- return
- }
- if err = app.Server.Serve(ln); err != nil {
- logs.Critical("ListenAndServe: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- return
- }
- } else {
- if err := app.Server.ListenAndServe(); err != nil {
- logs.Critical("ListenAndServe: ", err)
- time.Sleep(100 * time.Microsecond)
- endRunning <- true
- }
- }
- }()
- }
- <-endRunning
-}
-
-// Router adds a patterned controller handler to BeeApp.
-// it's an alias method of App.Router.
-// usage:
-// simple router
-// beego.Router("/admin", &admin.UserController{})
-// beego.Router("/admin/index", &admin.ArticleController{})
-//
-// regex router
-//
-// beego.Router("/api/:id([0-9]+)", &controllers.RController{})
-//
-// custom rules
-// beego.Router("/api/list",&RestController{},"*:ListFood")
-// beego.Router("/api/create",&RestController{},"post:CreateFood")
-// beego.Router("/api/update",&RestController{},"put:UpdateFood")
-// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
-func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
- BeeApp.Handlers.Add(rootpath, c, mappingMethods...)
- return BeeApp
-}
-
-// UnregisterFixedRoute unregisters the route with the specified fixedRoute. It is particularly useful
-// in web applications that inherit most routes from a base webapp via the underscore
-// import, and aim to overwrite only certain paths.
-// The method parameter can be empty or "*" for all HTTP methods, or a particular
-// method type (e.g. "GET" or "POST") for selective removal.
-//
-// Usage (replace "GET" with "*" for all methods):
-// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
-// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
-func UnregisterFixedRoute(fixedRoute string, method string) *App {
- subPaths := splitPath(fixedRoute)
- if method == "" || method == "*" {
- for m := range HTTPMETHOD {
- if _, ok := BeeApp.Handlers.routers[m]; !ok {
- continue
- }
- if BeeApp.Handlers.routers[m].prefix == strings.Trim(fixedRoute, "/ ") {
- findAndRemoveSingleTree(BeeApp.Handlers.routers[m])
- continue
- }
- findAndRemoveTree(subPaths, BeeApp.Handlers.routers[m], m)
- }
- return BeeApp
- }
- // Single HTTP method
- um := strings.ToUpper(method)
- if _, ok := BeeApp.Handlers.routers[um]; ok {
- if BeeApp.Handlers.routers[um].prefix == strings.Trim(fixedRoute, "/ ") {
- findAndRemoveSingleTree(BeeApp.Handlers.routers[um])
- return BeeApp
- }
- findAndRemoveTree(subPaths, BeeApp.Handlers.routers[um], um)
- }
- return BeeApp
-}
-
-func findAndRemoveTree(paths []string, entryPointTree *Tree, method string) {
- for i := range entryPointTree.fixrouters {
- if entryPointTree.fixrouters[i].prefix == paths[0] {
- if len(paths) == 1 {
- if len(entryPointTree.fixrouters[i].fixrouters) > 0 {
- // If the route had children subtrees, remove just the functional leaf,
- // to allow children to function as before
- if len(entryPointTree.fixrouters[i].leaves) > 0 {
- entryPointTree.fixrouters[i].leaves[0] = nil
- entryPointTree.fixrouters[i].leaves = entryPointTree.fixrouters[i].leaves[1:]
- }
- } else {
- // Remove the *Tree from the fixrouters slice
- entryPointTree.fixrouters[i] = nil
-
- if i == len(entryPointTree.fixrouters)-1 {
- entryPointTree.fixrouters = entryPointTree.fixrouters[:i]
- } else {
- entryPointTree.fixrouters = append(entryPointTree.fixrouters[:i], entryPointTree.fixrouters[i+1:len(entryPointTree.fixrouters)]...)
- }
- }
- return
- }
- findAndRemoveTree(paths[1:], entryPointTree.fixrouters[i], method)
- }
- }
-}
-
-func findAndRemoveSingleTree(entryPointTree *Tree) {
- if entryPointTree == nil {
- return
- }
- if len(entryPointTree.fixrouters) > 0 {
- // If the route had children subtrees, remove just the functional leaf,
- // to allow children to function as before
- if len(entryPointTree.leaves) > 0 {
- entryPointTree.leaves[0] = nil
- entryPointTree.leaves = entryPointTree.leaves[1:]
- }
- }
-}
-
-// Include will generate router file in the router/xxx.go from the controller's comments
-// usage:
-// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
-// type BankAccount struct{
-// beego.Controller
-// }
-//
-// register the function
-// func (b *BankAccount)Mapping(){
-// b.Mapping("ShowAccount" , b.ShowAccount)
-// b.Mapping("ModifyAccount", b.ModifyAccount)
-//}
-//
-// //@router /account/:id [get]
-// func (b *BankAccount) ShowAccount(){
-// //logic
-// }
-//
-//
-// //@router /account/:id [post]
-// func (b *BankAccount) ModifyAccount(){
-// //logic
-// }
-//
-// the comments @router url methodlist
-// url support all the function Router's pattern
-// methodlist [get post head put delete options *]
-func Include(cList ...ControllerInterface) *App {
- BeeApp.Handlers.Include(cList...)
- return BeeApp
-}
-
-// RESTRouter adds a restful controller handler to BeeApp.
-// its' controller implements beego.ControllerInterface and
-// defines a param "pattern/:objectId" to visit each resource.
-func RESTRouter(rootpath string, c ControllerInterface) *App {
- Router(rootpath, c)
- Router(path.Join(rootpath, ":objectId"), c)
- return BeeApp
-}
-
-// AutoRouter adds defined controller handler to BeeApp.
-// it's same to App.AutoRouter.
-// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page,
-// visit the url /main/list to exec List function or /main/page to exec Page function.
-func AutoRouter(c ControllerInterface) *App {
- BeeApp.Handlers.AddAuto(c)
- return BeeApp
-}
-
-// AutoPrefix adds controller handler to BeeApp with prefix.
-// it's same to App.AutoRouterWithPrefix.
-// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page,
-// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function.
-func AutoPrefix(prefix string, c ControllerInterface) *App {
- BeeApp.Handlers.AddAutoPrefix(prefix, c)
- return BeeApp
-}
-
-// Get used to register router for Get method
-// usage:
-// beego.Get("/", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Get(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Get(rootpath, f)
- return BeeApp
-}
-
-// Post used to register router for Post method
-// usage:
-// beego.Post("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Post(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Post(rootpath, f)
- return BeeApp
-}
-
-// Delete used to register router for Delete method
-// usage:
-// beego.Delete("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Delete(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Delete(rootpath, f)
- return BeeApp
-}
-
-// Put used to register router for Put method
-// usage:
-// beego.Put("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Put(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Put(rootpath, f)
- return BeeApp
-}
-
-// Head used to register router for Head method
-// usage:
-// beego.Head("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Head(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Head(rootpath, f)
- return BeeApp
-}
-
-// Options used to register router for Options method
-// usage:
-// beego.Options("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Options(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Options(rootpath, f)
- return BeeApp
-}
-
-// Patch used to register router for Patch method
-// usage:
-// beego.Patch("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Patch(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Patch(rootpath, f)
- return BeeApp
-}
-
-// Any used to register router for all methods
-// usage:
-// beego.Any("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func Any(rootpath string, f FilterFunc) *App {
- BeeApp.Handlers.Any(rootpath, f)
- return BeeApp
-}
-
-// Handler used to register a Handler router
-// usage:
-// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
-// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
-// }))
-func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
- BeeApp.Handlers.Handler(rootpath, h, options...)
- return BeeApp
-}
-
-// InsertFilter adds a FilterFunc with pattern condition and action constant.
-// The pos means action constant including
-// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
-// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
-func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App {
- BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...)
- return BeeApp
-}
diff --git a/src/vendor/github.com/beego/beego/cache/file.go b/src/vendor/github.com/beego/beego/cache/file.go
deleted file mode 100644
index 6f12d3eee..000000000
--- a/src/vendor/github.com/beego/beego/cache/file.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cache
-
-import (
- "bytes"
- "crypto/md5"
- "encoding/gob"
- "encoding/hex"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "reflect"
- "strconv"
- "time"
-)
-
-// FileCacheItem is basic unit of file cache adapter.
-// it contains data and expire time.
-type FileCacheItem struct {
- Data interface{}
- Lastaccess time.Time
- Expired time.Time
-}
-
-// FileCache Config
-var (
- FileCachePath = "cache" // cache directory
- FileCacheFileSuffix = ".bin" // cache file suffix
- FileCacheDirectoryLevel = 2 // cache file deep level if auto generated cache files.
- FileCacheEmbedExpiry time.Duration // cache expire time, default is no expire forever.
-)
-
-// FileCache is cache adapter for file storage.
-type FileCache struct {
- CachePath string
- FileSuffix string
- DirectoryLevel int
- EmbedExpiry int
-}
-
-// NewFileCache Create new file cache with no config.
-// the level and expiry need set in method StartAndGC as config string.
-func NewFileCache() Cache {
- // return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
- return &FileCache{}
-}
-
-// StartAndGC will start and begin gc for file cache.
-// the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}
-func (fc *FileCache) StartAndGC(config string) error {
-
- cfg := make(map[string]string)
- err := json.Unmarshal([]byte(config), &cfg)
- if err != nil {
- return err
- }
- if _, ok := cfg["CachePath"]; !ok {
- cfg["CachePath"] = FileCachePath
- }
- if _, ok := cfg["FileSuffix"]; !ok {
- cfg["FileSuffix"] = FileCacheFileSuffix
- }
- if _, ok := cfg["DirectoryLevel"]; !ok {
- cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel)
- }
- if _, ok := cfg["EmbedExpiry"]; !ok {
- cfg["EmbedExpiry"] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10)
- }
- fc.CachePath = cfg["CachePath"]
- fc.FileSuffix = cfg["FileSuffix"]
- fc.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"])
- fc.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"])
-
- fc.Init()
- return nil
-}
-
-// Init will make new dir for file cache if not exist.
-func (fc *FileCache) Init() {
- if ok, _ := exists(fc.CachePath); !ok { // todo : error handle
- _ = os.MkdirAll(fc.CachePath, os.ModePerm) // todo : error handle
- }
-}
-
-// get cached file name. it's md5 encoded.
-func (fc *FileCache) getCacheFileName(key string) string {
- m := md5.New()
- io.WriteString(m, key)
- keyMd5 := hex.EncodeToString(m.Sum(nil))
- cachePath := fc.CachePath
- switch fc.DirectoryLevel {
- case 2:
- cachePath = filepath.Join(cachePath, keyMd5[0:2], keyMd5[2:4])
- case 1:
- cachePath = filepath.Join(cachePath, keyMd5[0:2])
- }
-
- if ok, _ := exists(cachePath); !ok { // todo : error handle
- _ = os.MkdirAll(cachePath, os.ModePerm) // todo : error handle
- }
-
- return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, fc.FileSuffix))
-}
-
-// Get value from file cache.
-// if non-exist or expired, return empty string.
-func (fc *FileCache) Get(key string) interface{} {
- fileData, err := FileGetContents(fc.getCacheFileName(key))
- if err != nil {
- return ""
- }
- var to FileCacheItem
- GobDecode(fileData, &to)
- if to.Expired.Before(time.Now()) {
- return ""
- }
- return to.Data
-}
-
-// GetMulti gets values from file cache.
-// if non-exist or expired, return empty string.
-func (fc *FileCache) GetMulti(keys []string) []interface{} {
- var rc []interface{}
- for _, key := range keys {
- rc = append(rc, fc.Get(key))
- }
- return rc
-}
-
-// Put value into file cache.
-// timeout means how long to keep this file, unit of ms.
-// if timeout equals fc.EmbedExpiry(default is 0), cache this item forever.
-func (fc *FileCache) Put(key string, val interface{}, timeout time.Duration) error {
- gob.Register(val)
-
- item := FileCacheItem{Data: val}
- if timeout == time.Duration(fc.EmbedExpiry) {
- item.Expired = time.Now().Add((86400 * 365 * 10) * time.Second) // ten years
- } else {
- item.Expired = time.Now().Add(timeout)
- }
- item.Lastaccess = time.Now()
- data, err := GobEncode(item)
- if err != nil {
- return err
- }
- return FilePutContents(fc.getCacheFileName(key), data)
-}
-
-// Delete file cache value.
-func (fc *FileCache) Delete(key string) error {
- filename := fc.getCacheFileName(key)
- if ok, _ := exists(filename); ok {
- return os.Remove(filename)
- }
- return nil
-}
-
-// Incr will increase cached int value.
-// fc value is saving forever unless Delete.
-func (fc *FileCache) Incr(key string) error {
- data := fc.Get(key)
- var incr int
- if reflect.TypeOf(data).Name() != "int" {
- incr = 0
- } else {
- incr = data.(int) + 1
- }
- fc.Put(key, incr, time.Duration(fc.EmbedExpiry))
- return nil
-}
-
-// Decr will decrease cached int value.
-func (fc *FileCache) Decr(key string) error {
- data := fc.Get(key)
- var decr int
- if reflect.TypeOf(data).Name() != "int" || data.(int)-1 <= 0 {
- decr = 0
- } else {
- decr = data.(int) - 1
- }
- fc.Put(key, decr, time.Duration(fc.EmbedExpiry))
- return nil
-}
-
-// IsExist check value is exist.
-func (fc *FileCache) IsExist(key string) bool {
- ret, _ := exists(fc.getCacheFileName(key))
- return ret
-}
-
-// ClearAll will clean cached files.
-// not implemented.
-func (fc *FileCache) ClearAll() error {
- return nil
-}
-
-// check file exist.
-func exists(path string) (bool, error) {
- _, err := os.Stat(path)
- if err == nil {
- return true, nil
- }
- if os.IsNotExist(err) {
- return false, nil
- }
- return false, err
-}
-
-// FileGetContents Get bytes to file.
-// if non-exist, create this file.
-func FileGetContents(filename string) (data []byte, e error) {
- return ioutil.ReadFile(filename)
-}
-
-// FilePutContents Put bytes to file.
-// if non-exist, create this file.
-func FilePutContents(filename string, content []byte) error {
- return ioutil.WriteFile(filename, content, os.ModePerm)
-}
-
-// GobEncode Gob encodes file cache item.
-func GobEncode(data interface{}) ([]byte, error) {
- buf := bytes.NewBuffer(nil)
- enc := gob.NewEncoder(buf)
- err := enc.Encode(data)
- if err != nil {
- return nil, err
- }
- return buf.Bytes(), err
-}
-
-// GobDecode Gob decodes file cache item.
-func GobDecode(data []byte, to *FileCacheItem) error {
- buf := bytes.NewBuffer(data)
- dec := gob.NewDecoder(buf)
- return dec.Decode(&to)
-}
-
-func init() {
- Register("file", NewFileCache)
-}
diff --git a/src/vendor/github.com/beego/beego/cache/memory.go b/src/vendor/github.com/beego/beego/cache/memory.go
deleted file mode 100644
index d8314e3cc..000000000
--- a/src/vendor/github.com/beego/beego/cache/memory.go
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cache
-
-import (
- "encoding/json"
- "errors"
- "sync"
- "time"
-)
-
-var (
- // DefaultEvery means the clock time of recycling the expired cache items in memory.
- DefaultEvery = 60 // 1 minute
-)
-
-// MemoryItem store memory cache item.
-type MemoryItem struct {
- val interface{}
- createdTime time.Time
- lifespan time.Duration
-}
-
-func (mi *MemoryItem) isExpire() bool {
- // 0 means forever
- if mi.lifespan == 0 {
- return false
- }
- return time.Now().Sub(mi.createdTime) > mi.lifespan
-}
-
-// MemoryCache is Memory cache adapter.
-// it contains a RW locker for safe map storage.
-type MemoryCache struct {
- sync.RWMutex
- dur time.Duration
- items map[string]*MemoryItem
- Every int // run an expiration check Every clock time
-}
-
-// NewMemoryCache returns a new MemoryCache.
-func NewMemoryCache() Cache {
- cache := MemoryCache{items: make(map[string]*MemoryItem)}
- return &cache
-}
-
-// Get cache from memory.
-// if non-existed or expired, return nil.
-func (bc *MemoryCache) Get(name string) interface{} {
- bc.RLock()
- defer bc.RUnlock()
- if itm, ok := bc.items[name]; ok {
- if itm.isExpire() {
- return nil
- }
- return itm.val
- }
- return nil
-}
-
-// GetMulti gets caches from memory.
-// if non-existed or expired, return nil.
-func (bc *MemoryCache) GetMulti(names []string) []interface{} {
- var rc []interface{}
- for _, name := range names {
- rc = append(rc, bc.Get(name))
- }
- return rc
-}
-
-// Put cache to memory.
-// if lifespan is 0, it will be forever till restart.
-func (bc *MemoryCache) Put(name string, value interface{}, lifespan time.Duration) error {
- bc.Lock()
- defer bc.Unlock()
- bc.items[name] = &MemoryItem{
- val: value,
- createdTime: time.Now(),
- lifespan: lifespan,
- }
- return nil
-}
-
-// Delete cache in memory.
-func (bc *MemoryCache) Delete(name string) error {
- bc.Lock()
- defer bc.Unlock()
- if _, ok := bc.items[name]; !ok {
- return errors.New("key not exist")
- }
- delete(bc.items, name)
- if _, ok := bc.items[name]; ok {
- return errors.New("delete key error")
- }
- return nil
-}
-
-// Incr increase cache counter in memory.
-// it supports int,int32,int64,uint,uint32,uint64.
-func (bc *MemoryCache) Incr(key string) error {
- bc.Lock()
- defer bc.Unlock()
- itm, ok := bc.items[key]
- if !ok {
- return errors.New("key not exist")
- }
- switch val := itm.val.(type) {
- case int:
- itm.val = val + 1
- case int32:
- itm.val = val + 1
- case int64:
- itm.val = val + 1
- case uint:
- itm.val = val + 1
- case uint32:
- itm.val = val + 1
- case uint64:
- itm.val = val + 1
- default:
- return errors.New("item val is not (u)int (u)int32 (u)int64")
- }
- return nil
-}
-
-// Decr decrease counter in memory.
-func (bc *MemoryCache) Decr(key string) error {
- bc.Lock()
- defer bc.Unlock()
- itm, ok := bc.items[key]
- if !ok {
- return errors.New("key not exist")
- }
- switch val := itm.val.(type) {
- case int:
- itm.val = val - 1
- case int64:
- itm.val = val - 1
- case int32:
- itm.val = val - 1
- case uint:
- if val > 0 {
- itm.val = val - 1
- } else {
- return errors.New("item val is less than 0")
- }
- case uint32:
- if val > 0 {
- itm.val = val - 1
- } else {
- return errors.New("item val is less than 0")
- }
- case uint64:
- if val > 0 {
- itm.val = val - 1
- } else {
- return errors.New("item val is less than 0")
- }
- default:
- return errors.New("item val is not int int64 int32")
- }
- return nil
-}
-
-// IsExist check cache exist in memory.
-func (bc *MemoryCache) IsExist(name string) bool {
- bc.RLock()
- defer bc.RUnlock()
- if v, ok := bc.items[name]; ok {
- return !v.isExpire()
- }
- return false
-}
-
-// ClearAll will delete all cache in memory.
-func (bc *MemoryCache) ClearAll() error {
- bc.Lock()
- defer bc.Unlock()
- bc.items = make(map[string]*MemoryItem)
- return nil
-}
-
-// StartAndGC start memory cache. it will check expiration in every clock time.
-func (bc *MemoryCache) StartAndGC(config string) error {
- var cf map[string]int
- json.Unmarshal([]byte(config), &cf)
- if _, ok := cf["interval"]; !ok {
- cf = make(map[string]int)
- cf["interval"] = DefaultEvery
- }
- dur := time.Duration(cf["interval"]) * time.Second
- bc.Every = cf["interval"]
- bc.dur = dur
- go bc.vacuum()
- return nil
-}
-
-// check expiration.
-func (bc *MemoryCache) vacuum() {
- bc.RLock()
- every := bc.Every
- bc.RUnlock()
-
- if every < 1 {
- return
- }
- for {
- <-time.After(bc.dur)
- bc.RLock()
- if bc.items == nil {
- bc.RUnlock()
- return
- }
- bc.RUnlock()
- if keys := bc.expiredKeys(); len(keys) != 0 {
- bc.clearItems(keys)
- }
- }
-}
-
-// expiredKeys returns key list which are expired.
-func (bc *MemoryCache) expiredKeys() (keys []string) {
- bc.RLock()
- defer bc.RUnlock()
- for key, itm := range bc.items {
- if itm.isExpire() {
- keys = append(keys, key)
- }
- }
- return
-}
-
-// clearItems removes all the items which key in keys.
-func (bc *MemoryCache) clearItems(keys []string) {
- bc.Lock()
- defer bc.Unlock()
- for _, key := range keys {
- delete(bc.items, key)
- }
-}
-
-func init() {
- Register("memory", NewMemoryCache)
-}
diff --git a/src/vendor/github.com/beego/beego/config.go b/src/vendor/github.com/beego/beego/config.go
deleted file mode 100644
index ffa89edde..000000000
--- a/src/vendor/github.com/beego/beego/config.go
+++ /dev/null
@@ -1,537 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beego
-
-import (
- "crypto/tls"
- "fmt"
- "net/http"
- "os"
- "path/filepath"
- "reflect"
- "runtime"
- "strings"
-
- "github.com/beego/beego/config"
- "github.com/beego/beego/context"
- "github.com/beego/beego/logs"
- "github.com/beego/beego/session"
- "github.com/beego/beego/utils"
-)
-
-// Config is the main struct for BConfig
-type Config struct {
- AppName string // Application name
- RunMode string // Running Mode: dev | prod
- RouterCaseSensitive bool
- ServerName string
- RecoverPanic bool
- RecoverFunc func(*context.Context)
- CopyRequestBody bool
- EnableGzip bool
- MaxMemory int64
- EnableErrorsShow bool
- EnableErrorsRender bool
- Listen Listen
- WebConfig WebConfig
- Log LogConfig
-}
-
-// Listen holds for http and https related config
-type Listen struct {
- Graceful bool // Graceful means use graceful module to start the server
- ServerTimeOut int64
- ListenTCP4 bool
- EnableHTTP bool
- HTTPAddr string
- HTTPPort int
- AutoTLS bool
- Domains []string
- TLSCacheDir string
- EnableHTTPS bool
- EnableMutualHTTPS bool
- HTTPSAddr string
- HTTPSPort int
- HTTPSCertFile string
- HTTPSKeyFile string
- TrustCaFile string
- ClientAuth tls.ClientAuthType
- EnableAdmin bool
- AdminAddr string
- AdminPort int
- EnableFcgi bool
- EnableStdIo bool // EnableStdIo works with EnableFcgi Use FCGI via standard I/O
-}
-
-// WebConfig holds web related config
-type WebConfig struct {
- AutoRender bool
- EnableDocs bool
- FlashName string
- FlashSeparator string
- DirectoryIndex bool
- StaticDir map[string]string
- StaticExtensionsToGzip []string
- StaticCacheFileSize int
- StaticCacheFileNum int
- TemplateLeft string
- TemplateRight string
- ViewsPath string
- EnableXSRF bool
- XSRFKey string
- XSRFExpire int
- XSRFSecure bool
- XSRFHttpOnly bool
- Session SessionConfig
-}
-
-// SessionConfig holds session related config
-type SessionConfig struct {
- SessionOn bool
- SessionProvider string
- SessionName string
- SessionGCMaxLifetime int64
- SessionProviderConfig string
- SessionCookieLifeTime int
- SessionAutoSetCookie bool
- SessionDomain string
- SessionDisableHTTPOnly bool // used to allow for cross domain cookies/javascript cookies.
- SessionEnableSidInHTTPHeader bool // enable store/get the sessionId into/from http headers
- SessionNameInHTTPHeader string
- SessionEnableSidInURLQuery bool // enable get the sessionId from Url Query params
- SessionCookieSameSite http.SameSite
-}
-
-// LogConfig holds Log related config
-type LogConfig struct {
- AccessLogs bool
- EnableStaticLogs bool // log static files requests default: false
- AccessLogsFormat string // access log format: JSON_FORMAT, APACHE_FORMAT or empty string
- FileLineNum bool
- Outputs map[string]string // Store Adaptor : config
-}
-
-var (
- // BConfig is the default config for Application
- BConfig *Config
- // AppConfig is the instance of Config, store the config information from file
- AppConfig *beegoAppConfig
- // AppPath is the absolute path to the app
- AppPath string
- // GlobalSessions is the instance for the session manager
- GlobalSessions *session.Manager
-
- // appConfigPath is the path to the config files
- appConfigPath string
- // appConfigProvider is the provider for the config, default is ini
- appConfigProvider = "ini"
- // WorkPath is the absolute path to project root directory
- WorkPath string
-)
-
-func init() {
- BConfig = newBConfig()
- var err error
- if AppPath, err = filepath.Abs(filepath.Dir(os.Args[0])); err != nil {
- panic(err)
- }
- WorkPath, err = os.Getwd()
- if err != nil {
- panic(err)
- }
- var filename = "app.conf"
- if os.Getenv("BEEGO_RUNMODE") != "" {
- filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
- }
- appConfigPath = filepath.Join(WorkPath, "conf", filename)
- if configPath := os.Getenv("BEEGO_CONFIG_PATH"); configPath != "" {
- appConfigPath = configPath
- }
- if !utils.FileExists(appConfigPath) {
- appConfigPath = filepath.Join(AppPath, "conf", filename)
- if !utils.FileExists(appConfigPath) {
- AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()}
- return
- }
- }
- if err = parseConfig(appConfigPath); err != nil {
- panic(err)
- }
-}
-
-func recoverPanic(ctx *context.Context) {
- if err := recover(); err != nil {
- if err == ErrAbort {
- return
- }
- if !BConfig.RecoverPanic {
- panic(err)
- }
- if BConfig.EnableErrorsShow {
- if _, ok := ErrorMaps[fmt.Sprint(err)]; ok {
- exception(fmt.Sprint(err), ctx)
- return
- }
- }
- var stack string
- logs.Critical("the request url is ", ctx.Input.URL())
- logs.Critical("Handler crashed with error", err)
- for i := 1; ; i++ {
- _, file, line, ok := runtime.Caller(i)
- if !ok {
- break
- }
- logs.Critical(fmt.Sprintf("%s:%d", file, line))
- stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
- }
- if BConfig.RunMode == DEV && BConfig.EnableErrorsRender {
- showErr(err, ctx, stack)
- }
- if ctx.Output.Status != 0 {
- ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
- } else {
- ctx.ResponseWriter.WriteHeader(500)
- }
- }
-}
-
-func newBConfig() *Config {
- return &Config{
- AppName: "beego",
- RunMode: PROD,
- RouterCaseSensitive: true,
- ServerName: "beegoServer:" + VERSION,
- RecoverPanic: true,
- RecoverFunc: recoverPanic,
- CopyRequestBody: false,
- EnableGzip: false,
- MaxMemory: 1 << 26, // 64MB
- EnableErrorsShow: true,
- EnableErrorsRender: true,
- Listen: Listen{
- Graceful: false,
- ServerTimeOut: 0,
- ListenTCP4: false,
- EnableHTTP: true,
- AutoTLS: false,
- Domains: []string{},
- TLSCacheDir: ".",
- HTTPAddr: "",
- HTTPPort: 8080,
- EnableHTTPS: false,
- HTTPSAddr: "",
- HTTPSPort: 10443,
- HTTPSCertFile: "",
- HTTPSKeyFile: "",
- EnableAdmin: false,
- AdminAddr: "",
- AdminPort: 8088,
- EnableFcgi: false,
- EnableStdIo: false,
- ClientAuth: tls.RequireAndVerifyClientCert,
- },
- WebConfig: WebConfig{
- AutoRender: true,
- EnableDocs: false,
- FlashName: "BEEGO_FLASH",
- FlashSeparator: "BEEGOFLASH",
- DirectoryIndex: false,
- StaticDir: map[string]string{"/static": "static"},
- StaticExtensionsToGzip: []string{".css", ".js"},
- StaticCacheFileSize: 1024 * 100,
- StaticCacheFileNum: 1000,
- TemplateLeft: "{{",
- TemplateRight: "}}",
- ViewsPath: "views",
- EnableXSRF: false,
- XSRFKey: "beegoxsrf",
- XSRFExpire: 0,
- XSRFSecure: false,
- XSRFHttpOnly: false,
- Session: SessionConfig{
- SessionOn: false,
- SessionProvider: "memory",
- SessionName: "beegosessionID",
- SessionGCMaxLifetime: 3600,
- SessionProviderConfig: "",
- SessionDisableHTTPOnly: false,
- SessionCookieLifeTime: 0, // set cookie default is the browser life
- SessionAutoSetCookie: true,
- SessionDomain: "",
- SessionEnableSidInHTTPHeader: false, // enable store/get the sessionId into/from http headers
- SessionNameInHTTPHeader: "Beegosessionid",
- SessionEnableSidInURLQuery: false, // enable get the sessionId from Url Query params
- SessionCookieSameSite: http.SameSiteDefaultMode,
- },
- },
- Log: LogConfig{
- AccessLogs: false,
- EnableStaticLogs: false,
- AccessLogsFormat: "APACHE_FORMAT",
- FileLineNum: true,
- Outputs: map[string]string{"console": ""},
- },
- }
-}
-
-// now only support ini, next will support json.
-func parseConfig(appConfigPath string) (err error) {
- AppConfig, err = newAppConfig(appConfigProvider, appConfigPath)
- if err != nil {
- return err
- }
- return assignConfig(AppConfig)
-}
-
-func assignConfig(ac config.Configer) error {
- for _, i := range []interface{}{BConfig, &BConfig.Listen, &BConfig.WebConfig, &BConfig.Log, &BConfig.WebConfig.Session} {
- assignSingleConfig(i, ac)
- }
- // set the run mode first
- if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
- BConfig.RunMode = envRunMode
- } else if runMode := ac.String("RunMode"); runMode != "" {
- BConfig.RunMode = runMode
- }
-
- if sd := ac.String("StaticDir"); sd != "" {
- BConfig.WebConfig.StaticDir = map[string]string{}
- sds := strings.Fields(sd)
- for _, v := range sds {
- if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 {
- BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[1]
- } else {
- BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[0]
- }
- }
- }
-
- if sgz := ac.String("StaticExtensionsToGzip"); sgz != "" {
- extensions := strings.Split(sgz, ",")
- fileExts := []string{}
- for _, ext := range extensions {
- ext = strings.TrimSpace(ext)
- if ext == "" {
- continue
- }
- if !strings.HasPrefix(ext, ".") {
- ext = "." + ext
- }
- fileExts = append(fileExts, ext)
- }
- if len(fileExts) > 0 {
- BConfig.WebConfig.StaticExtensionsToGzip = fileExts
- }
- }
-
- if sfs, err := ac.Int("StaticCacheFileSize"); err == nil {
- BConfig.WebConfig.StaticCacheFileSize = sfs
- }
-
- if sfn, err := ac.Int("StaticCacheFileNum"); err == nil {
- BConfig.WebConfig.StaticCacheFileNum = sfn
- }
-
- if lo := ac.String("LogOutputs"); lo != "" {
- // if lo is not nil or empty
- // means user has set his own LogOutputs
- // clear the default setting to BConfig.Log.Outputs
- BConfig.Log.Outputs = make(map[string]string)
- los := strings.Split(lo, ";")
- for _, v := range los {
- if logType2Config := strings.SplitN(v, ",", 2); len(logType2Config) == 2 {
- BConfig.Log.Outputs[logType2Config[0]] = logType2Config[1]
- } else {
- continue
- }
- }
- }
-
- // init log
- logs.Reset()
- for adaptor, config := range BConfig.Log.Outputs {
- err := logs.SetLogger(adaptor, config)
- if err != nil {
- fmt.Fprintln(os.Stderr, fmt.Sprintf("%s with the config %q got err:%s", adaptor, config, err.Error()))
- }
- }
- logs.SetLogFuncCall(BConfig.Log.FileLineNum)
-
- return nil
-}
-
-func assignSingleConfig(p interface{}, ac config.Configer) {
- pt := reflect.TypeOf(p)
- if pt.Kind() != reflect.Ptr {
- return
- }
- pt = pt.Elem()
- if pt.Kind() != reflect.Struct {
- return
- }
- pv := reflect.ValueOf(p).Elem()
-
- for i := 0; i < pt.NumField(); i++ {
- pf := pv.Field(i)
- if !pf.CanSet() {
- continue
- }
- name := pt.Field(i).Name
- switch pf.Kind() {
- case reflect.String:
- pf.SetString(ac.DefaultString(name, pf.String()))
- case reflect.Int, reflect.Int64:
- pf.SetInt(ac.DefaultInt64(name, pf.Int()))
- case reflect.Bool:
- pf.SetBool(ac.DefaultBool(name, pf.Bool()))
- case reflect.Struct:
- default:
- // do nothing here
- }
- }
-
-}
-
-// LoadAppConfig allow developer to apply a config file
-func LoadAppConfig(adapterName, configPath string) error {
- absConfigPath, err := filepath.Abs(configPath)
- if err != nil {
- return err
- }
-
- if !utils.FileExists(absConfigPath) {
- return fmt.Errorf("the target config file: %s don't exist", configPath)
- }
-
- appConfigPath = absConfigPath
- appConfigProvider = adapterName
-
- return parseConfig(appConfigPath)
-}
-
-type beegoAppConfig struct {
- innerConfig config.Configer
-}
-
-func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, error) {
- ac, err := config.NewConfig(appConfigProvider, appConfigPath)
- if err != nil {
- return nil, err
- }
- return &beegoAppConfig{ac}, nil
-}
-
-func (b *beegoAppConfig) Set(key, val string) error {
- if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
- return b.innerConfig.Set(key, val)
- }
- return nil
-}
-
-func (b *beegoAppConfig) String(key string) string {
- if v := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" {
- return v
- }
- return b.innerConfig.String(key)
-}
-
-func (b *beegoAppConfig) Strings(key string) []string {
- if v := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 {
- return v
- }
- return b.innerConfig.Strings(key)
-}
-
-func (b *beegoAppConfig) Int(key string) (int, error) {
- if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Int(key)
-}
-
-func (b *beegoAppConfig) Int64(key string) (int64, error) {
- if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Int64(key)
-}
-
-func (b *beegoAppConfig) Bool(key string) (bool, error) {
- if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Bool(key)
-}
-
-func (b *beegoAppConfig) Float(key string) (float64, error) {
- if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
- return v, nil
- }
- return b.innerConfig.Float(key)
-}
-
-func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
- if v := b.String(key); v != "" {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
- if v := b.Strings(key); len(v) != 0 {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
- if v, err := b.Int(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
- if v, err := b.Int64(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
- if v, err := b.Bool(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
- if v, err := b.Float(key); err == nil {
- return v
- }
- return defaultVal
-}
-
-func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
- return b.innerConfig.DIY(key)
-}
-
-func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
- return b.innerConfig.GetSection(section)
-}
-
-func (b *beegoAppConfig) SaveConfigFile(filename string) error {
- return b.innerConfig.SaveConfigFile(filename)
-}
diff --git a/src/vendor/github.com/beego/beego/config/json.go b/src/vendor/github.com/beego/beego/config/json.go
deleted file mode 100644
index c4ef25cd3..000000000
--- a/src/vendor/github.com/beego/beego/config/json.go
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package config
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "os"
- "strconv"
- "strings"
- "sync"
-)
-
-// JSONConfig is a json config parser and implements Config interface.
-type JSONConfig struct {
-}
-
-// Parse returns a ConfigContainer with parsed json config map.
-func (js *JSONConfig) Parse(filename string) (Configer, error) {
- file, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer file.Close()
- content, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
-
- return js.ParseData(content)
-}
-
-// ParseData returns a ConfigContainer with json string
-func (js *JSONConfig) ParseData(data []byte) (Configer, error) {
- x := &JSONConfigContainer{
- data: make(map[string]interface{}),
- }
- err := json.Unmarshal(data, &x.data)
- if err != nil {
- var wrappingArray []interface{}
- err2 := json.Unmarshal(data, &wrappingArray)
- if err2 != nil {
- return nil, err
- }
- x.data["rootArray"] = wrappingArray
- }
-
- x.data = ExpandValueEnvForMap(x.data)
-
- return x, nil
-}
-
-// JSONConfigContainer A Config represents the json configuration.
-// Only when get value, support key as section:name type.
-type JSONConfigContainer struct {
- data map[string]interface{}
- sync.RWMutex
-}
-
-// Bool returns the boolean value for a given key.
-func (c *JSONConfigContainer) Bool(key string) (bool, error) {
- val := c.getData(key)
- if val != nil {
- return ParseBool(val)
- }
- return false, fmt.Errorf("not exist key: %q", key)
-}
-
-// DefaultBool return the bool value if has no error
-// otherwise return the defaultval
-func (c *JSONConfigContainer) DefaultBool(key string, defaultval bool) bool {
- if v, err := c.Bool(key); err == nil {
- return v
- }
- return defaultval
-}
-
-// Int returns the integer value for a given key.
-func (c *JSONConfigContainer) Int(key string) (int, error) {
- val := c.getData(key)
- if val != nil {
- if v, ok := val.(float64); ok {
- return int(v), nil
- } else if v, ok := val.(string); ok {
- return strconv.Atoi(v)
- }
- return 0, errors.New("not valid value")
- }
- return 0, errors.New("not exist key:" + key)
-}
-
-// DefaultInt returns the integer value for a given key.
-// if err != nil return defaultval
-func (c *JSONConfigContainer) DefaultInt(key string, defaultval int) int {
- if v, err := c.Int(key); err == nil {
- return v
- }
- return defaultval
-}
-
-// Int64 returns the int64 value for a given key.
-func (c *JSONConfigContainer) Int64(key string) (int64, error) {
- val := c.getData(key)
- if val != nil {
- if v, ok := val.(float64); ok {
- return int64(v), nil
- }
- return 0, errors.New("not int64 value")
- }
- return 0, errors.New("not exist key:" + key)
-}
-
-// DefaultInt64 returns the int64 value for a given key.
-// if err != nil return defaultval
-func (c *JSONConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
- if v, err := c.Int64(key); err == nil {
- return v
- }
- return defaultval
-}
-
-// Float returns the float value for a given key.
-func (c *JSONConfigContainer) Float(key string) (float64, error) {
- val := c.getData(key)
- if val != nil {
- if v, ok := val.(float64); ok {
- return v, nil
- }
- return 0.0, errors.New("not float64 value")
- }
- return 0.0, errors.New("not exist key:" + key)
-}
-
-// DefaultFloat returns the float64 value for a given key.
-// if err != nil return defaultval
-func (c *JSONConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
- if v, err := c.Float(key); err == nil {
- return v
- }
- return defaultval
-}
-
-// String returns the string value for a given key.
-func (c *JSONConfigContainer) String(key string) string {
- val := c.getData(key)
- if val != nil {
- if v, ok := val.(string); ok {
- return v
- }
- }
- return ""
-}
-
-// DefaultString returns the string value for a given key.
-// if err != nil return defaultval
-func (c *JSONConfigContainer) DefaultString(key string, defaultval string) string {
- // TODO FIXME should not use "" to replace non existence
- if v := c.String(key); v != "" {
- return v
- }
- return defaultval
-}
-
-// Strings returns the []string value for a given key.
-func (c *JSONConfigContainer) Strings(key string) []string {
- stringVal := c.String(key)
- if stringVal == "" {
- return nil
- }
- return strings.Split(c.String(key), ";")
-}
-
-// DefaultStrings returns the []string value for a given key.
-// if err != nil return defaultval
-func (c *JSONConfigContainer) DefaultStrings(key string, defaultval []string) []string {
- if v := c.Strings(key); v != nil {
- return v
- }
- return defaultval
-}
-
-// GetSection returns map for the given section
-func (c *JSONConfigContainer) GetSection(section string) (map[string]string, error) {
- if v, ok := c.data[section]; ok {
- return v.(map[string]string), nil
- }
- return nil, errors.New("nonexist section " + section)
-}
-
-// SaveConfigFile save the config into file
-func (c *JSONConfigContainer) SaveConfigFile(filename string) (err error) {
- // Write configuration file by filename.
- f, err := os.Create(filename)
- if err != nil {
- return err
- }
- defer f.Close()
- b, err := json.MarshalIndent(c.data, "", " ")
- if err != nil {
- return err
- }
- _, err = f.Write(b)
- return err
-}
-
-// Set writes a new value for key.
-func (c *JSONConfigContainer) Set(key, val string) error {
- c.Lock()
- defer c.Unlock()
- c.data[key] = val
- return nil
-}
-
-// DIY returns the raw value by a given key.
-func (c *JSONConfigContainer) DIY(key string) (v interface{}, err error) {
- val := c.getData(key)
- if val != nil {
- return val, nil
- }
- return nil, errors.New("not exist key")
-}
-
-// section.key or key
-func (c *JSONConfigContainer) getData(key string) interface{} {
- if len(key) == 0 {
- return nil
- }
-
- c.RLock()
- defer c.RUnlock()
-
- sectionKeys := strings.Split(key, "::")
- if len(sectionKeys) >= 2 {
- curValue, ok := c.data[sectionKeys[0]]
- if !ok {
- return nil
- }
- for _, key := range sectionKeys[1:] {
- if v, ok := curValue.(map[string]interface{}); ok {
- if curValue, ok = v[key]; !ok {
- return nil
- }
- }
- }
- return curValue
- }
- if v, ok := c.data[key]; ok {
- return v
- }
- return nil
-}
-
-func init() {
- Register("json", &JSONConfig{})
-}
diff --git a/src/vendor/github.com/beego/beego/context/context.go b/src/vendor/github.com/beego/beego/context/context.go
deleted file mode 100644
index bd83e825c..000000000
--- a/src/vendor/github.com/beego/beego/context/context.go
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Package context provide the context utils
-// Usage:
-//
-// import "github.com/beego/beego/context"
-//
-// ctx := context.Context{Request:req,ResponseWriter:rw}
-//
-// more docs http://beego.me/docs/module/context.md
-package context
-
-import (
- "bufio"
- "crypto/hmac"
- "crypto/sha256"
- "encoding/base64"
- "errors"
- "fmt"
- "net"
- "net/http"
- "strconv"
- "strings"
- "time"
-
- "github.com/beego/beego/utils"
-)
-
-//commonly used mime-types
-const (
- ApplicationJSON = "application/json"
- ApplicationXML = "application/xml"
- ApplicationYAML = "application/x-yaml"
- TextXML = "text/xml"
-)
-
-// NewContext return the Context with Input and Output
-func NewContext() *Context {
- return &Context{
- Input: NewInput(),
- Output: NewOutput(),
- }
-}
-
-// Context Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter.
-// BeegoInput and BeegoOutput provides some api to operate request and response more easily.
-type Context struct {
- Input *BeegoInput
- Output *BeegoOutput
- Request *http.Request
- ResponseWriter *Response
- _xsrfToken string
-}
-
-// Reset init Context, BeegoInput and BeegoOutput
-func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
- ctx.Request = r
- if ctx.ResponseWriter == nil {
- ctx.ResponseWriter = &Response{}
- }
- ctx.ResponseWriter.reset(rw)
- ctx.Input.Reset(ctx)
- ctx.Output.Reset(ctx)
- ctx._xsrfToken = ""
-}
-
-// Redirect does redirection to localurl with http header status code.
-func (ctx *Context) Redirect(status int, localurl string) {
- http.Redirect(ctx.ResponseWriter, ctx.Request, localurl, status)
-}
-
-// Abort stops this request.
-// if beego.ErrorMaps exists, panic body.
-func (ctx *Context) Abort(status int, body string) {
- ctx.Output.SetStatus(status)
- panic(body)
-}
-
-// WriteString Write string to response body.
-// it sends response body.
-func (ctx *Context) WriteString(content string) {
- ctx.ResponseWriter.Write([]byte(content))
-}
-
-// GetCookie Get cookie from request by a given key.
-// It's alias of BeegoInput.Cookie.
-func (ctx *Context) GetCookie(key string) string {
- return ctx.Input.Cookie(key)
-}
-
-// SetCookie Set cookie for response.
-// It's alias of BeegoOutput.Cookie.
-func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
- ctx.Output.Cookie(name, value, others...)
-}
-
-// GetSecureCookie Get secure cookie from request by a given key.
-func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
- val := ctx.Input.Cookie(key)
- if val == "" {
- return "", false
- }
-
- parts := strings.SplitN(val, "|", 3)
-
- if len(parts) != 3 {
- return "", false
- }
-
- vs := parts[0]
- timestamp := parts[1]
- sig := parts[2]
-
- h := hmac.New(sha256.New, []byte(Secret))
- fmt.Fprintf(h, "%s%s", vs, timestamp)
-
- if fmt.Sprintf("%02x", h.Sum(nil)) != sig {
- return "", false
- }
- res, _ := base64.URLEncoding.DecodeString(vs)
- return string(res), true
-}
-
-// SetSecureCookie Set Secure cookie for response.
-func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
- vs := base64.URLEncoding.EncodeToString([]byte(value))
- timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
- h := hmac.New(sha256.New, []byte(Secret))
- fmt.Fprintf(h, "%s%s", vs, timestamp)
- sig := fmt.Sprintf("%02x", h.Sum(nil))
- cookie := strings.Join([]string{vs, timestamp, sig}, "|")
- ctx.Output.Cookie(name, cookie, others...)
-}
-
-// XSRFToken creates a xsrf token string and returns.
-// others[0] bool secure
-// others[1] bool http-only
-func (ctx *Context) XSRFToken(key string, expire int64, others ...interface{}) string {
- if ctx._xsrfToken == "" {
- token, ok := ctx.GetSecureCookie(key, "_xsrf")
- if !ok {
- token = string(utils.RandomCreateBytes(32))
- secure := false
- if len(others) > 0 {
- secure = others[0].(bool)
- }
- httpOnly := false
- if len(others) > 1 {
- httpOnly = others[1].(bool)
- }
- ctx.SetSecureCookie(key, "_xsrf", token, expire, "", "", secure, httpOnly)
- }
- ctx._xsrfToken = token
- }
- return ctx._xsrfToken
-}
-
-// CheckXSRFCookie checks xsrf token in this request is valid or not.
-// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
-// or in form field value named as "_xsrf".
-func (ctx *Context) CheckXSRFCookie() bool {
- token := ctx.Input.Query("_xsrf")
- if token == "" {
- token = ctx.Request.Header.Get("X-Xsrftoken")
- }
- if token == "" {
- token = ctx.Request.Header.Get("X-Csrftoken")
- }
- if token == "" {
- ctx.Abort(422, "422")
- return false
- }
- if ctx._xsrfToken != token {
- ctx.Abort(417, "417")
- return false
- }
- return true
-}
-
-// RenderMethodResult renders the return value of a controller method to the output
-func (ctx *Context) RenderMethodResult(result interface{}) {
- if result != nil {
- renderer, ok := result.(Renderer)
- if !ok {
- err, ok := result.(error)
- if ok {
- renderer = errorRenderer(err)
- } else {
- renderer = jsonRenderer(result)
- }
- }
- renderer.Render(ctx)
- }
-}
-
-//Response is a wrapper for the http.ResponseWriter
-//started set to true if response was written to then don't execute other handler
-type Response struct {
- http.ResponseWriter
- Started bool
- Status int
- Elapsed time.Duration
-}
-
-func (r *Response) reset(rw http.ResponseWriter) {
- r.ResponseWriter = rw
- r.Status = 0
- r.Started = false
-}
-
-// Write writes the data to the connection as part of an HTTP reply,
-// and sets `started` to true.
-// started means the response has sent out.
-func (r *Response) Write(p []byte) (int, error) {
- r.Started = true
- return r.ResponseWriter.Write(p)
-}
-
-// WriteHeader sends an HTTP response header with status code,
-// and sets `started` to true.
-func (r *Response) WriteHeader(code int) {
- if r.Status > 0 {
- //prevent multiple response.WriteHeader calls
- return
- }
- r.Status = code
- r.Started = true
- r.ResponseWriter.WriteHeader(code)
-}
-
-// Hijack hijacker for http
-func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- hj, ok := r.ResponseWriter.(http.Hijacker)
- if !ok {
- return nil, nil, errors.New("webserver doesn't support hijacking")
- }
- return hj.Hijack()
-}
-
-// Flush http.Flusher
-func (r *Response) Flush() {
- if f, ok := r.ResponseWriter.(http.Flusher); ok {
- f.Flush()
- }
-}
-
-// CloseNotify http.CloseNotifier
-func (r *Response) CloseNotify() <-chan bool {
- if cn, ok := r.ResponseWriter.(http.CloseNotifier); ok {
- return cn.CloseNotify()
- }
- return nil
-}
-
-// Pusher http.Pusher
-func (r *Response) Pusher() (pusher http.Pusher) {
- if pusher, ok := r.ResponseWriter.(http.Pusher); ok {
- return pusher
- }
- return nil
-}
diff --git a/src/vendor/github.com/beego/beego/filter.go b/src/vendor/github.com/beego/beego/filter.go
deleted file mode 100644
index f4e74aaf1..000000000
--- a/src/vendor/github.com/beego/beego/filter.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beego
-
-import "github.com/beego/beego/context"
-
-// FilterFunc defines a filter function which is invoked before the controller handler is executed.
-type FilterFunc func(*context.Context)
-
-// FilterRouter defines a filter operation which is invoked before the controller handler is executed.
-// It can match the URL against a pattern, and execute a filter function
-// when a request with a matching URL arrives.
-type FilterRouter struct {
- filterFunc FilterFunc
- tree *Tree
- pattern string
- returnOnOutput bool
- resetParams bool
-}
-
-// ValidRouter checks if the current request is matched by this filter.
-// If the request is matched, the values of the URL parameters defined
-// by the filter pattern are also returned.
-func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
- isOk := f.tree.Match(url, ctx)
- if isOk != nil {
- if b, ok := isOk.(bool); ok {
- return b
- }
- }
- return false
-}
diff --git a/src/vendor/github.com/beego/beego/log.go b/src/vendor/github.com/beego/beego/log.go
deleted file mode 100644
index 27ea86bae..000000000
--- a/src/vendor/github.com/beego/beego/log.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beego
-
-import (
- "strings"
-
- "github.com/beego/beego/logs"
-)
-
-// Log levels to control the logging output.
-// Deprecated: use github.com/beego/beego/logs instead.
-const (
- LevelEmergency = iota
- LevelAlert
- LevelCritical
- LevelError
- LevelWarning
- LevelNotice
- LevelInformational
- LevelDebug
-)
-
-// BeeLogger references the used application logger.
-// Deprecated: use github.com/beego/beego/logs instead.
-var BeeLogger = logs.GetBeeLogger()
-
-// SetLevel sets the global log level used by the simple logger.
-// Deprecated: use github.com/beego/beego/logs instead.
-func SetLevel(l int) {
- logs.SetLevel(l)
-}
-
-// SetLogFuncCall set the CallDepth, default is 3
-// Deprecated: use github.com/beego/beego/logs instead.
-func SetLogFuncCall(b bool) {
- logs.SetLogFuncCall(b)
-}
-
-// SetLogger sets a new logger.
-// Deprecated: use github.com/beego/beego/logs instead.
-func SetLogger(adaptername string, config string) error {
- return logs.SetLogger(adaptername, config)
-}
-
-// Emergency logs a message at emergency level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Emergency(v ...interface{}) {
- logs.Emergency(generateFmtStr(len(v)), v...)
-}
-
-// Alert logs a message at alert level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Alert(v ...interface{}) {
- logs.Alert(generateFmtStr(len(v)), v...)
-}
-
-// Critical logs a message at critical level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Critical(v ...interface{}) {
- logs.Critical(generateFmtStr(len(v)), v...)
-}
-
-// Error logs a message at error level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Error(v ...interface{}) {
- logs.Error(generateFmtStr(len(v)), v...)
-}
-
-// Warning logs a message at warning level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Warning(v ...interface{}) {
- logs.Warning(generateFmtStr(len(v)), v...)
-}
-
-// Warn compatibility alias for Warning()
-// Deprecated: use github.com/beego/beego/logs instead.
-func Warn(v ...interface{}) {
- logs.Warn(generateFmtStr(len(v)), v...)
-}
-
-// Notice logs a message at notice level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Notice(v ...interface{}) {
- logs.Notice(generateFmtStr(len(v)), v...)
-}
-
-// Informational logs a message at info level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Informational(v ...interface{}) {
- logs.Informational(generateFmtStr(len(v)), v...)
-}
-
-// Info compatibility alias for Warning()
-// Deprecated: use github.com/beego/beego/logs instead.
-func Info(v ...interface{}) {
- logs.Info(generateFmtStr(len(v)), v...)
-}
-
-// Debug logs a message at debug level.
-// Deprecated: use github.com/beego/beego/logs instead.
-func Debug(v ...interface{}) {
- logs.Debug(generateFmtStr(len(v)), v...)
-}
-
-// Trace logs a message at trace level.
-// compatibility alias for Warning()
-// Deprecated: use github.com/beego/beego/logs instead.
-func Trace(v ...interface{}) {
- logs.Trace(generateFmtStr(len(v)), v...)
-}
-
-func generateFmtStr(n int) string {
- return strings.Repeat("%v ", n)
-}
diff --git a/src/vendor/github.com/beego/beego/logs/slack.go b/src/vendor/github.com/beego/beego/logs/slack.go
deleted file mode 100644
index 1cd2e5aee..000000000
--- a/src/vendor/github.com/beego/beego/logs/slack.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package logs
-
-import (
- "encoding/json"
- "fmt"
- "net/http"
- "net/url"
- "time"
-)
-
-// SLACKWriter implements beego LoggerInterface and is used to send jiaoliao webhook
-type SLACKWriter struct {
- WebhookURL string `json:"webhookurl"`
- Level int `json:"level"`
-}
-
-// newSLACKWriter create jiaoliao writer.
-func newSLACKWriter() Logger {
- return &SLACKWriter{Level: LevelTrace}
-}
-
-// Init SLACKWriter with json config string
-func (s *SLACKWriter) Init(jsonconfig string) error {
- return json.Unmarshal([]byte(jsonconfig), s)
-}
-
-// WriteMsg write message in smtp writer.
-// it will send an email with subject and only this message.
-func (s *SLACKWriter) WriteMsg(when time.Time, msg string, level int) error {
- if level > s.Level {
- return nil
- }
-
- text := fmt.Sprintf("{\"text\": \"%s %s\"}", when.Format("2006-01-02 15:04:05"), msg)
-
- form := url.Values{}
- form.Add("payload", text)
-
- resp, err := http.PostForm(s.WebhookURL, form)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- return fmt.Errorf("Post webhook failed %s %d", resp.Status, resp.StatusCode)
- }
- return nil
-}
-
-// Flush implementing method. empty.
-func (s *SLACKWriter) Flush() {
-}
-
-// Destroy implementing method. empty.
-func (s *SLACKWriter) Destroy() {
-}
-
-func init() {
- Register(AdapterSlack, newSLACKWriter)
-}
diff --git a/src/vendor/github.com/beego/beego/orm/cmd_utils.go b/src/vendor/github.com/beego/beego/orm/cmd_utils.go
deleted file mode 100644
index 692a079fa..000000000
--- a/src/vendor/github.com/beego/beego/orm/cmd_utils.go
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package orm
-
-import (
- "fmt"
- "os"
- "strings"
-)
-
-type dbIndex struct {
- Table string
- Name string
- SQL string
-}
-
-// create database drop sql.
-func getDbDropSQL(al *alias) (sqls []string) {
- if len(modelCache.cache) == 0 {
- fmt.Println("no Model found, need register your model")
- os.Exit(2)
- }
-
- Q := al.DbBaser.TableQuote()
-
- for _, mi := range modelCache.allOrdered() {
- sqls = append(sqls, fmt.Sprintf(`DROP TABLE IF EXISTS %s%s%s`, Q, mi.table, Q))
- }
- return sqls
-}
-
-// get database column type string.
-func getColumnTyp(al *alias, fi *fieldInfo) (col string) {
- T := al.DbBaser.DbTypes()
- fieldType := fi.fieldType
- fieldSize := fi.size
-
-checkColumn:
- switch fieldType {
- case TypeBooleanField:
- col = T["bool"]
- case TypeVarCharField:
- if al.Driver == DRPostgres && fi.toText {
- col = T["string-text"]
- } else {
- col = fmt.Sprintf(T["string"], fieldSize)
- }
- case TypeCharField:
- col = fmt.Sprintf(T["string-char"], fieldSize)
- case TypeTextField:
- col = T["string-text"]
- case TypeTimeField:
- col = T["time.Time-clock"]
- case TypeDateField:
- col = T["time.Time-date"]
- case TypeDateTimeField:
- col = T["time.Time"]
- case TypeBitField:
- col = T["int8"]
- case TypeSmallIntegerField:
- col = T["int16"]
- case TypeIntegerField:
- col = T["int32"]
- case TypeBigIntegerField:
- if al.Driver == DRSqlite {
- fieldType = TypeIntegerField
- goto checkColumn
- }
- col = T["int64"]
- case TypePositiveBitField:
- col = T["uint8"]
- case TypePositiveSmallIntegerField:
- col = T["uint16"]
- case TypePositiveIntegerField:
- col = T["uint32"]
- case TypePositiveBigIntegerField:
- col = T["uint64"]
- case TypeFloatField:
- col = T["float64"]
- case TypeDecimalField:
- s := T["float64-decimal"]
- if !strings.Contains(s, "%d") {
- col = s
- } else {
- col = fmt.Sprintf(s, fi.digits, fi.decimals)
- }
- case TypeJSONField:
- if al.Driver != DRPostgres {
- fieldType = TypeVarCharField
- goto checkColumn
- }
- col = T["json"]
- case TypeJsonbField:
- if al.Driver != DRPostgres {
- fieldType = TypeVarCharField
- goto checkColumn
- }
- col = T["jsonb"]
- case RelForeignKey, RelOneToOne:
- fieldType = fi.relModelInfo.fields.pk.fieldType
- fieldSize = fi.relModelInfo.fields.pk.size
- goto checkColumn
- }
-
- return
-}
-
-// create alter sql string.
-func getColumnAddQuery(al *alias, fi *fieldInfo) string {
- Q := al.DbBaser.TableQuote()
- typ := getColumnTyp(al, fi)
-
- if !fi.null {
- typ += " " + "NOT NULL"
- }
-
- return fmt.Sprintf("ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s %s",
- Q, fi.mi.table, Q,
- Q, fi.column, Q,
- typ, getColumnDefault(fi),
- )
-}
-
-// create database creation string.
-func getDbCreateSQL(al *alias) (sqls []string, tableIndexes map[string][]dbIndex) {
- if len(modelCache.cache) == 0 {
- fmt.Println("no Model found, need register your model")
- os.Exit(2)
- }
-
- Q := al.DbBaser.TableQuote()
- T := al.DbBaser.DbTypes()
- sep := fmt.Sprintf("%s, %s", Q, Q)
-
- tableIndexes = make(map[string][]dbIndex)
-
- for _, mi := range modelCache.allOrdered() {
- sql := fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
- sql += fmt.Sprintf("-- Table Structure for `%s`\n", mi.fullName)
- sql += fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
-
- sql += fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s%s%s (\n", Q, mi.table, Q)
-
- columns := make([]string, 0, len(mi.fields.fieldsDB))
-
- sqlIndexes := [][]string{}
-
- for _, fi := range mi.fields.fieldsDB {
-
- column := fmt.Sprintf(" %s%s%s ", Q, fi.column, Q)
- col := getColumnTyp(al, fi)
-
- if fi.auto {
- switch al.Driver {
- case DRSqlite, DRPostgres:
- column += T["auto"]
- default:
- column += col + " " + T["auto"]
- }
- } else if fi.pk {
- column += col + " " + T["pk"]
- } else {
- column += col
-
- if !fi.null {
- column += " " + "NOT NULL"
- }
-
- //if fi.initial.String() != "" {
- // column += " DEFAULT " + fi.initial.String()
- //}
-
- // Append attribute DEFAULT
- column += getColumnDefault(fi)
-
- if fi.unique {
- column += " " + "UNIQUE"
- }
-
- if fi.index {
- sqlIndexes = append(sqlIndexes, []string{fi.column})
- }
- }
-
- if strings.Contains(column, "%COL%") {
- column = strings.Replace(column, "%COL%", fi.column, -1)
- }
-
- if fi.description != "" && al.Driver != DRSqlite {
- column += " " + fmt.Sprintf("COMMENT '%s'", fi.description)
- }
-
- columns = append(columns, column)
- }
-
- if mi.model != nil {
- allnames := getTableUnique(mi.addrField)
- if !mi.manual && len(mi.uniques) > 0 {
- allnames = append(allnames, mi.uniques)
- }
- for _, names := range allnames {
- cols := make([]string, 0, len(names))
- for _, name := range names {
- if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
- cols = append(cols, fi.column)
- } else {
- panic(fmt.Errorf("cannot found column `%s` when parse UNIQUE in `%s.TableUnique`", name, mi.fullName))
- }
- }
- column := fmt.Sprintf(" UNIQUE (%s%s%s)", Q, strings.Join(cols, sep), Q)
- columns = append(columns, column)
- }
- }
-
- sql += strings.Join(columns, ",\n")
- sql += "\n)"
-
- if al.Driver == DRMySQL {
- var engine string
- if mi.model != nil {
- engine = getTableEngine(mi.addrField)
- }
- if engine == "" {
- engine = al.Engine
- }
- sql += " ENGINE=" + engine
- }
-
- sql += ";"
- sqls = append(sqls, sql)
-
- if mi.model != nil {
- for _, names := range getTableIndex(mi.addrField) {
- cols := make([]string, 0, len(names))
- for _, name := range names {
- if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
- cols = append(cols, fi.column)
- } else {
- panic(fmt.Errorf("cannot found column `%s` when parse INDEX in `%s.TableIndex`", name, mi.fullName))
- }
- }
- sqlIndexes = append(sqlIndexes, cols)
- }
- }
-
- for _, names := range sqlIndexes {
- name := mi.table + "_" + strings.Join(names, "_")
- cols := strings.Join(names, sep)
- sql := fmt.Sprintf("CREATE INDEX %s%s%s ON %s%s%s (%s%s%s);", Q, name, Q, Q, mi.table, Q, Q, cols, Q)
-
- index := dbIndex{}
- index.Table = mi.table
- index.Name = name
- index.SQL = sql
-
- tableIndexes[mi.table] = append(tableIndexes[mi.table], index)
- }
-
- }
-
- return
-}
-
-// Get string value for the attribute "DEFAULT" for the CREATE, ALTER commands
-func getColumnDefault(fi *fieldInfo) string {
- var (
- v, t, d string
- )
-
- // Skip default attribute if field is in relations
- if fi.rel || fi.reverse {
- return v
- }
-
- t = " DEFAULT '%s' "
-
- // These defaults will be useful if there no config value orm:"default" and NOT NULL is on
- switch fi.fieldType {
- case TypeTimeField, TypeDateField, TypeDateTimeField, TypeTextField:
- return v
-
- case TypeBitField, TypeSmallIntegerField, TypeIntegerField,
- TypeBigIntegerField, TypePositiveBitField, TypePositiveSmallIntegerField,
- TypePositiveIntegerField, TypePositiveBigIntegerField, TypeFloatField,
- TypeDecimalField:
- t = " DEFAULT %s "
- d = "0"
- case TypeBooleanField:
- t = " DEFAULT %s "
- d = "FALSE"
- case TypeJSONField, TypeJsonbField:
- d = "{}"
- }
-
- if fi.colDefault {
- if !fi.initial.Exist() {
- v = fmt.Sprintf(t, "")
- } else {
- v = fmt.Sprintf(t, fi.initial.String())
- }
- } else {
- if !fi.null {
- v = fmt.Sprintf(t, d)
- }
- }
-
- return v
-}
diff --git a/src/vendor/github.com/beego/beego/orm/models.go b/src/vendor/github.com/beego/beego/orm/models.go
deleted file mode 100644
index 4776bcba6..000000000
--- a/src/vendor/github.com/beego/beego/orm/models.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package orm
-
-import (
- "sync"
-)
-
-const (
- odCascade = "cascade"
- odSetNULL = "set_null"
- odSetDefault = "set_default"
- odDoNothing = "do_nothing"
- defaultStructTagName = "orm"
- defaultStructTagDelim = ";"
-)
-
-var (
- modelCache = &_modelCache{
- cache: make(map[string]*modelInfo),
- cacheByFullName: make(map[string]*modelInfo),
- }
-)
-
-// model info collection
-type _modelCache struct {
- sync.RWMutex // only used outsite for bootStrap
- orders []string
- cache map[string]*modelInfo
- cacheByFullName map[string]*modelInfo
- done bool
-}
-
-// get all model info
-func (mc *_modelCache) all() map[string]*modelInfo {
- m := make(map[string]*modelInfo, len(mc.cache))
- for k, v := range mc.cache {
- m[k] = v
- }
- return m
-}
-
-// get ordered model info
-func (mc *_modelCache) allOrdered() []*modelInfo {
- m := make([]*modelInfo, 0, len(mc.orders))
- for _, table := range mc.orders {
- m = append(m, mc.cache[table])
- }
- return m
-}
-
-// get model info by table name
-func (mc *_modelCache) get(table string) (mi *modelInfo, ok bool) {
- mi, ok = mc.cache[table]
- return
-}
-
-// get model info by full name
-func (mc *_modelCache) getByFullName(name string) (mi *modelInfo, ok bool) {
- mi, ok = mc.cacheByFullName[name]
- return
-}
-
-// set model info to collection
-func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
- mii := mc.cache[table]
- mc.cache[table] = mi
- mc.cacheByFullName[mi.fullName] = mi
- if mii == nil {
- mc.orders = append(mc.orders, table)
- }
- return mii
-}
-
-// clean all model info.
-func (mc *_modelCache) clean() {
- mc.orders = make([]string, 0)
- mc.cache = make(map[string]*modelInfo)
- mc.cacheByFullName = make(map[string]*modelInfo)
- mc.done = false
-}
-
-// ResetModelCache Clean model cache. Then you can re-RegisterModel.
-// Common use this api for test case.
-func ResetModelCache() {
- modelCache.clean()
-}
diff --git a/src/vendor/github.com/beego/beego/orm/models_boot.go b/src/vendor/github.com/beego/beego/orm/models_boot.go
deleted file mode 100644
index 8c56b3c44..000000000
--- a/src/vendor/github.com/beego/beego/orm/models_boot.go
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package orm
-
-import (
- "fmt"
- "os"
- "reflect"
- "runtime/debug"
- "strings"
-)
-
-// register models.
-// PrefixOrSuffix means table name prefix or suffix.
-// isPrefix whether the prefix is prefix or suffix
-func registerModel(PrefixOrSuffix string, model interface{}, isPrefix bool) {
- val := reflect.ValueOf(model)
- typ := reflect.Indirect(val).Type()
-
- if val.Kind() != reflect.Ptr {
- panic(fmt.Errorf(" cannot use non-ptr model struct `%s`", getFullName(typ)))
- }
- // For this case:
- // u := &User{}
- // registerModel(&u)
- if typ.Kind() == reflect.Ptr {
- panic(fmt.Errorf(" only allow ptr model struct, it looks you use two reference to the struct `%s`", typ))
- }
-
- table := getTableName(val)
-
- if PrefixOrSuffix != "" {
- if isPrefix {
- table = PrefixOrSuffix + table
- } else {
- table = table + PrefixOrSuffix
- }
- }
- // models's fullname is pkgpath + struct name
- name := getFullName(typ)
- if _, ok := modelCache.getByFullName(name); ok {
- fmt.Printf(" model `%s` repeat register, must be unique\n", name)
- os.Exit(2)
- }
-
- if _, ok := modelCache.get(table); ok {
- fmt.Printf(" table name `%s` repeat register, must be unique\n", table)
- os.Exit(2)
- }
-
- mi := newModelInfo(val)
- if mi.fields.pk == nil {
- outFor:
- for _, fi := range mi.fields.fieldsDB {
- if strings.ToLower(fi.name) == "id" {
- switch fi.addrValue.Elem().Kind() {
- case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64:
- fi.auto = true
- fi.pk = true
- mi.fields.pk = fi
- break outFor
- }
- }
- }
-
- if mi.fields.pk == nil {
- fmt.Printf(" `%s` needs a primary key field, default is to use 'id' if not set\n", name)
- os.Exit(2)
- }
-
- }
-
- mi.table = table
- mi.pkg = typ.PkgPath()
- mi.model = model
- mi.manual = true
-
- modelCache.set(table, mi)
-}
-
-// bootstrap models
-func bootStrap() {
- if modelCache.done {
- return
- }
- var (
- err error
- models map[string]*modelInfo
- )
- if dataBaseCache.getDefault() == nil {
- err = fmt.Errorf("must have one register DataBase alias named `default`")
- goto end
- }
-
- // set rel and reverse model
- // RelManyToMany set the relTable
- models = modelCache.all()
- for _, mi := range models {
- for _, fi := range mi.fields.columns {
- if fi.rel || fi.reverse {
- elm := fi.addrValue.Type().Elem()
- if fi.fieldType == RelReverseMany || fi.fieldType == RelManyToMany {
- elm = elm.Elem()
- }
- // check the rel or reverse model already register
- name := getFullName(elm)
- mii, ok := modelCache.getByFullName(name)
- if !ok || mii.pkg != elm.PkgPath() {
- err = fmt.Errorf("can not find rel in field `%s`, `%s` may be miss register", fi.fullName, elm.String())
- goto end
- }
- fi.relModelInfo = mii
-
- switch fi.fieldType {
- case RelManyToMany:
- if fi.relThrough != "" {
- if i := strings.LastIndex(fi.relThrough, "."); i != -1 && len(fi.relThrough) > (i+1) {
- pn := fi.relThrough[:i]
- rmi, ok := modelCache.getByFullName(fi.relThrough)
- if !ok || pn != rmi.pkg {
- err = fmt.Errorf("field `%s` wrong rel_through value `%s` cannot find table", fi.fullName, fi.relThrough)
- goto end
- }
- fi.relThroughModelInfo = rmi
- fi.relTable = rmi.table
- } else {
- err = fmt.Errorf("field `%s` wrong rel_through value `%s`", fi.fullName, fi.relThrough)
- goto end
- }
- } else {
- i := newM2MModelInfo(mi, mii)
- if fi.relTable != "" {
- i.table = fi.relTable
- }
- if v := modelCache.set(i.table, i); v != nil {
- err = fmt.Errorf("the rel table name `%s` already registered, cannot be use, please change one", fi.relTable)
- goto end
- }
- fi.relTable = i.table
- fi.relThroughModelInfo = i
- }
-
- fi.relThroughModelInfo.isThrough = true
- }
- }
- }
- }
-
- // check the rel filed while the relModelInfo also has filed point to current model
- // if not exist, add a new field to the relModelInfo
- models = modelCache.all()
- for _, mi := range models {
- for _, fi := range mi.fields.fieldsRel {
- switch fi.fieldType {
- case RelForeignKey, RelOneToOne, RelManyToMany:
- inModel := false
- for _, ffi := range fi.relModelInfo.fields.fieldsReverse {
- if ffi.relModelInfo == mi {
- inModel = true
- break
- }
- }
- if !inModel {
- rmi := fi.relModelInfo
- ffi := new(fieldInfo)
- ffi.name = mi.name
- ffi.column = ffi.name
- ffi.fullName = rmi.fullName + "." + ffi.name
- ffi.reverse = true
- ffi.relModelInfo = mi
- ffi.mi = rmi
- if fi.fieldType == RelOneToOne {
- ffi.fieldType = RelReverseOne
- } else {
- ffi.fieldType = RelReverseMany
- }
- if !rmi.fields.Add(ffi) {
- added := false
- for cnt := 0; cnt < 5; cnt++ {
- ffi.name = fmt.Sprintf("%s%d", mi.name, cnt)
- ffi.column = ffi.name
- ffi.fullName = rmi.fullName + "." + ffi.name
- if added = rmi.fields.Add(ffi); added {
- break
- }
- }
- if !added {
- panic(fmt.Errorf("cannot generate auto reverse field info `%s` to `%s`", fi.fullName, ffi.fullName))
- }
- }
- }
- }
- }
- }
-
- models = modelCache.all()
- for _, mi := range models {
- for _, fi := range mi.fields.fieldsRel {
- switch fi.fieldType {
- case RelManyToMany:
- for _, ffi := range fi.relThroughModelInfo.fields.fieldsRel {
- switch ffi.fieldType {
- case RelOneToOne, RelForeignKey:
- if ffi.relModelInfo == fi.relModelInfo {
- fi.reverseFieldInfoTwo = ffi
- }
- if ffi.relModelInfo == mi {
- fi.reverseField = ffi.name
- fi.reverseFieldInfo = ffi
- }
- }
- }
- if fi.reverseFieldInfoTwo == nil {
- err = fmt.Errorf("can not find m2m field for m2m model `%s`, ensure your m2m model defined correct",
- fi.relThroughModelInfo.fullName)
- goto end
- }
- }
- }
- }
-
- models = modelCache.all()
- for _, mi := range models {
- for _, fi := range mi.fields.fieldsReverse {
- switch fi.fieldType {
- case RelReverseOne:
- found := false
- mForA:
- for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelOneToOne] {
- if ffi.relModelInfo == mi {
- found = true
- fi.reverseField = ffi.name
- fi.reverseFieldInfo = ffi
-
- ffi.reverseField = fi.name
- ffi.reverseFieldInfo = fi
- break mForA
- }
- }
- if !found {
- err = fmt.Errorf("reverse field `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
- goto end
- }
- case RelReverseMany:
- found := false
- mForB:
- for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelForeignKey] {
- if ffi.relModelInfo == mi {
- found = true
- fi.reverseField = ffi.name
- fi.reverseFieldInfo = ffi
-
- ffi.reverseField = fi.name
- ffi.reverseFieldInfo = fi
-
- break mForB
- }
- }
- if !found {
- mForC:
- for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelManyToMany] {
- conditions := fi.relThrough != "" && fi.relThrough == ffi.relThrough ||
- fi.relTable != "" && fi.relTable == ffi.relTable ||
- fi.relThrough == "" && fi.relTable == ""
- if ffi.relModelInfo == mi && conditions {
- found = true
-
- fi.reverseField = ffi.reverseFieldInfoTwo.name
- fi.reverseFieldInfo = ffi.reverseFieldInfoTwo
- fi.relThroughModelInfo = ffi.relThroughModelInfo
- fi.reverseFieldInfoTwo = ffi.reverseFieldInfo
- fi.reverseFieldInfoM2M = ffi
- ffi.reverseFieldInfoM2M = fi
-
- break mForC
- }
- }
- }
- if !found {
- err = fmt.Errorf("reverse field for `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
- goto end
- }
- }
- }
- }
-
-end:
- if err != nil {
- fmt.Println(err)
- debug.PrintStack()
- os.Exit(2)
- }
-}
-
-// RegisterModel register models
-func RegisterModel(models ...interface{}) {
- if modelCache.done {
- panic(fmt.Errorf("RegisterModel must be run before BootStrap"))
- }
- RegisterModelWithPrefix("", models...)
-}
-
-// RegisterModelWithPrefix register models with a prefix
-func RegisterModelWithPrefix(prefix string, models ...interface{}) {
- if modelCache.done {
- panic(fmt.Errorf("RegisterModelWithPrefix must be run before BootStrap"))
- }
-
- for _, model := range models {
- registerModel(prefix, model, true)
- }
-}
-
-// RegisterModelWithSuffix register models with a suffix
-func RegisterModelWithSuffix(suffix string, models ...interface{}) {
- if modelCache.done {
- panic(fmt.Errorf("RegisterModelWithSuffix must be run before BootStrap"))
- }
-
- for _, model := range models {
- registerModel(suffix, model, false)
- }
-}
-
-// BootStrap bootstrap models.
-// make all model parsed and can not add more models
-func BootStrap() {
- modelCache.Lock()
- defer modelCache.Unlock()
- if modelCache.done {
- return
- }
- bootStrap()
- modelCache.done = true
-}
diff --git a/src/vendor/github.com/beego/beego/orm/orm.go b/src/vendor/github.com/beego/beego/orm/orm.go
deleted file mode 100644
index 1a4bb9b6b..000000000
--- a/src/vendor/github.com/beego/beego/orm/orm.go
+++ /dev/null
@@ -1,579 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// +build go1.8
-
-// Package orm provide ORM for MySQL/PostgreSQL/sqlite
-// Simple Usage
-//
-// package main
-//
-// import (
-// "fmt"
-// "github.com/beego/beego/orm"
-// _ "github.com/go-sql-driver/mysql" // import your used driver
-// )
-//
-// // Model Struct
-// type User struct {
-// Id int `orm:"auto"`
-// Name string `orm:"size(100)"`
-// }
-//
-// func init() {
-// orm.RegisterDataBase("default", "mysql", "root:root@/my_db?charset=utf8", 30)
-// }
-//
-// func main() {
-// o := orm.NewOrm()
-// user := User{Name: "slene"}
-// // insert
-// id, err := o.Insert(&user)
-// // update
-// user.Name = "astaxie"
-// num, err := o.Update(&user)
-// // read one
-// u := User{Id: user.Id}
-// err = o.Read(&u)
-// // delete
-// num, err = o.Delete(&u)
-// }
-//
-// more docs: http://beego.me/docs/mvc/model/overview.md
-package orm
-
-import (
- "context"
- "database/sql"
- "errors"
- "fmt"
- "os"
- "reflect"
- "sync"
- "time"
-)
-
-// DebugQueries define the debug
-const (
- DebugQueries = iota
-)
-
-// Define common vars
-var (
- Debug = false
- DebugLog = NewLog(os.Stdout)
- DefaultRowsLimit = -1
- DefaultRelsDepth = 2
- DefaultTimeLoc = time.Local
- ErrTxHasBegan = errors.New(" transaction already begin")
- ErrTxDone = errors.New(" transaction not begin")
- ErrMultiRows = errors.New(" return multi rows")
- ErrNoRows = errors.New(" no row found")
- ErrStmtClosed = errors.New(" stmt already closed")
- ErrArgs = errors.New(" args error may be empty")
- ErrNotImplement = errors.New("have not implement")
-)
-
-// Params stores the Params
-type Params map[string]interface{}
-
-// ParamsList stores paramslist
-type ParamsList []interface{}
-
-type orm struct {
- alias *alias
- db dbQuerier
- isTx bool
-}
-
-var _ Ormer = new(orm)
-
-// get model info and model reflect value
-func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect.Value) {
- val := reflect.ValueOf(md)
- ind = reflect.Indirect(val)
- typ := ind.Type()
- if needPtr && val.Kind() != reflect.Ptr {
- panic(fmt.Errorf(" cannot use non-ptr model struct `%s`", getFullName(typ)))
- }
- name := getFullName(typ)
- if mi, ok := modelCache.getByFullName(name); ok {
- return mi, ind
- }
- panic(fmt.Errorf(" table: `%s` not found, make sure it was registered with `RegisterModel()`", name))
-}
-
-// get field info from model info by given field name
-func (o *orm) getFieldInfo(mi *modelInfo, name string) *fieldInfo {
- fi, ok := mi.fields.GetByAny(name)
- if !ok {
- panic(fmt.Errorf(" cannot find field `%s` for model `%s`", name, mi.fullName))
- }
- return fi
-}
-
-// read data to model
-func (o *orm) Read(md interface{}, cols ...string) error {
- mi, ind := o.getMiInd(md, true)
- return o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, false)
-}
-
-// read data to model, like Read(), but use "SELECT FOR UPDATE" form
-func (o *orm) ReadForUpdate(md interface{}, cols ...string) error {
- mi, ind := o.getMiInd(md, true)
- return o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, true)
-}
-
-// Try to read a row from the database, or insert one if it doesn't exist
-func (o *orm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
- cols = append([]string{col1}, cols...)
- mi, ind := o.getMiInd(md, true)
- err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols, false)
- if err == ErrNoRows {
- // Create
- id, err := o.Insert(md)
- return (err == nil), id, err
- }
-
- id, vid := int64(0), ind.FieldByIndex(mi.fields.pk.fieldIndex)
- if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
- id = int64(vid.Uint())
- } else if mi.fields.pk.rel {
- return o.ReadOrCreate(vid.Interface(), mi.fields.pk.relModelInfo.fields.pk.name)
- } else {
- id = vid.Int()
- }
-
- return false, id, err
-}
-
-// insert model data to database
-func (o *orm) Insert(md interface{}) (int64, error) {
- mi, ind := o.getMiInd(md, true)
- id, err := o.alias.DbBaser.Insert(o.db, mi, ind, o.alias.TZ)
- if err != nil {
- return id, err
- }
-
- o.setPk(mi, ind, id)
-
- return id, nil
-}
-
-// set auto pk field
-func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) {
- if mi.fields.pk.auto {
- if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
- ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(uint64(id))
- } else {
- ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(id)
- }
- }
-}
-
-// insert some models to database
-func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) {
- var cnt int64
-
- sind := reflect.Indirect(reflect.ValueOf(mds))
-
- switch sind.Kind() {
- case reflect.Array, reflect.Slice:
- if sind.Len() == 0 {
- return cnt, ErrArgs
- }
- default:
- return cnt, ErrArgs
- }
-
- if bulk <= 1 {
- for i := 0; i < sind.Len(); i++ {
- ind := reflect.Indirect(sind.Index(i))
- mi, _ := o.getMiInd(ind.Interface(), false)
- id, err := o.alias.DbBaser.Insert(o.db, mi, ind, o.alias.TZ)
- if err != nil {
- return cnt, err
- }
-
- o.setPk(mi, ind, id)
-
- cnt++
- }
- } else {
- mi, _ := o.getMiInd(sind.Index(0).Interface(), false)
- return o.alias.DbBaser.InsertMulti(o.db, mi, sind, bulk, o.alias.TZ)
- }
- return cnt, nil
-}
-
-// InsertOrUpdate data to database
-func (o *orm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
- mi, ind := o.getMiInd(md, true)
- id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias, colConflitAndArgs...)
- if err != nil {
- return id, err
- }
-
- o.setPk(mi, ind, id)
-
- return id, nil
-}
-
-// update model to database.
-// cols set the columns those want to update.
-func (o *orm) Update(md interface{}, cols ...string) (int64, error) {
- mi, ind := o.getMiInd(md, true)
- return o.alias.DbBaser.Update(o.db, mi, ind, o.alias.TZ, cols)
-}
-
-// delete model in database
-// cols shows the delete conditions values read from. default is pk
-func (o *orm) Delete(md interface{}, cols ...string) (int64, error) {
- mi, ind := o.getMiInd(md, true)
- num, err := o.alias.DbBaser.Delete(o.db, mi, ind, o.alias.TZ, cols)
- if err != nil {
- return num, err
- }
- if num > 0 {
- o.setPk(mi, ind, 0)
- }
- return num, nil
-}
-
-// create a models to models queryer
-func (o *orm) QueryM2M(md interface{}, name string) QueryM2Mer {
- mi, ind := o.getMiInd(md, true)
- fi := o.getFieldInfo(mi, name)
-
- switch {
- case fi.fieldType == RelManyToMany:
- case fi.fieldType == RelReverseMany && fi.reverseFieldInfo.mi.isThrough:
- default:
- panic(fmt.Errorf(" model `%s` . name `%s` is not a m2m field", fi.name, mi.fullName))
- }
-
- return newQueryM2M(md, o, mi, fi, ind)
-}
-
-// load related models to md model.
-// args are limit, offset int and order string.
-//
-// example:
-// orm.LoadRelated(post,"Tags")
-// for _,tag := range post.Tags{...}
-//
-// make sure the relation is defined in model struct tags.
-func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
- _, fi, ind, qseter := o.queryRelated(md, name)
-
- qs := qseter.(*querySet)
-
- var relDepth int
- var limit, offset int64
- var order string
- for i, arg := range args {
- switch i {
- case 0:
- if v, ok := arg.(bool); ok {
- if v {
- relDepth = DefaultRelsDepth
- }
- } else if v, ok := arg.(int); ok {
- relDepth = v
- }
- case 1:
- limit = ToInt64(arg)
- case 2:
- offset = ToInt64(arg)
- case 3:
- order, _ = arg.(string)
- }
- }
-
- switch fi.fieldType {
- case RelOneToOne, RelForeignKey, RelReverseOne:
- limit = 1
- offset = 0
- }
-
- qs.limit = limit
- qs.offset = offset
- qs.relDepth = relDepth
-
- if len(order) > 0 {
- qs.orders = []string{order}
- }
-
- find := ind.FieldByIndex(fi.fieldIndex)
-
- var nums int64
- var err error
- switch fi.fieldType {
- case RelOneToOne, RelForeignKey, RelReverseOne:
- val := reflect.New(find.Type().Elem())
- container := val.Interface()
- err = qs.One(container)
- if err == nil {
- find.Set(val)
- nums = 1
- }
- default:
- nums, err = qs.All(find.Addr().Interface())
- }
-
- return nums, err
-}
-
-// return a QuerySeter for related models to md model.
-// it can do all, update, delete in QuerySeter.
-// example:
-// qs := orm.QueryRelated(post,"Tag")
-// qs.All(&[]*Tag{})
-//
-func (o *orm) QueryRelated(md interface{}, name string) QuerySeter {
- // is this api needed ?
- _, _, _, qs := o.queryRelated(md, name)
- return qs
-}
-
-// get QuerySeter for related models to md model
-func (o *orm) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, QuerySeter) {
- mi, ind := o.getMiInd(md, true)
- fi := o.getFieldInfo(mi, name)
-
- _, _, exist := getExistPk(mi, ind)
- if !exist {
- panic(ErrMissPK)
- }
-
- var qs *querySet
-
- switch fi.fieldType {
- case RelOneToOne, RelForeignKey, RelManyToMany:
- if !fi.inModel {
- break
- }
- qs = o.getRelQs(md, mi, fi)
- case RelReverseOne, RelReverseMany:
- if !fi.inModel {
- break
- }
- qs = o.getReverseQs(md, mi, fi)
- }
-
- if qs == nil {
- panic(fmt.Errorf(" name `%s` for model `%s` is not an available rel/reverse field", md, name))
- }
-
- return mi, fi, ind, qs
-}
-
-// get reverse relation QuerySeter
-func (o *orm) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
- switch fi.fieldType {
- case RelReverseOne, RelReverseMany:
- default:
- panic(fmt.Errorf(" name `%s` for model `%s` is not an available reverse field", fi.name, mi.fullName))
- }
-
- var q *querySet
-
- if fi.fieldType == RelReverseMany && fi.reverseFieldInfo.mi.isThrough {
- q = newQuerySet(o, fi.relModelInfo).(*querySet)
- q.cond = NewCondition().And(fi.reverseFieldInfoM2M.column+ExprSep+fi.reverseFieldInfo.column, md)
- } else {
- q = newQuerySet(o, fi.reverseFieldInfo.mi).(*querySet)
- q.cond = NewCondition().And(fi.reverseFieldInfo.column, md)
- }
-
- return q
-}
-
-// get relation QuerySeter
-func (o *orm) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
- switch fi.fieldType {
- case RelOneToOne, RelForeignKey, RelManyToMany:
- default:
- panic(fmt.Errorf(" name `%s` for model `%s` is not an available rel field", fi.name, mi.fullName))
- }
-
- q := newQuerySet(o, fi.relModelInfo).(*querySet)
- q.cond = NewCondition()
-
- if fi.fieldType == RelManyToMany {
- q.cond = q.cond.And(fi.reverseFieldInfoM2M.column+ExprSep+fi.reverseFieldInfo.column, md)
- } else {
- q.cond = q.cond.And(fi.reverseFieldInfo.column, md)
- }
-
- return q
-}
-
-// return a QuerySeter for table operations.
-// table name can be string or struct.
-// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
-func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
- var name string
- if table, ok := ptrStructOrTableName.(string); ok {
- name = nameStrategyMap[defaultNameStrategy](table)
- if mi, ok := modelCache.get(name); ok {
- qs = newQuerySet(o, mi)
- }
- } else {
- name = getFullName(indirectType(reflect.TypeOf(ptrStructOrTableName)))
- if mi, ok := modelCache.getByFullName(name); ok {
- qs = newQuerySet(o, mi)
- }
- }
- if qs == nil {
- panic(fmt.Errorf(" table name: `%s` not exists", name))
- }
- return
-}
-
-// switch to another registered database driver by given name.
-func (o *orm) Using(name string) error {
- if o.isTx {
- panic(fmt.Errorf(" transaction has been start, cannot change db"))
- }
- if al, ok := dataBaseCache.get(name); ok {
- o.alias = al
- if Debug {
- o.db = newDbQueryLog(al, al.DB)
- } else {
- o.db = al.DB
- }
- } else {
- return fmt.Errorf(" unknown db alias name `%s`", name)
- }
- return nil
-}
-
-// begin transaction
-func (o *orm) Begin() error {
- return o.BeginTx(context.Background(), nil)
-}
-
-func (o *orm) BeginTx(ctx context.Context, opts *sql.TxOptions) error {
- if o.isTx {
- return ErrTxHasBegan
- }
- var tx *sql.Tx
- tx, err := o.db.(txer).BeginTx(ctx, opts)
- if err != nil {
- return err
- }
- o.isTx = true
- if Debug {
- o.db.(*dbQueryLog).SetDB(tx)
- } else {
- o.db = tx
- }
- return nil
-}
-
-// commit transaction
-func (o *orm) Commit() error {
- if !o.isTx {
- return ErrTxDone
- }
- err := o.db.(txEnder).Commit()
- if err == nil {
- o.isTx = false
- o.Using(o.alias.Name)
- } else if err == sql.ErrTxDone {
- return ErrTxDone
- }
- return err
-}
-
-// rollback transaction
-func (o *orm) Rollback() error {
- if !o.isTx {
- return ErrTxDone
- }
- err := o.db.(txEnder).Rollback()
- if err == nil {
- o.isTx = false
- o.Using(o.alias.Name)
- } else if err == sql.ErrTxDone {
- return ErrTxDone
- }
- return err
-}
-
-// return a raw query seter for raw sql string.
-func (o *orm) Raw(query string, args ...interface{}) RawSeter {
- return newRawSet(o, query, args)
-}
-
-// return current using database Driver
-func (o *orm) Driver() Driver {
- return driver(o.alias.Name)
-}
-
-// return sql.DBStats for current database
-func (o *orm) DBStats() *sql.DBStats {
- if o.alias != nil && o.alias.DB != nil {
- stats := o.alias.DB.DB.Stats()
- return &stats
- }
- return nil
-}
-
-// NewOrm create new orm
-func NewOrm() Ormer {
- BootStrap() // execute only once
-
- o := new(orm)
- err := o.Using("default")
- if err != nil {
- panic(err)
- }
- return o
-}
-
-// NewOrmWithDB create a new ormer object with specify *sql.DB for query
-func NewOrmWithDB(driverName, aliasName string, db *sql.DB) (Ormer, error) {
- var al *alias
-
- if dr, ok := drivers[driverName]; ok {
- al = new(alias)
- al.DbBaser = dbBasers[dr]
- al.Driver = dr
- } else {
- return nil, fmt.Errorf("driver name `%s` have not registered", driverName)
- }
-
- al.Name = aliasName
- al.DriverName = driverName
- al.DB = &DB{
- RWMutex: new(sync.RWMutex),
- DB: db,
- stmtDecorators: newStmtDecoratorLruWithEvict(),
- }
-
- detectTZ(al)
-
- o := new(orm)
- o.alias = al
-
- if Debug {
- o.db = newDbQueryLog(o.alias, db)
- } else {
- o.db = db
- }
-
- return o, nil
-}
diff --git a/src/vendor/github.com/beego/beego/orm/qb_tidb.go b/src/vendor/github.com/beego/beego/orm/qb_tidb.go
deleted file mode 100644
index 87b3ae84f..000000000
--- a/src/vendor/github.com/beego/beego/orm/qb_tidb.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2015 TiDB Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package orm
-
-import (
- "fmt"
- "strconv"
- "strings"
-)
-
-// TiDBQueryBuilder is the SQL build
-type TiDBQueryBuilder struct {
- Tokens []string
-}
-
-// Select will join the fields
-func (qb *TiDBQueryBuilder) Select(fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "SELECT", strings.Join(fields, CommaSpace))
- return qb
-}
-
-// ForUpdate add the FOR UPDATE clause
-func (qb *TiDBQueryBuilder) ForUpdate() QueryBuilder {
- qb.Tokens = append(qb.Tokens, "FOR UPDATE")
- return qb
-}
-
-// From join the tables
-func (qb *TiDBQueryBuilder) From(tables ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "FROM", strings.Join(tables, CommaSpace))
- return qb
-}
-
-// InnerJoin INNER JOIN the table
-func (qb *TiDBQueryBuilder) InnerJoin(table string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "INNER JOIN", table)
- return qb
-}
-
-// LeftJoin LEFT JOIN the table
-func (qb *TiDBQueryBuilder) LeftJoin(table string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "LEFT JOIN", table)
- return qb
-}
-
-// RightJoin RIGHT JOIN the table
-func (qb *TiDBQueryBuilder) RightJoin(table string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "RIGHT JOIN", table)
- return qb
-}
-
-// On join with on cond
-func (qb *TiDBQueryBuilder) On(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "ON", cond)
- return qb
-}
-
-// Where join the Where cond
-func (qb *TiDBQueryBuilder) Where(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "WHERE", cond)
- return qb
-}
-
-// And join the and cond
-func (qb *TiDBQueryBuilder) And(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "AND", cond)
- return qb
-}
-
-// Or join the or cond
-func (qb *TiDBQueryBuilder) Or(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "OR", cond)
- return qb
-}
-
-// In join the IN (vals)
-func (qb *TiDBQueryBuilder) In(vals ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
- return qb
-}
-
-// OrderBy join the Order by fields
-func (qb *TiDBQueryBuilder) OrderBy(fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "ORDER BY", strings.Join(fields, CommaSpace))
- return qb
-}
-
-// Asc join the asc
-func (qb *TiDBQueryBuilder) Asc() QueryBuilder {
- qb.Tokens = append(qb.Tokens, "ASC")
- return qb
-}
-
-// Desc join the desc
-func (qb *TiDBQueryBuilder) Desc() QueryBuilder {
- qb.Tokens = append(qb.Tokens, "DESC")
- return qb
-}
-
-// Limit join the limit num
-func (qb *TiDBQueryBuilder) Limit(limit int) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "LIMIT", strconv.Itoa(limit))
- return qb
-}
-
-// Offset join the offset num
-func (qb *TiDBQueryBuilder) Offset(offset int) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "OFFSET", strconv.Itoa(offset))
- return qb
-}
-
-// GroupBy join the Group by fields
-func (qb *TiDBQueryBuilder) GroupBy(fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "GROUP BY", strings.Join(fields, CommaSpace))
- return qb
-}
-
-// Having join the Having cond
-func (qb *TiDBQueryBuilder) Having(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "HAVING", cond)
- return qb
-}
-
-// Update join the update table
-func (qb *TiDBQueryBuilder) Update(tables ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "UPDATE", strings.Join(tables, CommaSpace))
- return qb
-}
-
-// Set join the set kv
-func (qb *TiDBQueryBuilder) Set(kv ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "SET", strings.Join(kv, CommaSpace))
- return qb
-}
-
-// Delete join the Delete tables
-func (qb *TiDBQueryBuilder) Delete(tables ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "DELETE")
- if len(tables) != 0 {
- qb.Tokens = append(qb.Tokens, strings.Join(tables, CommaSpace))
- }
- return qb
-}
-
-// InsertInto join the insert SQL
-func (qb *TiDBQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "INSERT INTO", table)
- if len(fields) != 0 {
- fieldsStr := strings.Join(fields, CommaSpace)
- qb.Tokens = append(qb.Tokens, "(", fieldsStr, ")")
- }
- return qb
-}
-
-// Values join the Values(vals)
-func (qb *TiDBQueryBuilder) Values(vals ...string) QueryBuilder {
- valsStr := strings.Join(vals, CommaSpace)
- qb.Tokens = append(qb.Tokens, "VALUES", "(", valsStr, ")")
- return qb
-}
-
-// Subquery join the sub as alias
-func (qb *TiDBQueryBuilder) Subquery(sub string, alias string) string {
- return fmt.Sprintf("(%s) AS %s", sub, alias)
-}
-
-// String join all Tokens
-func (qb *TiDBQueryBuilder) String() string {
- return strings.Join(qb.Tokens, " ")
-}
diff --git a/src/vendor/github.com/beego/beego/parser.go b/src/vendor/github.com/beego/beego/parser.go
deleted file mode 100644
index de4ce8dc2..000000000
--- a/src/vendor/github.com/beego/beego/parser.go
+++ /dev/null
@@ -1,590 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beego
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
- "io/ioutil"
- "os"
- "path/filepath"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "unicode"
-
- "github.com/beego/beego/context/param"
- "github.com/beego/beego/logs"
- "github.com/beego/beego/utils"
-)
-
-var globalRouterTemplate = `package {{.routersDir}}
-
-import (
- "github.com/beego/beego"
- "github.com/beego/beego/context/param"{{.globalimport}}
-)
-
-func init() {
-{{.globalinfo}}
-}
-`
-
-var (
- lastupdateFilename = "lastupdate.tmp"
- pkgLastupdate map[string]int64
- genInfoList map[string][]ControllerComments
-
- routerHooks = map[string]int{
- "beego.BeforeStatic": BeforeStatic,
- "beego.BeforeRouter": BeforeRouter,
- "beego.BeforeExec": BeforeExec,
- "beego.AfterExec": AfterExec,
- "beego.FinishRouter": FinishRouter,
- }
-
- routerHooksMapping = map[int]string{
- BeforeStatic: "beego.BeforeStatic",
- BeforeRouter: "beego.BeforeRouter",
- BeforeExec: "beego.BeforeExec",
- AfterExec: "beego.AfterExec",
- FinishRouter: "beego.FinishRouter",
- }
-)
-
-const commentFilename = "commentsRouter.go"
-
-func init() {
- pkgLastupdate = make(map[string]int64)
-}
-
-func parserPkg(pkgRealpath, pkgpath string) error {
- if !compareFile(pkgRealpath) {
- logs.Info(pkgRealpath + " no changed")
- return nil
- }
- genInfoList = make(map[string][]ControllerComments)
- fileSet := token.NewFileSet()
- astPkgs, err := parser.ParseDir(fileSet, pkgRealpath, func(info os.FileInfo) bool {
- name := info.Name()
- return !info.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
- }, parser.ParseComments)
-
- if err != nil {
- return err
- }
- for _, pkg := range astPkgs {
- for _, fl := range pkg.Files {
- for _, d := range fl.Decls {
- switch specDecl := d.(type) {
- case *ast.FuncDecl:
- if specDecl.Recv != nil {
- exp, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr) // Check that the type is correct first beforing throwing to parser
- if ok {
- err = parserComments(specDecl, fmt.Sprint(exp.X), pkgpath)
- if err != nil {
- return err
- }
- }
- }
- }
- }
- }
- }
- genRouterCode(pkgRealpath)
- savetoFile(pkgRealpath)
- return nil
-}
-
-type parsedComment struct {
- routerPath string
- methods []string
- params map[string]parsedParam
- filters []parsedFilter
- imports []parsedImport
-}
-
-type parsedImport struct {
- importPath string
- importAlias string
-}
-
-type parsedFilter struct {
- pattern string
- pos int
- filter string
- params []bool
-}
-
-type parsedParam struct {
- name string
- datatype string
- location string
- defValue string
- required bool
-}
-
-func parserComments(f *ast.FuncDecl, controllerName, pkgpath string) error {
- if f.Doc != nil {
- parsedComments, err := parseComment(f.Doc.List)
- if err != nil {
- return err
- }
- for _, parsedComment := range parsedComments {
- if parsedComment.routerPath != "" {
- key := pkgpath + ":" + controllerName
- cc := ControllerComments{}
- cc.Method = f.Name.String()
- cc.Router = parsedComment.routerPath
- cc.AllowHTTPMethods = parsedComment.methods
- cc.MethodParams = buildMethodParams(f.Type.Params.List, parsedComment)
- cc.FilterComments = buildFilters(parsedComment.filters)
- cc.ImportComments = buildImports(parsedComment.imports)
- genInfoList[key] = append(genInfoList[key], cc)
- }
- }
- }
- return nil
-}
-
-func buildImports(pis []parsedImport) []*ControllerImportComments {
- var importComments []*ControllerImportComments
-
- for _, pi := range pis {
- importComments = append(importComments, &ControllerImportComments{
- ImportPath: pi.importPath,
- ImportAlias: pi.importAlias,
- })
- }
-
- return importComments
-}
-
-func buildFilters(pfs []parsedFilter) []*ControllerFilterComments {
- var filterComments []*ControllerFilterComments
-
- for _, pf := range pfs {
- var (
- returnOnOutput bool
- resetParams bool
- )
-
- if len(pf.params) >= 1 {
- returnOnOutput = pf.params[0]
- }
-
- if len(pf.params) >= 2 {
- resetParams = pf.params[1]
- }
-
- filterComments = append(filterComments, &ControllerFilterComments{
- Filter: pf.filter,
- Pattern: pf.pattern,
- Pos: pf.pos,
- ReturnOnOutput: returnOnOutput,
- ResetParams: resetParams,
- })
- }
-
- return filterComments
-}
-
-func buildMethodParams(funcParams []*ast.Field, pc *parsedComment) []*param.MethodParam {
- result := make([]*param.MethodParam, 0, len(funcParams))
- for _, fparam := range funcParams {
- for _, pName := range fparam.Names {
- methodParam := buildMethodParam(fparam, pName.Name, pc)
- result = append(result, methodParam)
- }
- }
- return result
-}
-
-func buildMethodParam(fparam *ast.Field, name string, pc *parsedComment) *param.MethodParam {
- options := []param.MethodParamOption{}
- if cparam, ok := pc.params[name]; ok {
- //Build param from comment info
- name = cparam.name
- if cparam.required {
- options = append(options, param.IsRequired)
- }
- switch cparam.location {
- case "body":
- options = append(options, param.InBody)
- case "header":
- options = append(options, param.InHeader)
- case "path":
- options = append(options, param.InPath)
- }
- if cparam.defValue != "" {
- options = append(options, param.Default(cparam.defValue))
- }
- } else {
- if paramInPath(name, pc.routerPath) {
- options = append(options, param.InPath)
- }
- }
- return param.New(name, options...)
-}
-
-func paramInPath(name, route string) bool {
- return strings.HasSuffix(route, ":"+name) ||
- strings.Contains(route, ":"+name+"/")
-}
-
-var routeRegex = regexp.MustCompile(`@router\s+(\S+)(?:\s+\[(\S+)\])?`)
-
-func parseComment(lines []*ast.Comment) (pcs []*parsedComment, err error) {
- pcs = []*parsedComment{}
- params := map[string]parsedParam{}
- filters := []parsedFilter{}
- imports := []parsedImport{}
-
- for _, c := range lines {
- t := strings.TrimSpace(strings.TrimLeft(c.Text, "//"))
- if strings.HasPrefix(t, "@Param") {
- pv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Param")))
- if len(pv) < 4 {
- logs.Error("Invalid @Param format. Needs at least 4 parameters")
- }
- p := parsedParam{}
- names := strings.SplitN(pv[0], "=>", 2)
- p.name = names[0]
- funcParamName := p.name
- if len(names) > 1 {
- funcParamName = names[1]
- }
- p.location = pv[1]
- p.datatype = pv[2]
- switch len(pv) {
- case 5:
- p.required, _ = strconv.ParseBool(pv[3])
- case 6:
- p.defValue = pv[3]
- p.required, _ = strconv.ParseBool(pv[4])
- }
- params[funcParamName] = p
- }
- }
-
- for _, c := range lines {
- t := strings.TrimSpace(strings.TrimLeft(c.Text, "//"))
- if strings.HasPrefix(t, "@Import") {
- iv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Import")))
- if len(iv) == 0 || len(iv) > 2 {
- logs.Error("Invalid @Import format. Only accepts 1 or 2 parameters")
- continue
- }
-
- p := parsedImport{}
- p.importPath = iv[0]
-
- if len(iv) == 2 {
- p.importAlias = iv[1]
- }
-
- imports = append(imports, p)
- }
- }
-
-filterLoop:
- for _, c := range lines {
- t := strings.TrimSpace(strings.TrimLeft(c.Text, "//"))
- if strings.HasPrefix(t, "@Filter") {
- fv := getparams(strings.TrimSpace(strings.TrimLeft(t, "@Filter")))
- if len(fv) < 3 {
- logs.Error("Invalid @Filter format. Needs at least 3 parameters")
- continue filterLoop
- }
-
- p := parsedFilter{}
- p.pattern = fv[0]
- posName := fv[1]
- if pos, exists := routerHooks[posName]; exists {
- p.pos = pos
- } else {
- logs.Error("Invalid @Filter pos: ", posName)
- continue filterLoop
- }
-
- p.filter = fv[2]
- fvParams := fv[3:]
- for _, fvParam := range fvParams {
- switch fvParam {
- case "true":
- p.params = append(p.params, true)
- case "false":
- p.params = append(p.params, false)
- default:
- logs.Error("Invalid @Filter param: ", fvParam)
- continue filterLoop
- }
- }
-
- filters = append(filters, p)
- }
- }
-
- for _, c := range lines {
- var pc = &parsedComment{}
- pc.params = params
- pc.filters = filters
- pc.imports = imports
-
- t := strings.TrimSpace(strings.TrimLeft(c.Text, "//"))
- if strings.HasPrefix(t, "@router") {
- t := strings.TrimSpace(strings.TrimLeft(c.Text, "//"))
- matches := routeRegex.FindStringSubmatch(t)
- if len(matches) == 3 {
- pc.routerPath = matches[1]
- methods := matches[2]
- if methods == "" {
- pc.methods = []string{"get"}
- //pc.hasGet = true
- } else {
- pc.methods = strings.Split(methods, ",")
- //pc.hasGet = strings.Contains(methods, "get")
- }
- pcs = append(pcs, pc)
- } else {
- return nil, errors.New("Router information is missing")
- }
- }
- }
- return
-}
-
-// direct copy from bee\g_docs.go
-// analysis params return []string
-// @Param query form string true "The email for login"
-// [query form string true "The email for login"]
-func getparams(str string) []string {
- var s []rune
- var j int
- var start bool
- var r []string
- var quoted int8
- for _, c := range str {
- if unicode.IsSpace(c) && quoted == 0 {
- if !start {
- continue
- } else {
- start = false
- j++
- r = append(r, string(s))
- s = make([]rune, 0)
- continue
- }
- }
-
- start = true
- if c == '"' {
- quoted ^= 1
- continue
- }
- s = append(s, c)
- }
- if len(s) > 0 {
- r = append(r, string(s))
- }
- return r
-}
-
-func genRouterCode(pkgRealpath string) {
- os.Mkdir(getRouterDir(pkgRealpath), 0755)
- logs.Info("generate router from comments")
- var (
- globalinfo string
- globalimport string
- sortKey []string
- )
- for k := range genInfoList {
- sortKey = append(sortKey, k)
- }
- sort.Strings(sortKey)
- for _, k := range sortKey {
- cList := genInfoList[k]
- sort.Sort(ControllerCommentsSlice(cList))
- for _, c := range cList {
- allmethod := "nil"
- if len(c.AllowHTTPMethods) > 0 {
- allmethod = "[]string{"
- for _, m := range c.AllowHTTPMethods {
- allmethod += `"` + m + `",`
- }
- allmethod = strings.TrimRight(allmethod, ",") + "}"
- }
-
- params := "nil"
- if len(c.Params) > 0 {
- params = "[]map[string]string{"
- for _, p := range c.Params {
- for k, v := range p {
- params = params + `map[string]string{` + k + `:"` + v + `"},`
- }
- }
- params = strings.TrimRight(params, ",") + "}"
- }
-
- methodParams := "param.Make("
- if len(c.MethodParams) > 0 {
- lines := make([]string, 0, len(c.MethodParams))
- for _, m := range c.MethodParams {
- lines = append(lines, fmt.Sprint(m))
- }
- methodParams += "\n " +
- strings.Join(lines, ",\n ") +
- ",\n "
- }
- methodParams += ")"
-
- imports := ""
- if len(c.ImportComments) > 0 {
- for _, i := range c.ImportComments {
- var s string
- if i.ImportAlias != "" {
- s = fmt.Sprintf(`
- %s "%s"`, i.ImportAlias, i.ImportPath)
- } else {
- s = fmt.Sprintf(`
- "%s"`, i.ImportPath)
- }
- if !strings.Contains(globalimport, s) {
- imports += s
- }
- }
- }
-
- filters := ""
- if len(c.FilterComments) > 0 {
- for _, f := range c.FilterComments {
- filters += fmt.Sprintf(` &beego.ControllerFilter{
- Pattern: "%s",
- Pos: %s,
- Filter: %s,
- ReturnOnOutput: %v,
- ResetParams: %v,
- },`, f.Pattern, routerHooksMapping[f.Pos], f.Filter, f.ReturnOnOutput, f.ResetParams)
- }
- }
-
- if filters == "" {
- filters = "nil"
- } else {
- filters = fmt.Sprintf(`[]*beego.ControllerFilter{
-%s
- }`, filters)
- }
-
- globalimport += imports
-
- globalinfo = globalinfo + `
- beego.GlobalControllerRouter["` + k + `"] = append(beego.GlobalControllerRouter["` + k + `"],
- beego.ControllerComments{
- Method: "` + strings.TrimSpace(c.Method) + `",
- ` + "Router: `" + c.Router + "`" + `,
- AllowHTTPMethods: ` + allmethod + `,
- MethodParams: ` + methodParams + `,
- Filters: ` + filters + `,
- Params: ` + params + `})
-`
- }
- }
-
- if globalinfo != "" {
- f, err := os.Create(filepath.Join(getRouterDir(pkgRealpath), commentFilename))
- if err != nil {
- panic(err)
- }
- defer f.Close()
-
- routersDir := AppConfig.DefaultString("routersdir", "routers")
- content := strings.Replace(globalRouterTemplate, "{{.globalinfo}}", globalinfo, -1)
- content = strings.Replace(content, "{{.routersDir}}", routersDir, -1)
- content = strings.Replace(content, "{{.globalimport}}", globalimport, -1)
- f.WriteString(content)
- }
-}
-
-func compareFile(pkgRealpath string) bool {
- if !utils.FileExists(filepath.Join(getRouterDir(pkgRealpath), commentFilename)) {
- return true
- }
- if utils.FileExists(lastupdateFilename) {
- content, err := ioutil.ReadFile(lastupdateFilename)
- if err != nil {
- return true
- }
- json.Unmarshal(content, &pkgLastupdate)
- lastupdate, err := getpathTime(pkgRealpath)
- if err != nil {
- return true
- }
- if v, ok := pkgLastupdate[pkgRealpath]; ok {
- if lastupdate <= v {
- return false
- }
- }
- }
- return true
-}
-
-func savetoFile(pkgRealpath string) {
- lastupdate, err := getpathTime(pkgRealpath)
- if err != nil {
- return
- }
- pkgLastupdate[pkgRealpath] = lastupdate
- d, err := json.Marshal(pkgLastupdate)
- if err != nil {
- return
- }
- ioutil.WriteFile(lastupdateFilename, d, os.ModePerm)
-}
-
-func getpathTime(pkgRealpath string) (lastupdate int64, err error) {
- fl, err := ioutil.ReadDir(pkgRealpath)
- if err != nil {
- return lastupdate, err
- }
- for _, f := range fl {
- if lastupdate < f.ModTime().UnixNano() {
- lastupdate = f.ModTime().UnixNano()
- }
- }
- return lastupdate, nil
-}
-
-func getRouterDir(pkgRealpath string) string {
- dir := filepath.Dir(pkgRealpath)
- for {
- routersDir := AppConfig.DefaultString("routersdir", "routers")
- d := filepath.Join(dir, routersDir)
- if utils.FileExists(d) {
- return d
- }
-
- if r, _ := filepath.Rel(dir, AppPath); r == "." {
- return d
- }
- // Parent dir.
- dir = filepath.Dir(dir)
- }
-}
diff --git a/src/vendor/github.com/beego/beego/router.go b/src/vendor/github.com/beego/beego/router.go
deleted file mode 100644
index df8e89dca..000000000
--- a/src/vendor/github.com/beego/beego/router.go
+++ /dev/null
@@ -1,1052 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package beego
-
-import (
- "errors"
- "fmt"
- "net/http"
- "os"
- "path"
- "path/filepath"
- "reflect"
- "strconv"
- "strings"
- "sync"
- "time"
-
- beecontext "github.com/beego/beego/context"
- "github.com/beego/beego/context/param"
- "github.com/beego/beego/logs"
- "github.com/beego/beego/toolbox"
- "github.com/beego/beego/utils"
-)
-
-// default filter execution points
-const (
- BeforeStatic = iota
- BeforeRouter
- BeforeExec
- AfterExec
- FinishRouter
-)
-
-const (
- routerTypeBeego = iota
- routerTypeRESTFul
- routerTypeHandler
-)
-
-var (
- // HTTPMETHOD list the supported http methods.
- HTTPMETHOD = map[string]bool{
- "GET": true,
- "POST": true,
- "PUT": true,
- "DELETE": true,
- "PATCH": true,
- "OPTIONS": true,
- "HEAD": true,
- "TRACE": true,
- "CONNECT": true,
- "MKCOL": true,
- "COPY": true,
- "MOVE": true,
- "PROPFIND": true,
- "PROPPATCH": true,
- "LOCK": true,
- "UNLOCK": true,
- }
- // these beego.Controller's methods shouldn't reflect to AutoRouter
- exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString",
- "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJSON", "ServeJSONP",
- "ServeYAML", "ServeXML", "Input", "ParseForm", "GetString", "GetStrings", "GetInt", "GetBool",
- "GetFloat", "GetFile", "SaveToFile", "StartSession", "SetSession", "GetSession",
- "DelSession", "SessionRegenerateID", "DestroySession", "IsAjax", "GetSecureCookie",
- "SetSecureCookie", "XsrfToken", "CheckXsrfCookie", "XsrfFormHtml",
- "GetControllerAndAction", "ServeFormatted"}
-
- urlPlaceholder = "{{placeholder}}"
- // DefaultAccessLogFilter will skip the accesslog if return true
- DefaultAccessLogFilter FilterHandler = &logFilter{}
-)
-
-// FilterHandler is an interface for
-type FilterHandler interface {
- Filter(*beecontext.Context) bool
-}
-
-// default log filter static file will not show
-type logFilter struct {
-}
-
-func (l *logFilter) Filter(ctx *beecontext.Context) bool {
- requestPath := path.Clean(ctx.Request.URL.Path)
- if requestPath == "/favicon.ico" || requestPath == "/robots.txt" {
- return true
- }
- for prefix := range BConfig.WebConfig.StaticDir {
- if strings.HasPrefix(requestPath, prefix) {
- return true
- }
- }
- return false
-}
-
-// ExceptMethodAppend to append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter
-func ExceptMethodAppend(action string) {
- exceptMethod = append(exceptMethod, action)
-}
-
-// ControllerInfo holds information about the controller.
-type ControllerInfo struct {
- pattern string
- controllerType reflect.Type
- methods map[string]string
- handler http.Handler
- runFunction FilterFunc
- routerType int
- initialize func() ControllerInterface
- methodParams []*param.MethodParam
-}
-
-func (c *ControllerInfo) GetPattern() string {
- return c.pattern
-}
-
-// ControllerRegister containers registered router rules, controller handlers and filters.
-type ControllerRegister struct {
- routers map[string]*Tree
- enablePolicy bool
- policies map[string]*Tree
- enableFilter bool
- filters [FinishRouter + 1][]*FilterRouter
- pool sync.Pool
-}
-
-// NewControllerRegister returns a new ControllerRegister.
-func NewControllerRegister() *ControllerRegister {
- return &ControllerRegister{
- routers: make(map[string]*Tree),
- policies: make(map[string]*Tree),
- pool: sync.Pool{
- New: func() interface{} {
- return beecontext.NewContext()
- },
- },
- }
-}
-
-// Add controller handler and pattern rules to ControllerRegister.
-// usage:
-// default methods is the same name as method
-// Add("/user",&UserController{})
-// Add("/api/list",&RestController{},"*:ListFood")
-// Add("/api/create",&RestController{},"post:CreateFood")
-// Add("/api/update",&RestController{},"put:UpdateFood")
-// Add("/api/delete",&RestController{},"delete:DeleteFood")
-// Add("/api",&RestController{},"get,post:ApiFunc"
-// Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
-func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingMethods ...string) {
- p.addWithMethodParams(pattern, c, nil, mappingMethods...)
-}
-
-func (p *ControllerRegister) addWithMethodParams(pattern string, c ControllerInterface, methodParams []*param.MethodParam, mappingMethods ...string) {
- reflectVal := reflect.ValueOf(c)
- t := reflect.Indirect(reflectVal).Type()
- methods := make(map[string]string)
- if len(mappingMethods) > 0 {
- semi := strings.Split(mappingMethods[0], ";")
- for _, v := range semi {
- colon := strings.Split(v, ":")
- if len(colon) != 2 {
- panic("method mapping format is invalid")
- }
- comma := strings.Split(colon[0], ",")
- for _, m := range comma {
- if m == "*" || HTTPMETHOD[strings.ToUpper(m)] {
- if val := reflectVal.MethodByName(colon[1]); val.IsValid() {
- methods[strings.ToUpper(m)] = colon[1]
- } else {
- panic("'" + colon[1] + "' method doesn't exist in the controller " + t.Name())
- }
- } else {
- panic(v + " is an invalid method mapping. Method doesn't exist " + m)
- }
- }
- }
- }
-
- route := &ControllerInfo{}
- route.pattern = pattern
- route.methods = methods
- route.routerType = routerTypeBeego
- route.controllerType = t
- route.initialize = func() ControllerInterface {
- vc := reflect.New(route.controllerType)
- execController, ok := vc.Interface().(ControllerInterface)
- if !ok {
- panic("controller is not ControllerInterface")
- }
-
- elemVal := reflect.ValueOf(c).Elem()
- elemType := reflect.TypeOf(c).Elem()
- execElem := reflect.ValueOf(execController).Elem()
-
- numOfFields := elemVal.NumField()
- for i := 0; i < numOfFields; i++ {
- fieldType := elemType.Field(i)
- elemField := execElem.FieldByName(fieldType.Name)
- if elemField.CanSet() {
- fieldVal := elemVal.Field(i)
- elemField.Set(fieldVal)
- }
- }
-
- return execController
- }
-
- route.methodParams = methodParams
- if len(methods) == 0 {
- for m := range HTTPMETHOD {
- p.addToRouter(m, pattern, route)
- }
- } else {
- for k := range methods {
- if k == "*" {
- for m := range HTTPMETHOD {
- p.addToRouter(m, pattern, route)
- }
- } else {
- p.addToRouter(k, pattern, route)
- }
- }
- }
-}
-
-func (p *ControllerRegister) addToRouter(method, pattern string, r *ControllerInfo) {
- if !BConfig.RouterCaseSensitive {
- pattern = strings.ToLower(pattern)
- }
- if t, ok := p.routers[method]; ok {
- t.AddRouter(pattern, r)
- } else {
- t := NewTree()
- t.AddRouter(pattern, r)
- p.routers[method] = t
- }
-}
-
-// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller
-// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
-func (p *ControllerRegister) Include(cList ...ControllerInterface) {
- if BConfig.RunMode == DEV {
- skip := make(map[string]bool, 10)
- wgopath := utils.GetGOPATHs()
- go111module := os.Getenv(`GO111MODULE`)
- for _, c := range cList {
- reflectVal := reflect.ValueOf(c)
- t := reflect.Indirect(reflectVal).Type()
- // for go modules
- if go111module == `on` {
- pkgpath := filepath.Join(WorkPath, "..", t.PkgPath())
- if utils.FileExists(pkgpath) {
- if pkgpath != "" {
- if _, ok := skip[pkgpath]; !ok {
- skip[pkgpath] = true
- parserPkg(pkgpath, t.PkgPath())
- }
- }
- }
- } else {
- if len(wgopath) == 0 {
- panic("you are in dev mode. So please set gopath")
- }
- pkgpath := ""
- for _, wg := range wgopath {
- wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", t.PkgPath()))
- if utils.FileExists(wg) {
- pkgpath = wg
- break
- }
- }
- if pkgpath != "" {
- if _, ok := skip[pkgpath]; !ok {
- skip[pkgpath] = true
- parserPkg(pkgpath, t.PkgPath())
- }
- }
- }
- }
- }
- for _, c := range cList {
- reflectVal := reflect.ValueOf(c)
- t := reflect.Indirect(reflectVal).Type()
- key := t.PkgPath() + ":" + t.Name()
- if comm, ok := GlobalControllerRouter[key]; ok {
- for _, a := range comm {
- for _, f := range a.Filters {
- p.InsertFilter(f.Pattern, f.Pos, f.Filter, f.ReturnOnOutput, f.ResetParams)
- }
-
- p.addWithMethodParams(a.Router, c, a.MethodParams, strings.Join(a.AllowHTTPMethods, ",")+":"+a.Method)
- }
- }
- }
-}
-
-// GetContext returns a context from pool, so usually you should remember to call Reset function to clean the context
-// And don't forget to give back context to pool
-// example:
-// ctx := p.GetContext()
-// ctx.Reset(w, q)
-// defer p.GiveBackContext(ctx)
-func (p *ControllerRegister) GetContext() *beecontext.Context {
- return p.pool.Get().(*beecontext.Context)
-}
-
-// GiveBackContext put the ctx into pool so that it could be reuse
-func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
- p.pool.Put(ctx)
-}
-
-// Get add get method
-// usage:
-// Get("/", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Get(pattern string, f FilterFunc) {
- p.AddMethod("get", pattern, f)
-}
-
-// Post add post method
-// usage:
-// Post("/api", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Post(pattern string, f FilterFunc) {
- p.AddMethod("post", pattern, f)
-}
-
-// Put add put method
-// usage:
-// Put("/api/:id", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Put(pattern string, f FilterFunc) {
- p.AddMethod("put", pattern, f)
-}
-
-// Delete add delete method
-// usage:
-// Delete("/api/:id", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Delete(pattern string, f FilterFunc) {
- p.AddMethod("delete", pattern, f)
-}
-
-// Head add head method
-// usage:
-// Head("/api/:id", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Head(pattern string, f FilterFunc) {
- p.AddMethod("head", pattern, f)
-}
-
-// Patch add patch method
-// usage:
-// Patch("/api/:id", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Patch(pattern string, f FilterFunc) {
- p.AddMethod("patch", pattern, f)
-}
-
-// Options add options method
-// usage:
-// Options("/api/:id", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Options(pattern string, f FilterFunc) {
- p.AddMethod("options", pattern, f)
-}
-
-// Any add all method
-// usage:
-// Any("/api/:id", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) Any(pattern string, f FilterFunc) {
- p.AddMethod("*", pattern, f)
-}
-
-// AddMethod add http method router
-// usage:
-// AddMethod("get","/api/:id", func(ctx *context.Context){
-// ctx.Output.Body("hello world")
-// })
-func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
- method = strings.ToUpper(method)
- if method != "*" && !HTTPMETHOD[method] {
- panic("not support http method: " + method)
- }
- route := &ControllerInfo{}
- route.pattern = pattern
- route.routerType = routerTypeRESTFul
- route.runFunction = f
- methods := make(map[string]string)
- if method == "*" {
- for val := range HTTPMETHOD {
- methods[val] = val
- }
- } else {
- methods[method] = method
- }
- route.methods = methods
- for k := range methods {
- if k == "*" {
- for m := range HTTPMETHOD {
- p.addToRouter(m, pattern, route)
- }
- } else {
- p.addToRouter(k, pattern, route)
- }
- }
-}
-
-// Handler add user defined Handler
-func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) {
- route := &ControllerInfo{}
- route.pattern = pattern
- route.routerType = routerTypeHandler
- route.handler = h
- if len(options) > 0 {
- if _, ok := options[0].(bool); ok {
- pattern = path.Join(pattern, "?:all(.*)")
- }
- }
- for m := range HTTPMETHOD {
- p.addToRouter(m, pattern, route)
- }
-}
-
-// AddAuto router to ControllerRegister.
-// example beego.AddAuto(&MainContorlller{}),
-// MainController has method List and Page.
-// visit the url /main/list to execute List function
-// /main/page to execute Page function.
-func (p *ControllerRegister) AddAuto(c ControllerInterface) {
- p.AddAutoPrefix("/", c)
-}
-
-// AddAutoPrefix Add auto router to ControllerRegister with prefix.
-// example beego.AddAutoPrefix("/admin",&MainContorlller{}),
-// MainController has method List and Page.
-// visit the url /admin/main/list to execute List function
-// /admin/main/page to execute Page function.
-func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) {
- reflectVal := reflect.ValueOf(c)
- rt := reflectVal.Type()
- ct := reflect.Indirect(reflectVal).Type()
- controllerName := strings.TrimSuffix(ct.Name(), "Controller")
- for i := 0; i < rt.NumMethod(); i++ {
- if !utils.InSlice(rt.Method(i).Name, exceptMethod) {
- route := &ControllerInfo{}
- route.routerType = routerTypeBeego
- route.methods = map[string]string{"*": rt.Method(i).Name}
- route.controllerType = ct
- pattern := path.Join(prefix, strings.ToLower(controllerName), strings.ToLower(rt.Method(i).Name), "*")
- patternInit := path.Join(prefix, controllerName, rt.Method(i).Name, "*")
- patternFix := path.Join(prefix, strings.ToLower(controllerName), strings.ToLower(rt.Method(i).Name))
- patternFixInit := path.Join(prefix, controllerName, rt.Method(i).Name)
- route.pattern = pattern
- for m := range HTTPMETHOD {
- p.addToRouter(m, pattern, route)
- p.addToRouter(m, patternInit, route)
- p.addToRouter(m, patternFix, route)
- p.addToRouter(m, patternFixInit, route)
- }
- }
- }
-}
-
-// InsertFilter Add a FilterFunc with pattern rule and action constant.
-// params is for:
-// 1. setting the returnOnOutput value (false allows multiple filters to execute)
-// 2. determining whether or not params need to be reset.
-func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
- mr := &FilterRouter{
- tree: NewTree(),
- pattern: pattern,
- filterFunc: filter,
- returnOnOutput: true,
- }
- if !BConfig.RouterCaseSensitive {
- mr.pattern = strings.ToLower(pattern)
- }
-
- paramsLen := len(params)
- if paramsLen > 0 {
- mr.returnOnOutput = params[0]
- }
- if paramsLen > 1 {
- mr.resetParams = params[1]
- }
- mr.tree.AddRouter(pattern, true)
- return p.insertFilterRouter(pos, mr)
-}
-
-// add Filter into
-func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) {
- if pos < BeforeStatic || pos > FinishRouter {
- return errors.New("can not find your filter position")
- }
- p.enableFilter = true
- p.filters[pos] = append(p.filters[pos], mr)
- return nil
-}
-
-// URLFor does another controller handler in this request function.
-// it can access any controller method.
-func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) string {
- paths := strings.Split(endpoint, ".")
- if len(paths) <= 1 {
- logs.Warn("urlfor endpoint must like path.controller.method")
- return ""
- }
- if len(values)%2 != 0 {
- logs.Warn("urlfor params must key-value pair")
- return ""
- }
- params := make(map[string]string)
- if len(values) > 0 {
- key := ""
- for k, v := range values {
- if k%2 == 0 {
- key = fmt.Sprint(v)
- } else {
- params[key] = fmt.Sprint(v)
- }
- }
- }
- controllerName := strings.Join(paths[:len(paths)-1], "/")
- methodName := paths[len(paths)-1]
- for m, t := range p.routers {
- ok, url := p.getURL(t, "/", controllerName, methodName, params, m)
- if ok {
- return url
- }
- }
- return ""
-}
-
-func (p *ControllerRegister) getURL(t *Tree, url, controllerName, methodName string, params map[string]string, httpMethod string) (bool, string) {
- for _, subtree := range t.fixrouters {
- u := path.Join(url, subtree.prefix)
- ok, u := p.getURL(subtree, u, controllerName, methodName, params, httpMethod)
- if ok {
- return ok, u
- }
- }
- if t.wildcard != nil {
- u := path.Join(url, urlPlaceholder)
- ok, u := p.getURL(t.wildcard, u, controllerName, methodName, params, httpMethod)
- if ok {
- return ok, u
- }
- }
- for _, l := range t.leaves {
- if c, ok := l.runObject.(*ControllerInfo); ok {
- if c.routerType == routerTypeBeego &&
- strings.HasSuffix(path.Join(c.controllerType.PkgPath(), c.controllerType.Name()), controllerName) {
- find := false
- if HTTPMETHOD[strings.ToUpper(methodName)] {
- if len(c.methods) == 0 {
- find = true
- } else if m, ok := c.methods[strings.ToUpper(methodName)]; ok && m == strings.ToUpper(methodName) {
- find = true
- } else if m, ok = c.methods["*"]; ok && m == methodName {
- find = true
- }
- }
- if !find {
- for m, md := range c.methods {
- if (m == "*" || m == httpMethod) && md == methodName {
- find = true
- }
- }
- }
- if find {
- if l.regexps == nil {
- if len(l.wildcards) == 0 {
- return true, strings.Replace(url, "/"+urlPlaceholder, "", 1) + toURL(params)
- }
- if len(l.wildcards) == 1 {
- if v, ok := params[l.wildcards[0]]; ok {
- delete(params, l.wildcards[0])
- return true, strings.Replace(url, urlPlaceholder, v, 1) + toURL(params)
- }
- return false, ""
- }
- if len(l.wildcards) == 3 && l.wildcards[0] == "." {
- if p, ok := params[":path"]; ok {
- if e, isok := params[":ext"]; isok {
- delete(params, ":path")
- delete(params, ":ext")
- return true, strings.Replace(url, urlPlaceholder, p+"."+e, -1) + toURL(params)
- }
- }
- }
- canSkip := false
- for _, v := range l.wildcards {
- if v == ":" {
- canSkip = true
- continue
- }
- if u, ok := params[v]; ok {
- delete(params, v)
- url = strings.Replace(url, urlPlaceholder, u, 1)
- } else {
- if canSkip {
- canSkip = false
- continue
- }
- return false, ""
- }
- }
- return true, url + toURL(params)
- }
- var i int
- var startReg bool
- regURL := ""
- for _, v := range strings.Trim(l.regexps.String(), "^$") {
- if v == '(' {
- startReg = true
- continue
- } else if v == ')' {
- startReg = false
- if v, ok := params[l.wildcards[i]]; ok {
- delete(params, l.wildcards[i])
- regURL = regURL + v
- i++
- } else {
- break
- }
- } else if !startReg {
- regURL = string(append([]rune(regURL), v))
- }
- }
- if l.regexps.MatchString(regURL) {
- ps := strings.Split(regURL, "/")
- for _, p := range ps {
- url = strings.Replace(url, urlPlaceholder, p, 1)
- }
- return true, url + toURL(params)
- }
- }
- }
- }
- }
-
- return false, ""
-}
-
-func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, pos int) (started bool) {
- var preFilterParams map[string]string
- for _, filterR := range p.filters[pos] {
- if filterR.returnOnOutput && context.ResponseWriter.Started {
- return true
- }
- if filterR.resetParams {
- preFilterParams = context.Input.Params()
- }
- if ok := filterR.ValidRouter(urlPath, context); ok {
- filterR.filterFunc(context)
- if filterR.resetParams {
- context.Input.ResetParams()
- for k, v := range preFilterParams {
- context.Input.SetParam(k, v)
- }
- }
- }
- if filterR.returnOnOutput && context.ResponseWriter.Started {
- return true
- }
- }
- return false
-}
-
-// Implement http.Handler interface.
-func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
- startTime := time.Now()
- var (
- runRouter reflect.Type
- findRouter bool
- runMethod string
- methodParams []*param.MethodParam
- routerInfo *ControllerInfo
- isRunnable bool
- )
- context := p.GetContext()
-
- context.Reset(rw, r)
-
- defer p.GiveBackContext(context)
- if BConfig.RecoverFunc != nil {
- defer BConfig.RecoverFunc(context)
- }
-
- context.Output.EnableGzip = BConfig.EnableGzip
-
- if BConfig.RunMode == DEV {
- context.Output.Header("Server", BConfig.ServerName)
- }
-
- var urlPath = r.URL.Path
-
- if !BConfig.RouterCaseSensitive {
- urlPath = strings.ToLower(urlPath)
- }
-
- // filter wrong http method
- if !HTTPMETHOD[r.Method] {
- exception("405", context)
- goto Admin
- }
-
- // filter for static file
- if len(p.filters[BeforeStatic]) > 0 && p.execFilter(context, urlPath, BeforeStatic) {
- goto Admin
- }
-
- serverStaticRouter(context)
-
- if context.ResponseWriter.Started {
- findRouter = true
- goto Admin
- }
-
- if r.Method != http.MethodGet && r.Method != http.MethodHead {
- if BConfig.CopyRequestBody && !context.Input.IsUpload() {
- // connection will close if the incoming data are larger (RFC 7231, 6.5.11)
- if r.ContentLength > BConfig.MaxMemory {
- logs.Error(errors.New("payload too large"))
- exception("413", context)
- goto Admin
- }
- context.Input.CopyBody(BConfig.MaxMemory)
- }
- context.Input.ParseFormOrMulitForm(BConfig.MaxMemory)
- }
-
- // session init
- if BConfig.WebConfig.Session.SessionOn {
- var err error
- context.Input.CruSession, err = GlobalSessions.SessionStart(rw, r)
- if err != nil {
- logs.Error(err)
- exception("503", context)
- goto Admin
- }
- defer func() {
- if context.Input.CruSession != nil {
- context.Input.CruSession.SessionRelease(rw)
- }
- }()
- }
- if len(p.filters[BeforeRouter]) > 0 && p.execFilter(context, urlPath, BeforeRouter) {
- goto Admin
- }
- // User can define RunController and RunMethod in filter
- if context.Input.RunController != nil && context.Input.RunMethod != "" {
- findRouter = true
- runMethod = context.Input.RunMethod
- runRouter = context.Input.RunController
- } else {
- routerInfo, findRouter = p.FindRouter(context)
- }
-
- // if no matches to url, throw a not found exception
- if !findRouter {
- exception("404", context)
- goto Admin
- }
- if splat := context.Input.Param(":splat"); splat != "" {
- for k, v := range strings.Split(splat, "/") {
- context.Input.SetParam(strconv.Itoa(k), v)
- }
- }
-
- if routerInfo != nil {
- // store router pattern into context
- context.Input.SetData("RouterPattern", routerInfo.pattern)
- }
-
- // execute middleware filters
- if len(p.filters[BeforeExec]) > 0 && p.execFilter(context, urlPath, BeforeExec) {
- goto Admin
- }
-
- // check policies
- if p.execPolicy(context, urlPath) {
- goto Admin
- }
-
- if routerInfo != nil {
- if routerInfo.routerType == routerTypeRESTFul {
- if _, ok := routerInfo.methods[r.Method]; ok {
- isRunnable = true
- routerInfo.runFunction(context)
- } else {
- exception("405", context)
- goto Admin
- }
- } else if routerInfo.routerType == routerTypeHandler {
- isRunnable = true
- routerInfo.handler.ServeHTTP(context.ResponseWriter, context.Request)
- } else {
- runRouter = routerInfo.controllerType
- methodParams = routerInfo.methodParams
- method := r.Method
- if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodPut {
- method = http.MethodPut
- }
- if r.Method == http.MethodPost && context.Input.Query("_method") == http.MethodDelete {
- method = http.MethodDelete
- }
- if m, ok := routerInfo.methods[method]; ok {
- runMethod = m
- } else if m, ok = routerInfo.methods["*"]; ok {
- runMethod = m
- } else {
- runMethod = method
- }
- }
- }
-
- // also defined runRouter & runMethod from filter
- if !isRunnable {
- // Invoke the request handler
- var execController ControllerInterface
- if routerInfo != nil && routerInfo.initialize != nil {
- execController = routerInfo.initialize()
- } else {
- vc := reflect.New(runRouter)
- var ok bool
- execController, ok = vc.Interface().(ControllerInterface)
- if !ok {
- panic("controller is not ControllerInterface")
- }
- }
-
- // call the controller init function
- execController.Init(context, runRouter.Name(), runMethod, execController)
-
- // call prepare function
- execController.Prepare()
-
- // if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf
- if BConfig.WebConfig.EnableXSRF {
- execController.XSRFToken()
- if r.Method == http.MethodPost || r.Method == http.MethodDelete || r.Method == http.MethodPut ||
- (r.Method == http.MethodPost && (context.Input.Query("_method") == http.MethodDelete || context.Input.Query("_method") == http.MethodPut)) {
- execController.CheckXSRFCookie()
- }
- }
-
- execController.URLMapping()
-
- if !context.ResponseWriter.Started {
- // exec main logic
- switch runMethod {
- case http.MethodGet:
- execController.Get()
- case http.MethodPost:
- execController.Post()
- case http.MethodDelete:
- execController.Delete()
- case http.MethodPut:
- execController.Put()
- case http.MethodHead:
- execController.Head()
- case http.MethodPatch:
- execController.Patch()
- case http.MethodOptions:
- execController.Options()
- case http.MethodTrace:
- execController.Trace()
- default:
- if !execController.HandlerFunc(runMethod) {
- vc := reflect.ValueOf(execController)
- method := vc.MethodByName(runMethod)
- in := param.ConvertParams(methodParams, method.Type(), context)
- out := method.Call(in)
-
- // For backward compatibility we only handle response if we had incoming methodParams
- if methodParams != nil {
- p.handleParamResponse(context, execController, out)
- }
- }
- }
-
- // render template
- if !context.ResponseWriter.Started && context.Output.Status == 0 {
- if BConfig.WebConfig.AutoRender {
- if err := execController.Render(); err != nil {
- logs.Error(err)
- }
- }
- }
- }
-
- // finish all runRouter. release resource
- execController.Finish()
- }
-
- // execute middleware filters
- if len(p.filters[AfterExec]) > 0 && p.execFilter(context, urlPath, AfterExec) {
- goto Admin
- }
-
- if len(p.filters[FinishRouter]) > 0 && p.execFilter(context, urlPath, FinishRouter) {
- goto Admin
- }
-
-Admin:
- // admin module record QPS
-
- statusCode := context.ResponseWriter.Status
- if statusCode == 0 {
- statusCode = 200
- }
-
- LogAccess(context, &startTime, statusCode)
-
- timeDur := time.Since(startTime)
- context.ResponseWriter.Elapsed = timeDur
- if BConfig.Listen.EnableAdmin {
- pattern := ""
- if routerInfo != nil {
- pattern = routerInfo.pattern
- }
-
- if FilterMonitorFunc(r.Method, r.URL.Path, timeDur, pattern, statusCode) {
- routerName := ""
- if runRouter != nil {
- routerName = runRouter.Name()
- }
- go toolbox.StatisticsMap.AddStatistics(r.Method, r.URL.Path, routerName, timeDur)
- }
- }
-
- if BConfig.RunMode == DEV && !BConfig.Log.AccessLogs {
- match := map[bool]string{true: "match", false: "nomatch"}
- devInfo := fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s",
- context.Input.IP(),
- logs.ColorByStatus(statusCode), statusCode, logs.ResetColor(),
- timeDur.String(),
- match[findRouter],
- logs.ColorByMethod(r.Method), r.Method, logs.ResetColor(),
- r.URL.Path)
- if routerInfo != nil {
- devInfo += fmt.Sprintf(" r:%s", routerInfo.pattern)
- }
-
- logs.Debug(devInfo)
- }
- // Call WriteHeader if status code has been set changed
- if context.Output.Status != 0 {
- context.ResponseWriter.WriteHeader(context.Output.Status)
- }
-}
-
-func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, execController ControllerInterface, results []reflect.Value) {
- // looping in reverse order for the case when both error and value are returned and error sets the response status code
- for i := len(results) - 1; i >= 0; i-- {
- result := results[i]
- if result.Kind() != reflect.Interface || !result.IsNil() {
- resultValue := result.Interface()
- context.RenderMethodResult(resultValue)
- }
- }
- if !context.ResponseWriter.Started && len(results) > 0 && context.Output.Status == 0 {
- context.Output.SetStatus(200)
- }
-}
-
-// FindRouter Find Router info for URL
-func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) {
- var urlPath = context.Input.URL()
- if !BConfig.RouterCaseSensitive {
- urlPath = strings.ToLower(urlPath)
- }
- httpMethod := context.Input.Method()
- if t, ok := p.routers[httpMethod]; ok {
- runObject := t.Match(urlPath, context)
- if r, ok := runObject.(*ControllerInfo); ok {
- return r, true
- }
- }
- return
-}
-
-func toURL(params map[string]string) string {
- if len(params) == 0 {
- return ""
- }
- u := "?"
- for k, v := range params {
- u += k + "=" + v + "&"
- }
- return strings.TrimRight(u, "&")
-}
-
-// LogAccess logging info HTTP Access
-func LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
- // Skip logging if AccessLogs config is false
- if !BConfig.Log.AccessLogs {
- return
- }
- // Skip logging static requests unless EnableStaticLogs config is true
- if !BConfig.Log.EnableStaticLogs && DefaultAccessLogFilter.Filter(ctx) {
- return
- }
- var (
- requestTime time.Time
- elapsedTime time.Duration
- r = ctx.Request
- )
- if startTime != nil {
- requestTime = *startTime
- elapsedTime = time.Since(*startTime)
- }
- record := &logs.AccessLogRecord{
- RemoteAddr: ctx.Input.IP(),
- RequestTime: requestTime,
- RequestMethod: r.Method,
- Request: fmt.Sprintf("%s %s %s", r.Method, r.RequestURI, r.Proto),
- ServerProtocol: r.Proto,
- Host: r.Host,
- Status: statusCode,
- ElapsedTime: elapsedTime,
- HTTPReferrer: r.Header.Get("Referer"),
- HTTPUserAgent: r.Header.Get("User-Agent"),
- RemoteUser: r.Header.Get("Remote-User"),
- BodyBytesSent: 0, // @todo this one is missing!
- }
- logs.AccessLog(record, BConfig.Log.AccessLogsFormat)
-}
diff --git a/src/vendor/github.com/beego/beego/test.sh b/src/vendor/github.com/beego/beego/test.sh
deleted file mode 100644
index 78928fea9..000000000
--- a/src/vendor/github.com/beego/beego/test.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-docker-compose -f test_docker_compose.yaml up -d
-
-export ORM_DRIVER=mysql
-export TZ=UTC
-export ORM_SOURCE="beego:test@tcp(localhost:13306)/orm_test?charset=utf8"
-
-go test ./...
-
-# clear all container
-docker-compose -f test_docker_compose.yaml down
-
-
diff --git a/src/vendor/github.com/beego/beego/test_docker_compose.yaml b/src/vendor/github.com/beego/beego/test_docker_compose.yaml
deleted file mode 100644
index 54ca40971..000000000
--- a/src/vendor/github.com/beego/beego/test_docker_compose.yaml
+++ /dev/null
@@ -1,39 +0,0 @@
-version: "3.8"
-services:
- redis:
- container_name: "beego-redis"
- image: redis
- environment:
- - ALLOW_EMPTY_PASSWORD=yes
- ports:
- - "6379:6379"
-
- mysql:
- container_name: "beego-mysql"
- image: mysql:5.7.30
- ports:
- - "13306:3306"
- environment:
- - MYSQL_ROOT_PASSWORD=1q2w3e
- - MYSQL_DATABASE=orm_test
- - MYSQL_USER=beego
- - MYSQL_PASSWORD=test
-
- postgresql:
- container_name: "beego-postgresql"
- image: bitnami/postgresql:latest
- ports:
- - "5432:5432"
- environment:
- - ALLOW_EMPTY_PASSWORD=yes
- ssdb:
- container_name: "beego-ssdb"
- image: wendal/ssdb
- ports:
- - "8888:8888"
- memcache:
- container_name: "beego-memcache"
- image: memcached
- ports:
- - "11211:11211"
-
diff --git a/src/vendor/github.com/beego/beego/toolbox/task.go b/src/vendor/github.com/beego/beego/toolbox/task.go
deleted file mode 100644
index d2a94ba95..000000000
--- a/src/vendor/github.com/beego/beego/toolbox/task.go
+++ /dev/null
@@ -1,634 +0,0 @@
-// Copyright 2014 beego Author. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package toolbox
-
-import (
- "log"
- "math"
- "sort"
- "strconv"
- "strings"
- "sync"
- "time"
-)
-
-// bounds provides a range of acceptable values (plus a map of name to value).
-type bounds struct {
- min, max uint
- names map[string]uint
-}
-
-// The bounds for each field.
-var (
- AdminTaskList map[string]Tasker
- taskLock sync.RWMutex
- stop chan bool
- changed chan bool
- isstart bool
- seconds = bounds{0, 59, nil}
- minutes = bounds{0, 59, nil}
- hours = bounds{0, 23, nil}
- days = bounds{1, 31, nil}
- months = bounds{1, 12, map[string]uint{
- "jan": 1,
- "feb": 2,
- "mar": 3,
- "apr": 4,
- "may": 5,
- "jun": 6,
- "jul": 7,
- "aug": 8,
- "sep": 9,
- "oct": 10,
- "nov": 11,
- "dec": 12,
- }}
- weeks = bounds{0, 6, map[string]uint{
- "sun": 0,
- "mon": 1,
- "tue": 2,
- "wed": 3,
- "thu": 4,
- "fri": 5,
- "sat": 6,
- }}
-)
-
-const (
- // Set the top bit if a star was included in the expression.
- starBit = 1 << 63
-)
-
-// Schedule time taks schedule
-type Schedule struct {
- Second uint64
- Minute uint64
- Hour uint64
- Day uint64
- Month uint64
- Week uint64
-}
-
-// TaskFunc task func type
-type TaskFunc func() error
-
-// Tasker task interface
-type Tasker interface {
- GetSpec() string
- GetStatus() string
- Run() error
- SetNext(time.Time)
- GetNext() time.Time
- SetPrev(time.Time)
- GetPrev() time.Time
-}
-
-// task error
-type taskerr struct {
- t time.Time
- errinfo string
-}
-
-// Task task struct
-type Task struct {
- Taskname string
- Spec *Schedule
- SpecStr string
- DoFunc TaskFunc
- Prev time.Time
- Next time.Time
- Errlist []*taskerr // like errtime:errinfo
- ErrLimit int // max length for the errlist, 0 stand for no limit
-}
-
-// NewTask add new task with name, time and func
-func NewTask(tname string, spec string, f TaskFunc) *Task {
-
- task := &Task{
- Taskname: tname,
- DoFunc: f,
- ErrLimit: 100,
- SpecStr: spec,
- }
- task.SetCron(spec)
- return task
-}
-
-// GetSpec get spec string
-func (t *Task) GetSpec() string {
- return t.SpecStr
-}
-
-// GetStatus get current task status
-func (t *Task) GetStatus() string {
- var str string
- for _, v := range t.Errlist {
- str += v.t.String() + ":" + v.errinfo + "
"
- }
- return str
-}
-
-// Run run all tasks
-func (t *Task) Run() error {
- err := t.DoFunc()
- if err != nil {
- if t.ErrLimit > 0 && t.ErrLimit > len(t.Errlist) {
- t.Errlist = append(t.Errlist, &taskerr{t: t.Next, errinfo: err.Error()})
- }
- }
- return err
-}
-
-// SetNext set next time for this task
-func (t *Task) SetNext(now time.Time) {
- t.Next = t.Spec.Next(now)
-}
-
-// GetNext get the next call time of this task
-func (t *Task) GetNext() time.Time {
- return t.Next
-}
-
-// SetPrev set prev time of this task
-func (t *Task) SetPrev(now time.Time) {
- t.Prev = now
-}
-
-// GetPrev get prev time of this task
-func (t *Task) GetPrev() time.Time {
- return t.Prev
-}
-
-// six columns mean:
-// second:0-59
-// minute:0-59
-// hour:1-23
-// day:1-31
-// month:1-12
-// week:0-6(0 means Sunday)
-
-// SetCron some signals:
-// *: any time
-// ,: separate signal
-// -:duration
-// /n : do as n times of time duration
-/////////////////////////////////////////////////////////
-// 0/30 * * * * * every 30s
-// 0 43 21 * * * 21:43
-// 0 15 05 * * * 05:15
-// 0 0 17 * * * 17:00
-// 0 0 17 * * 1 17:00 in every Monday
-// 0 0,10 17 * * 0,2,3 17:00 and 17:10 in every Sunday, Tuesday and Wednesday
-// 0 0-10 17 1 * * 17:00 to 17:10 in 1 min duration each time on the first day of month
-// 0 0 0 1,15 * 1 0:00 on the 1st day and 15th day of month
-// 0 42 4 1 * * 4:42 on the 1st day of month
-// 0 0 21 * * 1-6 21:00 from Monday to Saturday
-// 0 0,10,20,30,40,50 * * * * every 10 min duration
-// 0 */10 * * * * every 10 min duration
-// 0 * 1 * * * 1:00 to 1:59 in 1 min duration each time
-// 0 0 1 * * * 1:00
-// 0 0 */1 * * * 0 min of hour in 1 hour duration
-// 0 0 * * * * 0 min of hour in 1 hour duration
-// 0 2 8-20/3 * * * 8:02, 11:02, 14:02, 17:02, 20:02
-// 0 30 5 1,15 * * 5:30 on the 1st day and 15th day of month
-func (t *Task) SetCron(spec string) {
- t.Spec = t.parse(spec)
-}
-
-func (t *Task) parse(spec string) *Schedule {
- if len(spec) > 0 && spec[0] == '@' {
- return t.parseSpec(spec)
- }
- // Split on whitespace. We require 5 or 6 fields.
- // (second) (minute) (hour) (day of month) (month) (day of week, optional)
- fields := strings.Fields(spec)
- if len(fields) != 5 && len(fields) != 6 {
- log.Panicf("Expected 5 or 6 fields, found %d: %s", len(fields), spec)
- }
-
- // If a sixth field is not provided (DayOfWeek), then it is equivalent to star.
- if len(fields) == 5 {
- fields = append(fields, "*")
- }
-
- schedule := &Schedule{
- Second: getField(fields[0], seconds),
- Minute: getField(fields[1], minutes),
- Hour: getField(fields[2], hours),
- Day: getField(fields[3], days),
- Month: getField(fields[4], months),
- Week: getField(fields[5], weeks),
- }
-
- return schedule
-}
-
-func (t *Task) parseSpec(spec string) *Schedule {
- switch spec {
- case "@yearly", "@annually":
- return &Schedule{
- Second: 1 << seconds.min,
- Minute: 1 << minutes.min,
- Hour: 1 << hours.min,
- Day: 1 << days.min,
- Month: 1 << months.min,
- Week: all(weeks),
- }
-
- case "@monthly":
- return &Schedule{
- Second: 1 << seconds.min,
- Minute: 1 << minutes.min,
- Hour: 1 << hours.min,
- Day: 1 << days.min,
- Month: all(months),
- Week: all(weeks),
- }
-
- case "@weekly":
- return &Schedule{
- Second: 1 << seconds.min,
- Minute: 1 << minutes.min,
- Hour: 1 << hours.min,
- Day: all(days),
- Month: all(months),
- Week: 1 << weeks.min,
- }
-
- case "@daily", "@midnight":
- return &Schedule{
- Second: 1 << seconds.min,
- Minute: 1 << minutes.min,
- Hour: 1 << hours.min,
- Day: all(days),
- Month: all(months),
- Week: all(weeks),
- }
-
- case "@hourly":
- return &Schedule{
- Second: 1 << seconds.min,
- Minute: 1 << minutes.min,
- Hour: all(hours),
- Day: all(days),
- Month: all(months),
- Week: all(weeks),
- }
- }
- log.Panicf("Unrecognized descriptor: %s", spec)
- return nil
-}
-
-// Next set schedule to next time
-func (s *Schedule) Next(t time.Time) time.Time {
-
- // Start at the earliest possible time (the upcoming second).
- t = t.Add(1*time.Second - time.Duration(t.Nanosecond())*time.Nanosecond)
-
- // This flag indicates whether a field has been incremented.
- added := false
-
- // If no time is found within five years, return zero.
- yearLimit := t.Year() + 5
-
-WRAP:
- if t.Year() > yearLimit {
- return time.Time{}
- }
-
- // Find the first applicable month.
- // If it's this month, then do nothing.
- for 1< 0
- dowMatch = 1< 0
- )
-
- if s.Day&starBit > 0 || s.Week&starBit > 0 {
- return domMatch && dowMatch
- }
- return domMatch || dowMatch
-}
-
-// StartTask start all tasks
-func StartTask() {
- taskLock.Lock()
- defer taskLock.Unlock()
- if isstart {
- //If already started, no need to start another goroutine.
- return
- }
- isstart = true
- go run()
-}
-
-func run() {
- now := time.Now().Local()
- for _, t := range AdminTaskList {
- t.SetNext(now)
- }
-
- for {
- // we only use RLock here because NewMapSorter copy the reference, do not change any thing
- taskLock.RLock()
- sortList := NewMapSorter(AdminTaskList)
- taskLock.RUnlock()
- sortList.Sort()
- var effective time.Time
- if len(AdminTaskList) == 0 || sortList.Vals[0].GetNext().IsZero() {
- // If there are no entries yet, just sleep - it still handles new entries
- // and stop requests.
- effective = now.AddDate(10, 0, 0)
- } else {
- effective = sortList.Vals[0].GetNext()
- }
- select {
- case now = <-time.After(effective.Sub(now)):
- // Run every entry whose next time was this effective time.
- for _, e := range sortList.Vals {
- if e.GetNext() != effective {
- break
- }
- go e.Run()
- e.SetPrev(e.GetNext())
- e.SetNext(effective)
- }
- continue
- case <-changed:
- now = time.Now().Local()
- taskLock.Lock()
- for _, t := range AdminTaskList {
- t.SetNext(now)
- }
- taskLock.Unlock()
- continue
- case <-stop:
- return
- }
- }
-}
-
-// StopTask stop all tasks
-func StopTask() {
- taskLock.Lock()
- defer taskLock.Unlock()
- if isstart {
- isstart = false
- stop <- true
- }
-
-}
-
-// AddTask add task with name
-func AddTask(taskname string, t Tasker) {
- taskLock.Lock()
- defer taskLock.Unlock()
- t.SetNext(time.Now().Local())
- AdminTaskList[taskname] = t
- if isstart {
- changed <- true
- }
-}
-
-// DeleteTask delete task with name
-func DeleteTask(taskname string) {
- taskLock.Lock()
- defer taskLock.Unlock()
- delete(AdminTaskList, taskname)
- if isstart {
- changed <- true
- }
-}
-
-// MapSorter sort map for tasker
-type MapSorter struct {
- Keys []string
- Vals []Tasker
-}
-
-// NewMapSorter create new tasker map
-func NewMapSorter(m map[string]Tasker) *MapSorter {
- ms := &MapSorter{
- Keys: make([]string, 0, len(m)),
- Vals: make([]Tasker, 0, len(m)),
- }
- for k, v := range m {
- ms.Keys = append(ms.Keys, k)
- ms.Vals = append(ms.Vals, v)
- }
- return ms
-}
-
-// Sort sort tasker map
-func (ms *MapSorter) Sort() {
- sort.Sort(ms)
-}
-
-func (ms *MapSorter) Len() int { return len(ms.Keys) }
-func (ms *MapSorter) Less(i, j int) bool {
- if ms.Vals[i].GetNext().IsZero() {
- return false
- }
- if ms.Vals[j].GetNext().IsZero() {
- return true
- }
- return ms.Vals[i].GetNext().Before(ms.Vals[j].GetNext())
-}
-func (ms *MapSorter) Swap(i, j int) {
- ms.Vals[i], ms.Vals[j] = ms.Vals[j], ms.Vals[i]
- ms.Keys[i], ms.Keys[j] = ms.Keys[j], ms.Keys[i]
-}
-
-func getField(field string, r bounds) uint64 {
- // list = range {"," range}
- var bits uint64
- ranges := strings.FieldsFunc(field, func(r rune) bool { return r == ',' })
- for _, expr := range ranges {
- bits |= getRange(expr, r)
- }
- return bits
-}
-
-// getRange returns the bits indicated by the given expression:
-// number | number "-" number [ "/" number ]
-func getRange(expr string, r bounds) uint64 {
-
- var (
- start, end, step uint
- rangeAndStep = strings.Split(expr, "/")
- lowAndHigh = strings.Split(rangeAndStep[0], "-")
- singleDigit = len(lowAndHigh) == 1
- )
-
- var extrastar uint64
- if lowAndHigh[0] == "*" || lowAndHigh[0] == "?" {
- start = r.min
- end = r.max
- extrastar = starBit
- } else {
- start = parseIntOrName(lowAndHigh[0], r.names)
- switch len(lowAndHigh) {
- case 1:
- end = start
- case 2:
- end = parseIntOrName(lowAndHigh[1], r.names)
- default:
- log.Panicf("Too many hyphens: %s", expr)
- }
- }
-
- switch len(rangeAndStep) {
- case 1:
- step = 1
- case 2:
- step = mustParseInt(rangeAndStep[1])
-
- // Special handling: "N/step" means "N-max/step".
- if singleDigit {
- end = r.max
- }
- default:
- log.Panicf("Too many slashes: %s", expr)
- }
-
- if start < r.min {
- log.Panicf("Beginning of range (%d) below minimum (%d): %s", start, r.min, expr)
- }
- if end > r.max {
- log.Panicf("End of range (%d) above maximum (%d): %s", end, r.max, expr)
- }
- if start > end {
- log.Panicf("Beginning of range (%d) beyond end of range (%d): %s", start, end, expr)
- }
-
- return getBits(start, end, step) | extrastar
-}
-
-// parseIntOrName returns the (possibly-named) integer contained in expr.
-func parseIntOrName(expr string, names map[string]uint) uint {
- if names != nil {
- if namedInt, ok := names[strings.ToLower(expr)]; ok {
- return namedInt
- }
- }
- return mustParseInt(expr)
-}
-
-// mustParseInt parses the given expression as an int or panics.
-func mustParseInt(expr string) uint {
- num, err := strconv.Atoi(expr)
- if err != nil {
- log.Panicf("Failed to parse int from %s: %s", expr, err)
- }
- if num < 0 {
- log.Panicf("Negative number (%d) not allowed: %s", num, expr)
- }
-
- return uint(num)
-}
-
-// getBits sets all bits in the range [min, max], modulo the given step size.
-func getBits(min, max, step uint) uint64 {
- var bits uint64
-
- // If step is 1, use shifts.
- if step == 1 {
- return ^(math.MaxUint64 << (max + 1)) & (math.MaxUint64 << min)
- }
-
- // Else, use a simple loop.
- for i := min; i <= max; i += step {
- bits |= 1 << i
- }
- return bits
-}
-
-// all returns all bits within the given bounds. (plus the star bit)
-func all(r bounds) uint64 {
- return getBits(r.min, r.max, 1) | starBit
-}
-
-func init() {
- AdminTaskList = make(map[string]Tasker)
- stop = make(chan bool)
- changed = make(chan bool)
-}
diff --git a/src/vendor/github.com/beego/beego/v2/.deepsource.toml b/src/vendor/github.com/beego/beego/v2/.deepsource.toml
new file mode 100644
index 000000000..7901d2d2a
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/.deepsource.toml
@@ -0,0 +1,12 @@
+version = 1
+
+test_patterns = ["**/*_test.go"]
+
+exclude_patterns = ["scripts/**"]
+
+[[analyzers]]
+name = "go"
+enabled = true
+
+ [analyzers.meta]
+ import_paths = ["github.com/beego/beego"]
diff --git a/src/vendor/github.com/beego/beego/v2/.gitignore b/src/vendor/github.com/beego/beego/v2/.gitignore
new file mode 100644
index 000000000..9a2af3cfc
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/.gitignore
@@ -0,0 +1,17 @@
+.idea
+.vscode
+.DS_Store
+*.swp
+*.swo
+beego.iml
+
+_beeTmp/
+_beeTmp2/
+pkg/_beeTmp/
+pkg/_beeTmp2/
+test/tmp/
+core/config/env/pkg/
+
+my save path/
+
+profile.out
diff --git a/src/vendor/github.com/beego/beego/v2/CHANGELOG.md b/src/vendor/github.com/beego/beego/v2/CHANGELOG.md
new file mode 100644
index 000000000..7e803c991
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/CHANGELOG.md
@@ -0,0 +1,136 @@
+# developing
+
+# v2.0.5
+
+Note: now we force the web admin service serving HTTP only.
+
+- [Fix 4984: random expire cache](https://github.com/beego/beego/pull/4984)
+- [Fix 4907: make admin serve HTTP only](https://github.com/beego/beego/pull/5005)
+- [Feat 4999: add get all tasks function](https://github.com/beego/beego/pull/4999)
+- [Fix 5012: fix some bug, pass []any as any in variadic function](https://github.com/beego/beego/pull/5012)
+- [Fix 5022: Miss assigning listener to graceful Server](https://github.com/beego/beego/pull/5028)
+- [Fix 4955: Make commands and Docker compose for ORM unit tests](https://github.com/beego/beego/pull/5031)
+
+
+# v2.0.4
+
+Note: now we force the web admin service serving HTTP only.
+
+- [Fix issue 4961, `leafInfo.match()` use `path.join()` to deal with `wildcardValues`, which may lead to cross directory risk ](https://github.com/beego/beego/pull/4964)
+- [Fix 4975: graceful server listen the specific address](https://github.com/beego/beego/pull/4979)
+- [Fix 4976: make admin serve HTTP only](https://github.com/beego/beego/pull/4980)
+
+# v2.0.3
+- [upgrade redisgo to v1.8.8](https://github.com/beego/beego/pull/4872)
+- [fix prometheus CVE-2022-21698](https://github.com/beego/beego/pull/4878)
+- [upgrade to Go 1.18](https://github.com/beego/beego/pull/4896)
+- [make `PatternLogFormatter` handling the arguments](https://github.com/beego/beego/pull/4914/files)
+- [Add httplib OpenTelemetry Filter](https://github.com/beego/beego/pull/4888, https://github.com/beego/beego/pull/4915)
+- [Add orm OpenTelemetry Filter](https://github.com/beego/beego/issues/4944)
+- [Support NewBeegoRequestWithCtx in httplib](https://github.com/beego/beego/pull/4895)
+- [Support lifecycle callback](https://github.com/beego/beego/pull/4918)
+- [Append column comments to create table sentence when using postgres](https://github.com/beego/beego/pull/4940)
+- [logs: multiFileLogWriter uses incorrect formatter](https://github.com/beego/beego/pull/4943)
+- [fix issue 4946 CVE-2022-31259](https://github.com/beego/beego/pull/4954)
+
+# v2.0.2
+See v2.0.2-beta.1
+- [fix bug: etcd should use etcd as adapter name](https://github.com/beego/beego/pull/4845)
+# v2.0.2-beta.1
+- Add a custom option for whether to escape HTML special characters when processing http request parameters. [4701](https://github.com/beego/beego/pull/4701)
+- Always set the response status in the CustomAbort function. [4686](https://github.com/beego/beego/pull/4686)
+- Add template functions eq,lt to support uint and int compare. [4607](https://github.com/beego/beego/pull/4607)
+- Migrate tests to GitHub Actions. [4663](https://github.com/beego/beego/issues/4663)
+- Add http client and option func. [4455](https://github.com/beego/beego/issues/4455)
+- Add: Convenient way to generate mock object [4620](https://github.com/beego/beego/issues/4620)
+- Infra: use dependabot to update dependencies. [4623](https://github.com/beego/beego/pull/4623)
+- Lint: use golangci-lint. [4619](https://github.com/beego/beego/pull/4619)
+- Chore: format code. [4615](https://github.com/beego/beego/pull/4615)
+- Test on Go v1.15.x & v1.16.x. [4614](https://github.com/beego/beego/pull/4614)
+- Env: non-empty GOBIN & GOPATH. [4613](https://github.com/beego/beego/pull/4613)
+- Chore: update dependencies. [4611](https://github.com/beego/beego/pull/4611)
+- Update orm_test.go/TestInsertOrUpdate with table-driven. [4609](https://github.com/beego/beego/pull/4609)
+- Add: Resp() method for web.Controller. [4588](https://github.com/beego/beego/pull/4588)
+- Web mock and test support. [4565](https://github.com/beego/beego/pull/4565) [4574](https://github.com/beego/beego/pull/4574)
+- Error codes definition of cache module. [4493](https://github.com/beego/beego/pull/4493)
+- Remove generateCommentRoute http hook. Using `bee generate routers` commands instead.[4486](https://github.com/beego/beego/pull/4486) [bee PR 762](https://github.com/beego/bee/pull/762)
+- Fix: /abc.html/aaa match /abc/aaa. [4459](https://github.com/beego/beego/pull/4459)
+- ORM mock. [4407](https://github.com/beego/beego/pull/4407)
+- Add sonar check and ignore test. [4432](https://github.com/beego/beego/pull/4432) [4433](https://github.com/beego/beego/pull/4433)
+- Update changlog.yml to check every PR to develop branch.[4427](https://github.com/beego/beego/pull/4427)
+- Fix 4396: Add context.param module into adapter. [4398](https://github.com/beego/beego/pull/4398)
+- Support `RollbackUnlessCommit` API. [4542](https://github.com/beego/beego/pull/4542)
+- Fix 4503 and 4504: Add `when` to `Write([]byte)` method and add `prefix` to `writeMsg`. [4507](https://github.com/beego/beego/pull/4507)
+- Fix 4480: log format incorrect. [4482](https://github.com/beego/beego/pull/4482)
+- Remove `duration` from prometheus labels. [4391](https://github.com/beego/beego/pull/4391)
+- Fix `unknown escape sequence` in generated code. [4385](https://github.com/beego/beego/pull/4385)
+- Fix 4590: Forget to check URL when FilterChain invoke `next()`. [4593](https://github.com/beego/beego/pull/4593)
+- Fix 4727: CSS when request URI is invalid. [4729](https://github.com/beego/beego/pull/4729)
+- Using fixed name `commentRouter.go` as generated file name. [4385](https://github.com/beego/beego/pull/4385)
+- Fix 4383: ORM Adapter produces panic when using orm.RegisterModelWithPrefix. [4386](https://github.com/beego/beego/pull/4386)
+- Support 4144: Add new api for order by for supporting multiple way to query [4294](https://github.com/beego/beego/pull/4294)
+- Support session Filter chain. [4404](https://github.com/beego/beego/pull/4404)
+- Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416)
+- Implement context.Context support and deprecate `QueryM2MWithCtx` and `QueryTableWithCtx` [4424](https://github.com/beego/beego/pull/4424)
+- Finish timeout option for tasks #4441 [4441](https://github.com/beego/beego/pull/4441)
+- Error Module brief design & using httplib module to validate this design. [4453](https://github.com/beego/beego/pull/4453)
+- Fix 4444: panic when 404 not found. [4446](https://github.com/beego/beego/pull/4446)
+- Fix 4435: fix panic when controller dir not found. [4452](https://github.com/beego/beego/pull/4452)
+- Hotfix:reflect.ValueOf(nil) in getFlatParams [4716](https://github.com/beego/beego/issues/4716)
+- Fix 4456: Fix router method expression [4456](https://github.com/beego/beego/pull/4456)
+- Remove some `go get` lines in `.travis.yml` file [4469](https://github.com/beego/beego/pull/4469)
+- Fix 4451: support QueryExecutor interface. [4461](https://github.com/beego/beego/pull/4461)
+- Add some testing scripts [4461](https://github.com/beego/beego/pull/4461)
+- Refactor httplib: Move debug code to a filter [4440](https://github.com/beego/beego/issues/4440)
+- fix: code quality issues [4513](https://github.com/beego/beego/pull/4513)
+- Optimize maligned structs to reduce memory foot-print [4525](https://github.com/beego/beego/pull/4525)
+- Feat: add token bucket ratelimit filter [4508](https://github.com/beego/beego/pull/4508)
+- Improve: Avoid ignoring mistakes that need attention [4548](https://github.com/beego/beego/pull/4548)
+- Integration: DeepSource [4560](https://github.com/beego/beego/pull/4560)
+- Integration: Remove unnecessary function call [4577](https://github.com/beego/beego/pull/4577)
+- Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416)
+- Proposal: Add Bind() method for `web.Controller` [4491](https://github.com/beego/beego/issues/4579)
+- Optimize AddAutoPrefix: only register one router in case-insensitive mode. [4582](https://github.com/beego/beego/pull/4582)
+- Init exceptMethod by using reflection. [4583](https://github.com/beego/beego/pull/4583)
+- Deprecated BeeMap and replace all usage with `sync.map` [4616](https://github.com/beego/beego/pull/4616)
+- TaskManager support graceful shutdown [4635](https://github.com/beego/beego/pull/4635)
+- Add comments to `web.Config`, rename `RouterXXX` to `CtrlXXX`, define `HandleFunc` [4714](https://github.com/beego/beego/pull/4714)
+- Refactor: Move `BindXXX` and `XXXResp` methods to `context.Context`. [4718](https://github.com/beego/beego/pull/4718)
+- Fix 4728: Print wrong file name. [4737](https://github.com/beego/beego/pull/4737)
+- fix bug:reflect.ValueOf(nil) in getFlatParams [4715](https://github.com/beego/beego/pull/4715)
+- Fix 4736: set a fixed value "/" to the "Path" of "_xsrf" cookie. [4736](https://github.com/beego/beego/issues/4735) [4739](https://github.com/beego/beego/issues/4739)
+- Fix 4734: do not reset id in Delete function. [4738](https://github.com/beego/beego/pull/4738) [4742](https://github.com/beego/beego/pull/4742)
+- Fix 4699: Remove Remove goyaml2 dependency. [4755](https://github.com/beego/beego/pull/4755)
+- Fix 4698: Prompt error when config format is incorrect. [4757](https://github.com/beego/beego/pull/4757)
+- Fix 4674: Tx Orm missing debug log [4756](https://github.com/beego/beego/pull/4756)
+- Fix 4759: fix numeric notation of permissions [4759](https://github.com/beego/beego/pull/4759)
+- set default rate and capacity for ratelimit filter [4796](https://github.com/beego/beego/pull/4796)
+- Fix 4782: must set status before rendering error page [4797](https://github.com/beego/beego/pull/4797)
+- Fix 4791: delay to format parameter in log module [4804](https://github.com/beego/beego/pull/4804)
+
+## Fix Sonar
+
+- [4677](https://github.com/beego/beego/pull/4677)
+- [4624](https://github.com/beego/beego/pull/4624)
+- [4608](https://github.com/beego/beego/pull/4608)
+- [4473](https://github.com/beego/beego/pull/4473)
+- [4474](https://github.com/beego/beego/pull/4474)
+- [4479](https://github.com/beego/beego/pull/4479)
+- [4639](https://github.com/beego/beego/pull/4639)
+- [4668](https://github.com/beego/beego/pull/4668)
+
+## Fix lint and format code
+
+- [4644](https://github.com/beego/beego/pull/4644)
+- [4645](https://github.com/beego/beego/pull/4645)
+- [4646](https://github.com/beego/beego/pull/4646)
+- [4647](https://github.com/beego/beego/pull/4647)
+- [4648](https://github.com/beego/beego/pull/4648)
+- [4649](https://github.com/beego/beego/pull/4649)
+- [4651](https://github.com/beego/beego/pull/4651)
+- [4652](https://github.com/beego/beego/pull/4652)
+- [4653](https://github.com/beego/beego/pull/4653)
+- [4654](https://github.com/beego/beego/pull/4654)
+- [4655](https://github.com/beego/beego/pull/4655)
+- [4656](https://github.com/beego/beego/pull/4656)
+- [4660](https://github.com/beego/beego/pull/4660)
diff --git a/src/vendor/github.com/beego/beego/v2/CONTRIBUTING.md b/src/vendor/github.com/beego/beego/v2/CONTRIBUTING.md
new file mode 100644
index 000000000..59cc5682c
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/CONTRIBUTING.md
@@ -0,0 +1,93 @@
+# Contributing to beego
+
+beego is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+Here are instructions to get you started. They are probably not perfect, please let us know if anything feels wrong or
+incomplete.
+
+## Prepare environment
+
+Firstly, install some tools. Execute those commands **outside** the project. Or those command will modify go.mod file.
+
+```shell script
+go get -u golang.org/x/tools/cmd/goimports
+
+go get -u github.com/gordonklaus/ineffassign
+```
+
+Put those lines into your pre-commit githook script:
+
+```shell script
+goimports -w -format-only ./
+
+ineffassign .
+
+staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024" ./
+```
+
+## Prepare middleware
+
+Beego uses many middlewares, including MySQL, Redis, SSDB and so on.
+
+We provide docker compose file to start all middlewares.
+
+You can run:
+
+```shell script
+docker-compose -f scripts/test_docker_compose.yaml up -d
+```
+
+Unit tests read addresses from environment, here is an example:
+
+```shell script
+export ORM_DRIVER=mysql
+export ORM_SOURCE="beego:test@tcp(192.168.0.105:13306)/orm_test?charset=utf8"
+export MEMCACHE_ADDR="192.168.0.105:11211"
+export REDIS_ADDR="192.168.0.105:6379"
+export SSDB_ADDR="192.168.0.105:8888"
+```
+
+## Contribution guidelines
+
+### Pull requests
+
+First, beego follow the gitflow. So please send you pull request to **develop** branch. We will close the pull
+request to master branch.
+
+By the way, please don't forget update the `CHANGELOG.md` before you send pull request.
+You can just add your pull request following 'developing' section in `CHANGELOG.md`.
+We'll release them in the next Beego version.
+
+We are always happy to receive pull requests, and do our best to review them as fast as possible. Not sure if that typo
+is worth a pull request? Do it! We will appreciate it.
+
+Don't forget to rebase your commits!
+
+If your pull request is not accepted on the first try, don't be discouraged! Sometimes we can make a mistake, please do
+more explaining for us. We will appreciate it.
+
+We're trying very hard to keep beego simple and fast. We don't want it to do everything for everybody. This means that
+we might decide against incorporating a new feature. But we will give you some advice on how to do it in other way.
+
+### Create issues
+
+Any significant improvement should be documented as [a GitHub issue](https://github.com/beego/beego/v2/issues) before
+anybody starts working on it.
+
+Also when filing an issue, make sure to answer these five questions:
+
+- What version of beego are you using (bee version)?
+- What operating system and processor architecture are you using?
+- What did you do?
+- What did you expect to see?
+- What did you see instead?
+
+### but check existing issues and docs first!
+
+Please take a moment to check that an issue doesn't already exist documenting your bug report or improvement proposal.
+If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common
+problems and requests.
+
+Also, if you don't know how to use it. please make sure you have read through the docs in http://beego.vip/docs
diff --git a/src/vendor/github.com/beego/beego/v2/ERROR_SPECIFICATION.md b/src/vendor/github.com/beego/beego/v2/ERROR_SPECIFICATION.md
new file mode 100644
index 000000000..68a04bd11
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/ERROR_SPECIFICATION.md
@@ -0,0 +1,5 @@
+# Error Module
+
+## Module code
+- httplib 1
+- cache 2
\ No newline at end of file
diff --git a/src/vendor/github.com/beego/beego/LICENSE b/src/vendor/github.com/beego/beego/v2/LICENSE
similarity index 94%
rename from src/vendor/github.com/beego/beego/LICENSE
rename to src/vendor/github.com/beego/beego/v2/LICENSE
index 5dbd42435..26050108e 100644
--- a/src/vendor/github.com/beego/beego/LICENSE
+++ b/src/vendor/github.com/beego/beego/v2/LICENSE
@@ -10,4 +10,4 @@ Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
-limitations under the License.
\ No newline at end of file
+limitations under the License.
diff --git a/src/vendor/github.com/beego/beego/v2/Makefile b/src/vendor/github.com/beego/beego/v2/Makefile
new file mode 100644
index 000000000..d2a2e169b
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/Makefile
@@ -0,0 +1,64 @@
+# Copyright 2020
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+##@ General
+
+# The help target prints out all targets with their descriptions organized
+# beneath their categories. The categories are represented by '##@' and the
+# target descriptions by '##'. The awk commands is responsible for reading the
+# entire set of makefiles included in this invocation, looking for lines of the
+# file as xyz: ## something, and then pretty-format the target and help. Then,
+# if there's a line with ##@ something, that gets pretty-printed as a category.
+# More info on the usage of ANSI control characters for terminal formatting:
+# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
+# More info on the awk command:
+# http://linuxcommand.org/lc3_adv_awk.php
+
+help: ## Display this help.
+ @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
+
+
+##@ Test
+
+test-orm-mysql5: ## Run ORM unit tests on mysql5.
+ docker-compose -f scripts/orm_docker_compose.yaml up -d
+ export ORM_DRIVER=mysql
+ export ORM_SOURCE="beego:test@tcp(localhost:13306)/orm_test?charset=utf8"
+ go test -v github.com/beego/beego/v2/client/orm
+ docker-compose -f scripts/orm_docker_compose.yaml down
+
+test-orm-mysql8: ## Run ORM unit tests on mysql8.
+ docker-compose -f scripts/orm_docker_compose.yaml up -d
+ export ORM_DRIVER=mysql
+ export ORM_SOURCE="beego:test@tcp(localhost:23306)/orm_test?charset=utf8"
+ go test -v github.com/beego/beego/v2/client/orm
+ docker-compose -f scripts/orm_docker_compose.yaml down
+
+test-orm-pgsql: ## Run ORM unit tests on postgresql.
+ docker-compose -f scripts/orm_docker_compose.yaml up -d
+ export ORM_DRIVER=postgres
+ export ORM_SOURCE="user=postgres password=postgres dbname=orm_test sslmode=disable"
+ go test -v github.com/beego/beego/v2/client/orm
+ docker-compose -f scripts/orm_docker_compose.yaml down
+
+test-orm-tidb: ## Run ORM unit tests on tidb.
+ docker-compose -f scripts/orm_docker_compose.yaml up -d
+ export ORM_DRIVER=tidb
+ export ORM_SOURCE="memory://test/test"
+ go test -v github.com/beego/beego/v2/client/orm
+ docker-compose -f scripts/orm_docker_compose.yaml down
+
+.PHONY: test-orm-all
+test-orm-all: test-orm-mysql5 test-orm-mysql8 test-orm-pgsql test-orm-tidb
diff --git a/src/vendor/github.com/beego/beego/v2/README.md b/src/vendor/github.com/beego/beego/v2/README.md
new file mode 100644
index 000000000..d361f66ed
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/README.md
@@ -0,0 +1,99 @@
+# Beego [](https://github.com/beego/beego/actions/workflows/test.yml) [](https://goreportcard.com/report/github.com/beego/beego) [](https://pkg.go.dev/github.com/beego/beego/v2)
+
+Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services.
+
+It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding.
+
+
+
+Beego is composed of four parts:
+
+1. Base modules: including log module, config module, governor module;
+2. Task: is used for running timed tasks or periodic tasks;
+3. Client: including ORM module, httplib module, cache module;
+4. Server: including web module. We will support gRPC in the future;
+
+**Please use RELEASE version, or master branch which contains the latest bug fix**
+
+## Quick Start
+
+[Official website](http://beego.vip)
+[中文新版文档网站](https://beego.gocn.vip)
+
+[Example](https://github.com/beego/beego-example)
+
+> If you could not open official website, go to [beedoc](https://github.com/beego/beedoc)
+
+### Web Application
+
+
+
+#### Create `hello` directory, cd `hello` directory
+
+ mkdir hello
+ cd hello
+
+#### Init module
+
+ go mod init
+
+#### Download and install
+
+ go get github.com/beego/beego/v2@latest
+
+#### Create file `hello.go`
+
+```go
+package main
+
+import "github.com/beego/beego/v2/server/web"
+
+func main() {
+ web.Run()
+}
+```
+
+#### Build and run
+
+ go build hello.go
+ ./hello
+
+#### Go to [http://localhost:8080](http://localhost:8080)
+
+Congratulations! You've just built your first **beego** app.
+
+## Features
+
+* RESTful support
+* [MVC architecture](https://github.com/beego/beedoc/tree/master/en-US/mvc)
+* Modularity
+* [Auto API documents](https://github.com/beego/beedoc/blob/master/en-US/advantage/docs.md)
+* [Annotation router](https://github.com/beego/beedoc/blob/master/en-US/mvc/controller/router.md)
+* [Namespace](https://github.com/beego/beedoc/blob/master/en-US/mvc/controller/router.md#namespace)
+* [Powerful development tools](https://github.com/beego/bee)
+* Full stack for Web & API
+
+## Modules
+
+* [orm](https://github.com/beego/beedoc/tree/master/en-US/mvc/model)
+* [session](https://github.com/beego/beedoc/blob/master/en-US/module/session.md)
+* [logs](https://github.com/beego/beedoc/blob/master/en-US/module/logs.md)
+* [config](https://github.com/beego/beedoc/blob/master/en-US/module/config.md)
+* [cache](https://github.com/beego/beedoc/blob/master/en-US/module/cache.md)
+* [context](https://github.com/beego/beedoc/blob/master/en-US/module/context.md)
+* [admin](https://github.com/beego/beedoc/blob/master/en-US/module/admin.md)
+* [httplib](https://github.com/beego/beedoc/blob/master/en-US/module/httplib.md)
+* [task](https://github.com/beego/beedoc/blob/master/en-US/module/task.md)
+* [i18n](https://github.com/beego/beedoc/blob/master/en-US/module/i18n.md)
+
+## Community
+
+* [http://beego.vip/community](http://beego.vip/community)
+* Welcome to join us in Slack: [https://beego.slack.com invite](https://join.slack.com/t/beego/shared_invite/zt-fqlfjaxs-_CRmiITCSbEqQG9NeBqXKA),
+* QQ Group ID:523992905
+* [Contribution Guide](https://github.com/beego/beedoc/blob/master/en-US/intro/contributing.md).
+
+## License
+
+beego source code is licensed under the Apache Licence, Version 2.0
+([https://www.apache.org/licenses/LICENSE-2.0.html](https://www.apache.org/licenses/LICENSE-2.0.html)).
diff --git a/src/vendor/github.com/beego/beego/build_info.go b/src/vendor/github.com/beego/beego/v2/build_info.go
similarity index 90%
rename from src/vendor/github.com/beego/beego/build_info.go
rename to src/vendor/github.com/beego/beego/v2/build_info.go
index c31152ea3..23f74b53a 100644
--- a/src/vendor/github.com/beego/beego/build_info.go
+++ b/src/vendor/github.com/beego/beego/v2/build_info.go
@@ -25,3 +25,8 @@ var (
GitBranch string
)
+
+const (
+ // VERSION represent beego web framework version.
+ VERSION = "2.0.0"
+)
diff --git a/src/vendor/github.com/beego/beego/cache/README.md b/src/vendor/github.com/beego/beego/v2/client/cache/README.md
similarity index 89%
rename from src/vendor/github.com/beego/beego/cache/README.md
rename to src/vendor/github.com/beego/beego/v2/client/cache/README.md
index 1c037c87c..df1ea0957 100644
--- a/src/vendor/github.com/beego/beego/cache/README.md
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/README.md
@@ -1,37 +1,34 @@
## cache
-cache is a Go cache manager. It can use many cache adapters. The repo is inspired by `database/sql` .
+cache is a Go cache manager. It can use many cache adapters. The repo is inspired by `database/sql` .
## How to install?
- go get github.com/beego/beego/cache
-
+ go get github.com/beego/beego/v2/client/cache
## What adapters are supported?
As of now this cache support memory, Memcache and Redis.
-
## How to use it?
First you must import it
import (
- "github.com/beego/beego/cache"
+ "github.com/beego/beego/v2/client/cache"
)
Then init a Cache (example with memory adapter)
bm, err := cache.NewCache("memory", `{"interval":60}`)
-Use it like this:
-
+Use it like this:
+
bm.Put("astaxie", 1, 10 * time.Second)
bm.Get("astaxie")
bm.IsExist("astaxie")
bm.Delete("astaxie")
-
## Memory adapter
Configure memory adapter like this:
@@ -40,7 +37,6 @@ Configure memory adapter like this:
interval means the gc time. The cache will check at each time interval, whether item has expired.
-
## Memcache adapter
Memcache adapter use the [gomemcache](http://github.com/bradfitz/gomemcache) client.
@@ -49,7 +45,6 @@ Configure like this:
{"conn":"127.0.0.1:11211"}
-
## Redis adapter
Redis adapter use the [redigo](http://github.com/gomodule/redigo) client.
diff --git a/src/vendor/github.com/beego/beego/cache/cache.go b/src/vendor/github.com/beego/beego/v2/client/cache/cache.go
similarity index 60%
rename from src/vendor/github.com/beego/beego/cache/cache.go
rename to src/vendor/github.com/beego/beego/v2/client/cache/cache.go
index 1a4926420..1eafccdc1 100644
--- a/src/vendor/github.com/beego/beego/cache/cache.go
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/cache.go
@@ -16,7 +16,7 @@
// Usage:
//
// import(
-// "github.com/beego/beego/cache"
+// "github.com/beego/beego/v2/client/cache"
// )
//
// bm, err := cache.NewCache("memory", `{"interval":60}`)
@@ -28,12 +28,14 @@
// bm.IsExist("astaxie")
// bm.Delete("astaxie")
//
-// more docs http://beego.me/docs/module/cache.md
+// more docs http://beego.vip/docs/module/cache.md
package cache
import (
- "fmt"
+ "context"
"time"
+
+ "github.com/beego/beego/v2/core/berror"
)
// Cache interface contains all behaviors for cache adapter.
@@ -47,23 +49,25 @@ import (
// c.Incr("counter") // now is 2
// count := c.Get("counter").(int)
type Cache interface {
- // get cached value by key.
- Get(key string) interface{}
+ // Get a cached value by key.
+ Get(ctx context.Context, key string) (interface{}, error)
// GetMulti is a batch version of Get.
- GetMulti(keys []string) []interface{}
- // set cached value with key and expire time.
- Put(key string, val interface{}, timeout time.Duration) error
- // delete cached value by key.
- Delete(key string) error
- // increase cached int value by key, as a counter.
- Incr(key string) error
- // decrease cached int value by key, as a counter.
- Decr(key string) error
- // check if cached value exists or not.
- IsExist(key string) bool
- // clear all cache.
- ClearAll() error
- // start gc routine based on config string settings.
+ GetMulti(ctx context.Context, keys []string) ([]interface{}, error)
+ // Put Set a cached value with key and expire time.
+ Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error
+ // Delete cached value by key.
+ // Should not return error if key not found
+ Delete(ctx context.Context, key string) error
+ // Incr Increment a cached int value by key, as a counter.
+ Incr(ctx context.Context, key string) error
+ // Decr Decrement a cached int value by key, as a counter.
+ Decr(ctx context.Context, key string) error
+ // IsExist Check if a cached value exists or not.
+ // if key is expired, return (false, nil)
+ IsExist(ctx context.Context, key string) (bool, error)
+ // ClearAll Clear all cache.
+ ClearAll(ctx context.Context) error
+ // StartAndGC Start gc routine based on config string settings.
StartAndGC(config string) error
}
@@ -77,7 +81,7 @@ var adapters = make(map[string]Instance)
// it panics.
func Register(name string, adapter Instance) {
if adapter == nil {
- panic("cache: Register adapter is nil")
+ panic(berror.Error(NilCacheAdapter, "cache: Register adapter is nil").Error())
}
if _, ok := adapters[name]; ok {
panic("cache: Register called twice for adapter " + name)
@@ -85,13 +89,13 @@ func Register(name string, adapter Instance) {
adapters[name] = adapter
}
-// NewCache Create a new cache driver by adapter name and config string.
-// config need to be correct JSON as string: {"interval":360}.
-// it will start gc automatically.
+// NewCache creates a new cache driver by adapter name and config string.
+// config: must be in JSON format such as {"interval":360}.
+// Starts gc automatically.
func NewCache(adapterName, config string) (adapter Cache, err error) {
instanceFunc, ok := adapters[adapterName]
if !ok {
- err = fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapterName)
+ err = berror.Errorf(UnknownAdapter, "cache: unknown adapter name %s (forgot to import?)", adapterName)
return
}
adapter = instanceFunc()
diff --git a/src/vendor/github.com/beego/beego/v2/client/cache/calc_utils.go b/src/vendor/github.com/beego/beego/v2/client/cache/calc_utils.go
new file mode 100644
index 000000000..f8b7f24ac
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/calc_utils.go
@@ -0,0 +1,95 @@
+package cache
+
+import (
+ "math"
+
+ "github.com/beego/beego/v2/core/berror"
+)
+
+var (
+ ErrIncrementOverflow = berror.Error(IncrementOverflow, "this incr invocation will overflow.")
+ ErrDecrementOverflow = berror.Error(DecrementOverflow, "this decr invocation will overflow.")
+ ErrNotIntegerType = berror.Error(NotIntegerType, "item val is not (u)int (u)int32 (u)int64")
+)
+
+const (
+ MinUint32 uint32 = 0
+ MinUint64 uint64 = 0
+)
+
+func incr(originVal interface{}) (interface{}, error) {
+ switch val := originVal.(type) {
+ case int:
+ tmp := val + 1
+ if val > 0 && tmp < 0 {
+ return nil, ErrIncrementOverflow
+ }
+ return tmp, nil
+ case int32:
+ if val == math.MaxInt32 {
+ return nil, ErrIncrementOverflow
+ }
+ return val + 1, nil
+ case int64:
+ if val == math.MaxInt64 {
+ return nil, ErrIncrementOverflow
+ }
+ return val + 1, nil
+ case uint:
+ tmp := val + 1
+ if tmp < val {
+ return nil, ErrIncrementOverflow
+ }
+ return tmp, nil
+ case uint32:
+ if val == math.MaxUint32 {
+ return nil, ErrIncrementOverflow
+ }
+ return val + 1, nil
+ case uint64:
+ if val == math.MaxUint64 {
+ return nil, ErrIncrementOverflow
+ }
+ return val + 1, nil
+ default:
+ return nil, ErrNotIntegerType
+ }
+}
+
+func decr(originVal interface{}) (interface{}, error) {
+ switch val := originVal.(type) {
+ case int:
+ tmp := val - 1
+ if val < 0 && tmp > 0 {
+ return nil, ErrDecrementOverflow
+ }
+ return tmp, nil
+ case int32:
+ if val == math.MinInt32 {
+ return nil, ErrDecrementOverflow
+ }
+ return val - 1, nil
+ case int64:
+ if val == math.MinInt64 {
+ return nil, ErrDecrementOverflow
+ }
+ return val - 1, nil
+ case uint:
+ if val == 0 {
+ return nil, ErrDecrementOverflow
+ }
+ return val - 1, nil
+ case uint32:
+ if val == MinUint32 {
+ return nil, ErrDecrementOverflow
+ }
+ return val - 1, nil
+ case uint64:
+ if val == MinUint64 {
+ return nil, ErrDecrementOverflow
+ }
+ return val - 1, nil
+ default:
+ return nil, ErrNotIntegerType
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/cache/conv.go b/src/vendor/github.com/beego/beego/v2/client/cache/conv.go
similarity index 90%
rename from src/vendor/github.com/beego/beego/cache/conv.go
rename to src/vendor/github.com/beego/beego/v2/client/cache/conv.go
index 878005864..158f7f413 100644
--- a/src/vendor/github.com/beego/beego/cache/conv.go
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/conv.go
@@ -19,7 +19,7 @@ import (
"strconv"
)
-// GetString convert interface to string.
+// GetString converts interface to string.
func GetString(v interface{}) string {
switch result := v.(type) {
case string:
@@ -34,7 +34,7 @@ func GetString(v interface{}) string {
return ""
}
-// GetInt convert interface to int.
+// GetInt converts interface to int.
func GetInt(v interface{}) int {
switch result := v.(type) {
case int:
@@ -52,7 +52,7 @@ func GetInt(v interface{}) int {
return 0
}
-// GetInt64 convert interface to int64.
+// GetInt64 converts interface to int64.
func GetInt64(v interface{}) int64 {
switch result := v.(type) {
case int:
@@ -71,7 +71,7 @@ func GetInt64(v interface{}) int64 {
return 0
}
-// GetFloat64 convert interface to float64.
+// GetFloat64 converts interface to float64.
func GetFloat64(v interface{}) float64 {
switch result := v.(type) {
case float64:
@@ -85,7 +85,7 @@ func GetFloat64(v interface{}) float64 {
return 0
}
-// GetBool convert interface to bool.
+// GetBool converts interface to bool.
func GetBool(v interface{}) bool {
switch result := v.(type) {
case bool:
diff --git a/src/vendor/github.com/beego/beego/v2/client/cache/error_code.go b/src/vendor/github.com/beego/beego/v2/client/cache/error_code.go
new file mode 100644
index 000000000..5611f065f
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/error_code.go
@@ -0,0 +1,176 @@
+// Copyright 2021 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cache
+
+import (
+ "github.com/beego/beego/v2/core/berror"
+)
+
+var NilCacheAdapter = berror.DefineCode(4002001, moduleName, "NilCacheAdapter", `
+It means that you register cache adapter by pass nil.
+A cache adapter is an instance of Cache interface.
+`)
+
+var DuplicateAdapter = berror.DefineCode(4002002, moduleName, "DuplicateAdapter", `
+You register two adapter with same name. In beego cache module, one name one adapter.
+Once you got this error, please check the error stack, search adapter
+`)
+
+var UnknownAdapter = berror.DefineCode(4002003, moduleName, "UnknownAdapter", `
+Unknown adapter, do you forget to register the adapter?
+You must register adapter before use it. For example, if you want to use redis implementation,
+you must import the cache/redis package.
+`)
+
+var IncrementOverflow = berror.DefineCode(4002004, moduleName, "IncrementOverflow", `
+The increment operation will overflow.
+`)
+
+var DecrementOverflow = berror.DefineCode(4002005, moduleName, "DecrementOverflow", `
+The decrement operation will overflow.
+`)
+
+var NotIntegerType = berror.DefineCode(4002006, moduleName, "NotIntegerType", `
+The type of value is not (u)int (u)int32 (u)int64.
+When you want to call Incr or Decr function of Cache API, you must confirm that the value's type is one of (u)int (u)int32 (u)int64.
+`)
+
+var InvalidFileCacheDirectoryLevelCfg = berror.DefineCode(4002007, moduleName, "InvalidFileCacheDirectoryLevelCfg", `
+You pass invalid DirectoryLevel parameter when you try to StartAndGC file cache instance.
+This parameter must be a integer, and please check your input.
+`)
+
+var InvalidFileCacheEmbedExpiryCfg = berror.DefineCode(4002008, moduleName, "InvalidFileCacheEmbedExpiryCfg", `
+You pass invalid EmbedExpiry parameter when you try to StartAndGC file cache instance.
+This parameter must be a integer, and please check your input.
+`)
+
+var CreateFileCacheDirFailed = berror.DefineCode(4002009, moduleName, "CreateFileCacheDirFailed", `
+Beego failed to create file cache directory. There are two cases:
+1. You pass invalid CachePath parameter. Please check your input.
+2. Beego doesn't have the permission to create this directory. Please check your file mode.
+`)
+
+var InvalidFileCachePath = berror.DefineCode(4002010, moduleName, "InvalidFilePath", `
+The file path of FileCache is invalid. Please correct the config.
+`)
+
+var ReadFileCacheContentFailed = berror.DefineCode(4002011, moduleName, "ReadFileCacheContentFailed", `
+Usually you won't got this error. It means that Beego cannot read the data from the file.
+You need to check whether the file exist. Sometimes it may be deleted by other processes.
+If the file exists, please check the permission that Beego is able to read data from the file.
+`)
+
+var InvalidGobEncodedData = berror.DefineCode(4002012, moduleName, "InvalidEncodedData", `
+The data is invalid. When you try to decode the invalid data, you got this error.
+Please confirm that the data is encoded by GOB correctly.
+`)
+
+var GobEncodeDataFailed = berror.DefineCode(4002013, moduleName, "GobEncodeDataFailed", `
+Beego could not encode the data to GOB byte array. In general, the data type is invalid.
+For example, GOB doesn't support function type.
+Basic types, string, structure, structure pointer are supported.
+`)
+
+var KeyExpired = berror.DefineCode(4002014, moduleName, "KeyExpired", `
+Cache key is expired.
+You should notice that, a key is expired and then it may be deleted by GC goroutine.
+So when you query a key which may be expired, you may got this code, or KeyNotExist.
+`)
+
+var KeyNotExist = berror.DefineCode(4002015, moduleName, "KeyNotExist", `
+Key not found.
+`)
+
+var MultiGetFailed = berror.DefineCode(4002016, moduleName, "MultiGetFailed", `
+Get multiple keys failed. Please check the detail msg to find out the root cause.
+`)
+
+var InvalidMemoryCacheCfg = berror.DefineCode(4002017, moduleName, "InvalidMemoryCacheCfg", `
+The config is invalid. Please check your input. It must be a json string.
+`)
+
+var InvalidMemCacheCfg = berror.DefineCode(4002018, moduleName, "InvalidMemCacheCfg", `
+The config is invalid. Please check your input, it must be json string and contains "conn" field.
+`)
+
+var InvalidMemCacheValue = berror.DefineCode(4002019, moduleName, "InvalidMemCacheValue", `
+The value must be string or byte[], please check your input.
+`)
+
+var InvalidRedisCacheCfg = berror.DefineCode(4002020, moduleName, "InvalidRedisCacheCfg", `
+The config must be json string, and has "conn" field.
+`)
+
+var InvalidSsdbCacheCfg = berror.DefineCode(4002021, moduleName, "InvalidSsdbCacheCfg", `
+The config must be json string, and has "conn" field. The value of "conn" field should be "host:port".
+"port" must be a valid integer.
+`)
+
+var InvalidSsdbCacheValue = berror.DefineCode(4002022, moduleName, "InvalidSsdbCacheValue", `
+SSDB cache only accept string value. Please check your input.
+`)
+
+var DeleteFileCacheItemFailed = berror.DefineCode(5002001, moduleName, "DeleteFileCacheItemFailed", `
+Beego try to delete file cache item failed.
+Please check whether Beego generated file correctly.
+And then confirm whether this file is already deleted by other processes or other people.
+`)
+
+var MemCacheCurdFailed = berror.DefineCode(5002002, moduleName, "MemCacheError", `
+When you want to get, put, delete key-value from remote memcache servers, you may get error:
+1. You pass invalid servers address, so Beego could not connect to remote server;
+2. The servers address is correct, but there is some net issue. Typically there is some firewalls between application and memcache server;
+3. Key is invalid. The key's length should be less than 250 and must not contains special characters;
+4. The response from memcache server is invalid;
+`)
+
+var RedisCacheCurdFailed = berror.DefineCode(5002003, moduleName, "RedisCacheCurdFailed", `
+When Beego uses client to send request to redis server, it failed.
+1. The server addresses is invalid;
+2. Network issue, firewall issue or network is unstable;
+3. Client failed to manage connection. In extreme cases, Beego's redis client didn't maintain connections correctly, for example, Beego try to send request via closed connection;
+4. The request are huge and redis server spent too much time to process it, and client is timeout;
+
+In general, if you always got this error whatever you do, in most cases, it was caused by network issue.
+You could check your network state, and confirm that firewall rules are correct.
+`)
+
+var InvalidConnection = berror.DefineCode(5002004, moduleName, "InvalidConnection", `
+The connection is invalid. Please check your connection info, network, firewall.
+You could simply uses ping, telnet or write some simple tests to test network.
+`)
+
+var DialFailed = berror.DefineCode(5002005, moduleName, "DialFailed", `
+When Beego try to dial to remote servers, it failed. Please check your connection info and network state, server state.
+`)
+
+var SsdbCacheCurdFailed = berror.DefineCode(5002006, moduleName, "SsdbCacheCurdFailed", `
+When you try to use SSDB cache, it failed. There are many cases:
+1. servers unavailable;
+2. network issue, including network unstable, firewall;
+3. connection issue;
+4. request are huge and servers spent too much time to process it, got timeout;
+`)
+
+var SsdbBadResponse = berror.DefineCode(5002007, moduleName, "SsdbBadResponse", `
+The reponse from SSDB server is invalid.
+Usually it indicates something wrong on server side.
+`)
+
+var (
+ ErrKeyExpired = berror.Error(KeyExpired, "the key is expired")
+ ErrKeyNotExist = berror.Error(KeyNotExist, "the key isn't exist")
+)
diff --git a/src/vendor/github.com/beego/beego/v2/client/cache/file.go b/src/vendor/github.com/beego/beego/v2/client/cache/file.go
new file mode 100644
index 000000000..ae2bc7cf6
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/file.go
@@ -0,0 +1,338 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cache
+
+import (
+ "bytes"
+ "context"
+ "crypto/md5"
+ "encoding/gob"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/beego/beego/v2/core/berror"
+)
+
+// FileCacheItem is basic unit of file cache adapter which
+// contains data and expire time.
+type FileCacheItem struct {
+ Data interface{}
+ Lastaccess time.Time
+ Expired time.Time
+}
+
+// FileCache Config
+var (
+ FileCachePath = "cache" // cache directory
+ FileCacheFileSuffix = ".bin" // cache file suffix
+ FileCacheDirectoryLevel = 2 // cache file deep level if auto generated cache files.
+ FileCacheEmbedExpiry time.Duration // cache expire time, default is no expire forever.
+)
+
+// FileCache is cache adapter for file storage.
+type FileCache struct {
+ CachePath string
+ FileSuffix string
+ DirectoryLevel int
+ EmbedExpiry int
+}
+
+// NewFileCache creates a new file cache with no config.
+// The level and expiry need to be set in the method StartAndGC as config string.
+func NewFileCache() Cache {
+ // return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
+ return &FileCache{}
+}
+
+// StartAndGC starts gc for file cache.
+// config must be in the format {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}
+func (fc *FileCache) StartAndGC(config string) error {
+ cfg := make(map[string]string)
+ err := json.Unmarshal([]byte(config), &cfg)
+ if err != nil {
+ return err
+ }
+
+ const cpKey = "CachePath"
+ const fsKey = "FileSuffix"
+ const dlKey = "DirectoryLevel"
+ const eeKey = "EmbedExpiry"
+
+ if _, ok := cfg[cpKey]; !ok {
+ cfg[cpKey] = FileCachePath
+ }
+
+ if _, ok := cfg[fsKey]; !ok {
+ cfg[fsKey] = FileCacheFileSuffix
+ }
+
+ if _, ok := cfg[dlKey]; !ok {
+ cfg[dlKey] = strconv.Itoa(FileCacheDirectoryLevel)
+ }
+
+ if _, ok := cfg[eeKey]; !ok {
+ cfg[eeKey] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10)
+ }
+ fc.CachePath = cfg[cpKey]
+ fc.FileSuffix = cfg[fsKey]
+ fc.DirectoryLevel, err = strconv.Atoi(cfg[dlKey])
+ if err != nil {
+ return berror.Wrapf(err, InvalidFileCacheDirectoryLevelCfg,
+ "invalid directory level config, please check your input, it must be integer: %s", cfg[dlKey])
+ }
+ fc.EmbedExpiry, err = strconv.Atoi(cfg[eeKey])
+ if err != nil {
+ return berror.Wrapf(err, InvalidFileCacheEmbedExpiryCfg,
+ "invalid embed expiry config, please check your input, it must be integer: %s", cfg[eeKey])
+ }
+ return fc.Init()
+}
+
+// Init makes new a dir for file cache if it does not already exist
+func (fc *FileCache) Init() error {
+ ok, err := exists(fc.CachePath)
+ if err != nil || ok {
+ return err
+ }
+ err = os.MkdirAll(fc.CachePath, os.ModePerm)
+ if err != nil {
+ return berror.Wrapf(err, CreateFileCacheDirFailed,
+ "could not create directory, please check the config [%s] and file mode.", fc.CachePath)
+ }
+ return nil
+}
+
+// getCachedFilename returns an md5 encoded file name.
+func (fc *FileCache) getCacheFileName(key string) (string, error) {
+ m := md5.New()
+ _, _ = io.WriteString(m, key)
+ keyMd5 := hex.EncodeToString(m.Sum(nil))
+ cachePath := fc.CachePath
+ switch fc.DirectoryLevel {
+ case 2:
+ cachePath = filepath.Join(cachePath, keyMd5[0:2], keyMd5[2:4])
+ case 1:
+ cachePath = filepath.Join(cachePath, keyMd5[0:2])
+ }
+ ok, err := exists(cachePath)
+ if err != nil {
+ return "", err
+ }
+ if !ok {
+ err = os.MkdirAll(cachePath, os.ModePerm)
+ if err != nil {
+ return "", berror.Wrapf(err, CreateFileCacheDirFailed,
+ "could not create the directory: %s", cachePath)
+ }
+ }
+
+ return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, fc.FileSuffix)), nil
+}
+
+// Get value from file cache.
+// if nonexistent or expired return an empty string.
+func (fc *FileCache) Get(ctx context.Context, key string) (interface{}, error) {
+ fn, err := fc.getCacheFileName(key)
+ if err != nil {
+ return nil, err
+ }
+ fileData, err := FileGetContents(fn)
+ if err != nil {
+ return nil, err
+ }
+
+ var to FileCacheItem
+ err = GobDecode(fileData, &to)
+ if err != nil {
+ return nil, err
+ }
+
+ if to.Expired.Before(time.Now()) {
+ return nil, ErrKeyExpired
+ }
+ return to.Data, nil
+}
+
+// GetMulti gets values from file cache.
+// if nonexistent or expired return an empty string.
+func (fc *FileCache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
+ rc := make([]interface{}, len(keys))
+ keysErr := make([]string, 0)
+
+ for i, ki := range keys {
+ val, err := fc.Get(context.Background(), ki)
+ if err != nil {
+ keysErr = append(keysErr, fmt.Sprintf("key [%s] error: %s", ki, err.Error()))
+ continue
+ }
+ rc[i] = val
+ }
+
+ if len(keysErr) == 0 {
+ return rc, nil
+ }
+ return rc, berror.Error(MultiGetFailed, strings.Join(keysErr, "; "))
+}
+
+// Put value into file cache.
+// timeout: how long this file should be kept in ms
+// if timeout equals fc.EmbedExpiry(default is 0), cache this item forever.
+func (fc *FileCache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
+ gob.Register(val)
+
+ item := FileCacheItem{Data: val}
+ if timeout == time.Duration(fc.EmbedExpiry) {
+ item.Expired = time.Now().Add((86400 * 365 * 10) * time.Second) // ten years
+ } else {
+ item.Expired = time.Now().Add(timeout)
+ }
+ item.Lastaccess = time.Now()
+ data, err := GobEncode(item)
+ if err != nil {
+ return err
+ }
+
+ fn, err := fc.getCacheFileName(key)
+ if err != nil {
+ return err
+ }
+ return FilePutContents(fn, data)
+}
+
+// Delete file cache value.
+func (fc *FileCache) Delete(ctx context.Context, key string) error {
+ filename, err := fc.getCacheFileName(key)
+ if err != nil {
+ return err
+ }
+ if ok, _ := exists(filename); ok {
+ err = os.Remove(filename)
+ if err != nil {
+ return berror.Wrapf(err, DeleteFileCacheItemFailed,
+ "can not delete this file cache key-value, key is %s and file name is %s", key, filename)
+ }
+ }
+ return nil
+}
+
+// Incr increases cached int value.
+// fc value is saved forever unless deleted.
+func (fc *FileCache) Incr(ctx context.Context, key string) error {
+ data, err := fc.Get(context.Background(), key)
+ if err != nil {
+ return err
+ }
+
+ val, err := incr(data)
+ if err != nil {
+ return err
+ }
+
+ return fc.Put(context.Background(), key, val, time.Duration(fc.EmbedExpiry))
+}
+
+// Decr decreases cached int value.
+func (fc *FileCache) Decr(ctx context.Context, key string) error {
+ data, err := fc.Get(context.Background(), key)
+ if err != nil {
+ return err
+ }
+
+ val, err := decr(data)
+ if err != nil {
+ return err
+ }
+
+ return fc.Put(context.Background(), key, val, time.Duration(fc.EmbedExpiry))
+}
+
+// IsExist checks if value exists.
+func (fc *FileCache) IsExist(ctx context.Context, key string) (bool, error) {
+ fn, err := fc.getCacheFileName(key)
+ if err != nil {
+ return false, err
+ }
+ return exists(fn)
+}
+
+// ClearAll cleans cached files (not implemented)
+func (fc *FileCache) ClearAll(context.Context) error {
+ return nil
+}
+
+// Check if a file exists
+func exists(path string) (bool, error) {
+ _, err := os.Stat(path)
+ if err == nil {
+ return true, nil
+ }
+ if os.IsNotExist(err) {
+ return false, nil
+ }
+ return false, berror.Wrapf(err, InvalidFileCachePath, "file cache path is invalid: %s", path)
+}
+
+// FileGetContents Reads bytes from a file.
+// if non-existent, create this file.
+func FileGetContents(filename string) ([]byte, error) {
+ data, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, berror.Wrapf(err, ReadFileCacheContentFailed,
+ "could not read the data from the file: %s, "+
+ "please confirm that file exist and Beego has the permission to read the content.", filename)
+ }
+ return data, nil
+}
+
+// FilePutContents puts bytes into a file.
+// if non-existent, create this file.
+func FilePutContents(filename string, content []byte) error {
+ return ioutil.WriteFile(filename, content, os.ModePerm)
+}
+
+// GobEncode Gob encodes a file cache item.
+func GobEncode(data interface{}) ([]byte, error) {
+ buf := bytes.NewBuffer(nil)
+ enc := gob.NewEncoder(buf)
+ err := enc.Encode(data)
+ if err != nil {
+ return nil, berror.Wrap(err, GobEncodeDataFailed, "could not encode this data")
+ }
+ return buf.Bytes(), nil
+}
+
+// GobDecode Gob decodes a file cache item.
+func GobDecode(data []byte, to *FileCacheItem) error {
+ buf := bytes.NewBuffer(data)
+ dec := gob.NewDecoder(buf)
+ err := dec.Decode(&to)
+ if err != nil {
+ return berror.Wrap(err, InvalidGobEncodedData,
+ "could not decode this data to FileCacheItem. Make sure that the data is encoded by GOB.")
+ }
+ return nil
+}
+
+func init() {
+ Register("file", NewFileCache)
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/cache/memory.go b/src/vendor/github.com/beego/beego/v2/client/cache/memory.go
new file mode 100644
index 000000000..c1d1a2e50
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/memory.go
@@ -0,0 +1,235 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cache
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/beego/beego/v2/core/berror"
+)
+
+// DefaultEvery sets a timer for how often to recycle the expired cache items in memory (in seconds)
+var DefaultEvery = 60 // 1 minute
+
+// MemoryItem stores memory cache item.
+type MemoryItem struct {
+ val interface{}
+ createdTime time.Time
+ lifespan time.Duration
+}
+
+func (mi *MemoryItem) isExpire() bool {
+ // 0 means forever
+ if mi.lifespan == 0 {
+ return false
+ }
+ return time.Since(mi.createdTime) > mi.lifespan
+}
+
+// MemoryCache is a memory cache adapter.
+// Contains a RW locker for safe map storage.
+type MemoryCache struct {
+ sync.RWMutex
+ dur time.Duration
+ items map[string]*MemoryItem
+ Every int // run an expiration check Every clock time
+}
+
+// NewMemoryCache returns a new MemoryCache.
+func NewMemoryCache() Cache {
+ cache := MemoryCache{items: make(map[string]*MemoryItem)}
+ return &cache
+}
+
+// Get returns cache from memory.
+// If non-existent or expired, return nil.
+func (bc *MemoryCache) Get(ctx context.Context, key string) (interface{}, error) {
+ bc.RLock()
+ defer bc.RUnlock()
+ if itm, ok :=
+ bc.items[key]; ok {
+ if itm.isExpire() {
+ return nil, ErrKeyExpired
+ }
+ return itm.val, nil
+ }
+ return nil, ErrKeyNotExist
+}
+
+// GetMulti gets caches from memory.
+// If non-existent or expired, return nil.
+func (bc *MemoryCache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
+ rc := make([]interface{}, len(keys))
+ keysErr := make([]string, 0)
+
+ for i, ki := range keys {
+ val, err := bc.Get(context.Background(), ki)
+ if err != nil {
+ keysErr = append(keysErr, fmt.Sprintf("key [%s] error: %s", ki, err.Error()))
+ continue
+ }
+ rc[i] = val
+ }
+
+ if len(keysErr) == 0 {
+ return rc, nil
+ }
+ return rc, berror.Error(MultiGetFailed, strings.Join(keysErr, "; "))
+}
+
+// Put puts cache into memory.
+// If lifespan is 0, it will never overwrite this value unless restarted
+func (bc *MemoryCache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
+ bc.Lock()
+ defer bc.Unlock()
+ bc.items[key] = &MemoryItem{
+ val: val,
+ createdTime: time.Now(),
+ lifespan: timeout,
+ }
+ return nil
+}
+
+// Delete cache in memory.
+// If the key is not found, it will not return error
+func (bc *MemoryCache) Delete(ctx context.Context, key string) error {
+ bc.Lock()
+ defer bc.Unlock()
+ delete(bc.items, key)
+ return nil
+}
+
+// Incr increases cache counter in memory.
+// Supports int,int32,int64,uint,uint32,uint64.
+func (bc *MemoryCache) Incr(ctx context.Context, key string) error {
+ bc.Lock()
+ defer bc.Unlock()
+ itm, ok := bc.items[key]
+ if !ok {
+ return ErrKeyNotExist
+ }
+
+ val, err := incr(itm.val)
+ if err != nil {
+ return err
+ }
+ itm.val = val
+ return nil
+}
+
+// Decr decreases counter in memory.
+func (bc *MemoryCache) Decr(ctx context.Context, key string) error {
+ bc.Lock()
+ defer bc.Unlock()
+ itm, ok := bc.items[key]
+ if !ok {
+ return ErrKeyNotExist
+ }
+
+ val, err := decr(itm.val)
+ if err != nil {
+ return err
+ }
+ itm.val = val
+ return nil
+}
+
+// IsExist checks if cache exists in memory.
+func (bc *MemoryCache) IsExist(ctx context.Context, key string) (bool, error) {
+ bc.RLock()
+ defer bc.RUnlock()
+ if v, ok := bc.items[key]; ok {
+ return !v.isExpire(), nil
+ }
+ return false, nil
+}
+
+// ClearAll deletes all cache in memory.
+func (bc *MemoryCache) ClearAll(context.Context) error {
+ bc.Lock()
+ defer bc.Unlock()
+ bc.items = make(map[string]*MemoryItem)
+ return nil
+}
+
+// StartAndGC starts memory cache. Checks expiration in every clock time.
+func (bc *MemoryCache) StartAndGC(config string) error {
+ var cf map[string]int
+ if err := json.Unmarshal([]byte(config), &cf); err != nil {
+ return berror.Wrapf(err, InvalidMemoryCacheCfg, "invalid config, please check your input: %s", config)
+ }
+ if _, ok := cf["interval"]; !ok {
+ cf = make(map[string]int)
+ cf["interval"] = DefaultEvery
+ }
+ dur := time.Duration(cf["interval"]) * time.Second
+ bc.Every = cf["interval"]
+ bc.dur = dur
+ go bc.vacuum()
+ return nil
+}
+
+// check expiration.
+func (bc *MemoryCache) vacuum() {
+ bc.RLock()
+ every := bc.Every
+ bc.RUnlock()
+
+ if every < 1 {
+ return
+ }
+ for {
+ <-time.After(bc.dur)
+ bc.RLock()
+ if bc.items == nil {
+ bc.RUnlock()
+ return
+ }
+ bc.RUnlock()
+ if keys := bc.expiredKeys(); len(keys) != 0 {
+ bc.clearItems(keys)
+ }
+ }
+}
+
+// expiredKeys returns keys list which are expired.
+func (bc *MemoryCache) expiredKeys() (keys []string) {
+ bc.RLock()
+ defer bc.RUnlock()
+ for key, itm := range bc.items {
+ if itm.isExpire() {
+ keys = append(keys, key)
+ }
+ }
+ return
+}
+
+// ClearItems removes all items who's key is in keys
+func (bc *MemoryCache) clearItems(keys []string) {
+ bc.Lock()
+ defer bc.Unlock()
+ for _, key := range keys {
+ delete(bc.items, key)
+ }
+}
+
+func init() {
+ Register("memory", NewMemoryCache)
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/cache/module.go b/src/vendor/github.com/beego/beego/v2/client/cache/module.go
new file mode 100644
index 000000000..5a4e499ea
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/module.go
@@ -0,0 +1,17 @@
+// Copyright 2021 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cache
+
+const moduleName = "cache"
diff --git a/src/vendor/github.com/beego/beego/v2/client/cache/random_expired_cache.go b/src/vendor/github.com/beego/beego/v2/client/cache/random_expired_cache.go
new file mode 100644
index 000000000..262001124
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/random_expired_cache.go
@@ -0,0 +1,75 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cache
+
+import (
+ "context"
+ "math/rand"
+ "sync/atomic"
+ "time"
+)
+
+// RandomExpireCacheOption implement genreate random time offset expired option
+type RandomExpireCacheOption func(*RandomExpireCache)
+
+// WithOffsetFunc returns a RandomExpireCacheOption that configures the offset function
+func WithOffsetFunc(fn func() time.Duration) RandomExpireCacheOption {
+ return func(cache *RandomExpireCache) {
+ cache.offset = fn
+ }
+}
+
+// RandomExpireCache prevent cache batch invalidation
+// Cache random time offset expired
+type RandomExpireCache struct {
+ Cache
+ offset func() time.Duration
+}
+
+// Put random time offset expired
+func (rec *RandomExpireCache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
+ timeout += rec.offset()
+ return rec.Cache.Put(ctx, key, val, timeout)
+}
+
+// NewRandomExpireCache return random expire cache struct
+func NewRandomExpireCache(adapter Cache, opts ...RandomExpireCacheOption) Cache {
+ rec := RandomExpireCache{
+ Cache: adapter,
+ offset: defaultExpiredFunc(),
+ }
+ for _, fn := range opts {
+ fn(&rec)
+ }
+ return &rec
+}
+
+// defaultExpiredFunc return a func that used to generate random time offset (range: [3s,8s)) expired
+func defaultExpiredFunc() func() time.Duration {
+ const size = 5
+ var randTimes [size]time.Duration
+ for i := range randTimes {
+ randTimes[i] = time.Duration(i+3) * time.Second
+ }
+ // shuffle values
+ for i := range randTimes {
+ n := rand.Intn(size)
+ randTimes[i], randTimes[n] = randTimes[n], randTimes[i]
+ }
+ var i uint64
+ return func() time.Duration {
+ return randTimes[atomic.AddUint64(&i, 1)%size]
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/cache/redis/redis.go b/src/vendor/github.com/beego/beego/v2/client/cache/redis/redis.go
similarity index 58%
rename from src/vendor/github.com/beego/beego/cache/redis/redis.go
rename to src/vendor/github.com/beego/beego/v2/client/cache/redis/redis.go
index 06115aefd..9462bcd8e 100644
--- a/src/vendor/github.com/beego/beego/cache/redis/redis.go
+++ b/src/vendor/github.com/beego/beego/v2/client/cache/redis/redis.go
@@ -20,33 +20,31 @@
//
// Usage:
// import(
-// _ "github.com/beego/beego/cache/redis"
-// "github.com/beego/beego/cache"
+// _ "github.com/beego/beego/v2/client/cache/redis"
+// "github.com/beego/beego/v2/client/cache"
// )
//
// bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`)
//
-// more docs http://beego.me/docs/module/cache.md
+// more docs http://beego.vip/docs/module/cache.md
package redis
import (
+ "context"
"encoding/json"
- "errors"
"fmt"
"strconv"
+ "strings"
"time"
"github.com/gomodule/redigo/redis"
- "strings"
-
- "github.com/beego/beego/cache"
+ "github.com/beego/beego/v2/client/cache"
+ "github.com/beego/beego/v2/core/berror"
)
-var (
- // DefaultKey the collection name of redis for cache adapter.
- DefaultKey = "beecacheRedis"
-)
+// DefaultKey defines the collection name of redis for the cache adapter.
+var DefaultKey = "beecacheRedis"
// Cache is Redis cache adapter.
type Cache struct {
@@ -57,25 +55,30 @@ type Cache struct {
password string
maxIdle int
- //the timeout to a value less than the redis server's timeout.
+ // Timeout value (less than the redis server's timeout value)
timeout time.Duration
}
-// NewRedisCache create new redis cache with default collection name.
+// NewRedisCache creates a new redis cache with default collection name.
func NewRedisCache() cache.Cache {
return &Cache{key: DefaultKey}
}
-// actually do the redis cmds, args[0] must be the key name.
-func (rc *Cache) do(commandName string, args ...interface{}) (reply interface{}, err error) {
- if len(args) < 1 {
- return nil, errors.New("missing required arguments")
- }
+// Execute the redis commands. args[0] must be the key name
+func (rc *Cache) do(commandName string, args ...interface{}) (interface{}, error) {
args[0] = rc.associate(args[0])
c := rc.p.Get()
- defer c.Close()
+ defer func() {
+ _ = c.Close()
+ }()
- return c.Do(commandName, args...)
+ reply, err := c.Do(commandName, args...)
+ if err != nil {
+ return nil, berror.Wrapf(err, cache.RedisCacheCurdFailed,
+ "could not execute this command: %s", commandName)
+ }
+
+ return reply, nil
}
// associate with config key.
@@ -84,69 +87,71 @@ func (rc *Cache) associate(originKey interface{}) string {
}
// Get cache from redis.
-func (rc *Cache) Get(key string) interface{} {
+func (rc *Cache) Get(ctx context.Context, key string) (interface{}, error) {
if v, err := rc.do("GET", key); err == nil {
- return v
+ return v, nil
+ } else {
+ return nil, err
}
- return nil
}
-// GetMulti get cache from redis.
-func (rc *Cache) GetMulti(keys []string) []interface{} {
+// GetMulti gets cache from redis.
+func (rc *Cache) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
c := rc.p.Get()
- defer c.Close()
+ defer func() {
+ _ = c.Close()
+ }()
var args []interface{}
for _, key := range keys {
args = append(args, rc.associate(key))
}
- values, err := redis.Values(c.Do("MGET", args...))
- if err != nil {
- return nil
- }
- return values
+ return redis.Values(c.Do("MGET", args...))
}
-// Put put cache to redis.
-func (rc *Cache) Put(key string, val interface{}, timeout time.Duration) error {
+// Put puts cache into redis.
+func (rc *Cache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
_, err := rc.do("SETEX", key, int64(timeout/time.Second), val)
return err
}
-// Delete delete cache in redis.
-func (rc *Cache) Delete(key string) error {
+// Delete deletes a key's cache in redis.
+func (rc *Cache) Delete(ctx context.Context, key string) error {
_, err := rc.do("DEL", key)
return err
}
-// IsExist check cache's existence in redis.
-func (rc *Cache) IsExist(key string) bool {
+// IsExist checks cache's existence in redis.
+func (rc *Cache) IsExist(ctx context.Context, key string) (bool, error) {
v, err := redis.Bool(rc.do("EXISTS", key))
if err != nil {
- return false
+ return false, err
}
- return v
+ return v, nil
}
-// Incr increase counter in redis.
-func (rc *Cache) Incr(key string) error {
+// Incr increases a key's counter in redis.
+func (rc *Cache) Incr(ctx context.Context, key string) error {
_, err := redis.Bool(rc.do("INCRBY", key, 1))
return err
}
-// Decr decrease counter in redis.
-func (rc *Cache) Decr(key string) error {
+// Decr decreases a key's counter in redis.
+func (rc *Cache) Decr(ctx context.Context, key string) error {
_, err := redis.Bool(rc.do("INCRBY", key, -1))
return err
}
-// ClearAll clean all cache in redis. delete this redis collection.
-func (rc *Cache) ClearAll() error {
+// ClearAll deletes all cache in the redis collection
+// Be careful about this method, because it scans all keys and the delete them one by one
+func (rc *Cache) ClearAll(context.Context) error {
cachedKeys, err := rc.Scan(rc.key + ":*")
if err != nil {
return err
}
c := rc.p.Get()
- defer c.Close()
+ defer func() {
+ _ = c.Close()
+ }()
for _, str := range cachedKeys {
if _, err = c.Do("DEL", str); err != nil {
return err
@@ -155,10 +160,12 @@ func (rc *Cache) ClearAll() error {
return err
}
-// Scan scan all keys matching the pattern. a better choice than `keys`
+// Scan scans all keys matching a given pattern.
func (rc *Cache) Scan(pattern string) (keys []string, err error) {
c := rc.p.Get()
- defer c.Close()
+ defer func() {
+ _ = c.Close()
+ }()
var (
cursor uint64 = 0 // start
result []interface{}
@@ -184,19 +191,21 @@ func (rc *Cache) Scan(pattern string) (keys []string, err error) {
}
}
-// StartAndGC start redis cache adapter.
-// config is like {"key":"collection key","conn":"connection info","dbNum":"0"}
-// the cache item in redis are stored forever,
-// so no gc operation.
+// StartAndGC starts the redis cache adapter.
+// config: must be in this format {"key":"collection key","conn":"connection info","dbNum":"0"}
+// Cached items in redis are stored forever, no garbage collection happens
func (rc *Cache) StartAndGC(config string) error {
var cf map[string]string
- json.Unmarshal([]byte(config), &cf)
+ err := json.Unmarshal([]byte(config), &cf)
+ if err != nil {
+ return berror.Wrapf(err, cache.InvalidRedisCacheCfg, "could not unmarshal the config: %s", config)
+ }
if _, ok := cf["key"]; !ok {
cf["key"] = DefaultKey
}
if _, ok := cf["conn"]; !ok {
- return errors.New("config has no conn key")
+ return berror.Wrapf(err, cache.InvalidRedisCacheCfg, "config missing conn field: %s", config)
}
// Format redis://@:
@@ -233,9 +242,16 @@ func (rc *Cache) StartAndGC(config string) error {
rc.connectInit()
c := rc.p.Get()
- defer c.Close()
+ defer func() {
+ _ = c.Close()
+ }()
- return c.Err()
+ // test connection
+ if err = c.Err(); err != nil {
+ return berror.Wrapf(err, cache.InvalidConnection,
+ "can not connect to remote redis server, please check the connection info and network state: %s", config)
+ }
+ return nil
}
// connect to redis.
@@ -243,19 +259,20 @@ func (rc *Cache) connectInit() {
dialFunc := func() (c redis.Conn, err error) {
c, err = redis.Dial("tcp", rc.conninfo)
if err != nil {
- return nil, err
+ return nil, berror.Wrapf(err, cache.DialFailed,
+ "could not dial to remote server: %s ", rc.conninfo)
}
if rc.password != "" {
- if _, err := c.Do("AUTH", rc.password); err != nil {
- c.Close()
+ if _, err = c.Do("AUTH", rc.password); err != nil {
+ _ = c.Close()
return nil, err
}
}
_, selecterr := c.Do("SELECT", rc.dbNum)
if selecterr != nil {
- c.Close()
+ _ = c.Close()
return nil, selecterr
}
return
diff --git a/src/vendor/github.com/beego/beego/orm/README.md b/src/vendor/github.com/beego/beego/v2/client/orm/README.md
similarity index 91%
rename from src/vendor/github.com/beego/beego/orm/README.md
rename to src/vendor/github.com/beego/beego/v2/client/orm/README.md
index d3ef8362a..15fd1b11c 100644
--- a/src/vendor/github.com/beego/beego/orm/README.md
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/README.md
@@ -1,6 +1,6 @@
# beego orm
-[](https://drone.io/github.com/beego/beego/latest)
+[](https://drone.io/github.com/beego/beego/v2/latest)
A powerful orm framework for go.
@@ -27,7 +27,7 @@ more features please read the docs
**Install:**
- go get github.com/beego/beego/orm
+ go get github.com/beego/beego/v2/client/orm
## Changelog
@@ -45,7 +45,7 @@ package main
import (
"fmt"
- "github.com/beego/beego/orm"
+ "github.com/beego/beego/v2/client/orm"
_ "github.com/go-sql-driver/mysql" // import your used driver
)
@@ -155,5 +155,5 @@ note: not recommend use this in product env.
more details and examples in docs and test
-[documents](http://beego.me/docs/mvc/model/overview.md)
+[documents](http://beego.vip/docs/mvc/model/overview.md)
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/clauses/const.go b/src/vendor/github.com/beego/beego/v2/client/orm/clauses/const.go
new file mode 100644
index 000000000..38a6d5569
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/clauses/const.go
@@ -0,0 +1,6 @@
+package clauses
+
+const (
+ ExprSep = "__"
+ ExprDot = "."
+)
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/clauses/order_clause/order.go b/src/vendor/github.com/beego/beego/v2/client/orm/clauses/order_clause/order.go
new file mode 100644
index 000000000..bdb2d1ca0
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/clauses/order_clause/order.go
@@ -0,0 +1,104 @@
+package order_clause
+
+import (
+ "strings"
+
+ "github.com/beego/beego/v2/client/orm/clauses"
+)
+
+type Sort int8
+
+const (
+ None Sort = 0
+ Ascending Sort = 1
+ Descending Sort = 2
+)
+
+type Option func(order *Order)
+
+type Order struct {
+ column string
+ sort Sort
+ isRaw bool
+}
+
+func Clause(options ...Option) *Order {
+ o := &Order{}
+ for _, option := range options {
+ option(o)
+ }
+
+ return o
+}
+
+func (o *Order) GetColumn() string {
+ return o.column
+}
+
+func (o *Order) GetSort() Sort {
+ return o.sort
+}
+
+func (o *Order) SortString() string {
+ switch o.GetSort() {
+ case Ascending:
+ return "ASC"
+ case Descending:
+ return "DESC"
+ }
+
+ return ``
+}
+
+func (o *Order) IsRaw() bool {
+ return o.isRaw
+}
+
+func ParseOrder(expressions ...string) []*Order {
+ var orders []*Order
+ for _, expression := range expressions {
+ sort := Ascending
+ column := strings.ReplaceAll(expression, clauses.ExprSep, clauses.ExprDot)
+ if column[0] == '-' {
+ sort = Descending
+ column = column[1:]
+ }
+
+ orders = append(orders, &Order{
+ column: column,
+ sort: sort,
+ })
+ }
+
+ return orders
+}
+
+func Column(column string) Option {
+ return func(order *Order) {
+ order.column = strings.ReplaceAll(column, clauses.ExprSep, clauses.ExprDot)
+ }
+}
+
+func sort(sort Sort) Option {
+ return func(order *Order) {
+ order.sort = sort
+ }
+}
+
+func SortAscending() Option {
+ return sort(Ascending)
+}
+
+func SortDescending() Option {
+ return sort(Descending)
+}
+
+func SortNone() Option {
+ return sort(None)
+}
+
+func Raw() Option {
+ return func(order *Order) {
+ order.isRaw = true
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/orm/cmd.go b/src/vendor/github.com/beego/beego/v2/client/orm/cmd.go
similarity index 79%
rename from src/vendor/github.com/beego/beego/orm/cmd.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/cmd.go
index 0ff4dc40d..9819badb1 100644
--- a/src/vendor/github.com/beego/beego/orm/cmd.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/cmd.go
@@ -15,6 +15,7 @@
package orm
import (
+ "context"
"flag"
"fmt"
"os"
@@ -26,9 +27,7 @@ type commander interface {
Run() error
}
-var (
- commands = make(map[string]commander)
-)
+var commands = make(map[string]commander)
// print help.
func printHelp(errs ...string) {
@@ -46,7 +45,7 @@ func printHelp(errs ...string) {
os.Exit(2)
}
-// RunCommand listen for orm command and then run it if command arguments passed.
+// RunCommand listens for orm command and runs if command arguments have been passed.
func RunCommand() {
if len(os.Args) < 2 || os.Args[1] != "orm" {
return
@@ -83,7 +82,7 @@ type commandSyncDb struct {
rtOnError bool
}
-// parse orm command line arguments.
+// Parse the orm command line arguments.
func (d *commandSyncDb) Parse(args []string) {
var name string
@@ -96,17 +95,21 @@ func (d *commandSyncDb) Parse(args []string) {
d.al = getDbAlias(name)
}
-// run orm line command.
+// Run orm line command.
func (d *commandSyncDb) Run() error {
var drops []string
+ var err error
if d.force {
- drops = getDbDropSQL(d.al)
+ drops, err = defaultModelCache.getDbDropSQL(d.al)
+ if err != nil {
+ return err
+ }
}
db := d.al.DB
- if d.force {
- for i, mi := range modelCache.allOrdered() {
+ if d.force && len(drops) > 0 {
+ for i, mi := range defaultModelCache.allOrdered() {
query := drops[i]
if !d.noInfo {
fmt.Printf("drop table `%s`\n", mi.table)
@@ -124,7 +127,10 @@ func (d *commandSyncDb) Run() error {
}
}
- sqls, indexes := getDbCreateSQL(d.al)
+ createQueries, indexes, err := defaultModelCache.getDbCreateSQL(d.al)
+ if err != nil {
+ return err
+ }
tables, err := d.al.DbBaser.GetTables(db)
if err != nil {
@@ -134,14 +140,21 @@ func (d *commandSyncDb) Run() error {
fmt.Printf(" %s\n", err.Error())
}
- for i, mi := range modelCache.allOrdered() {
+ ctx := context.Background()
+ for i, mi := range defaultModelCache.allOrdered() {
+
+ if !isApplicableTableForDB(mi.addrField, d.al.Name) {
+ fmt.Printf("table `%s` is not applicable to database '%s'\n", mi.table, d.al.Name)
+ continue
+ }
+
if tables[mi.table] {
if !d.noInfo {
fmt.Printf("table `%s` already exists, skip\n", mi.table)
}
var fields []*fieldInfo
- columns, err := d.al.DbBaser.GetColumns(db, mi.table)
+ columns, err := d.al.DbBaser.GetColumns(ctx, db, mi.table)
if err != nil {
if d.rtOnError {
return err
@@ -175,7 +188,7 @@ func (d *commandSyncDb) Run() error {
}
for _, idx := range indexes[mi.table] {
- if !d.al.DbBaser.IndexExists(db, idx.Table, idx.Name) {
+ if !d.al.DbBaser.IndexExists(ctx, db, idx.Table, idx.Name) {
if !d.noInfo {
fmt.Printf("create index `%s` for table `%s`\n", idx.Name, idx.Table)
}
@@ -201,7 +214,7 @@ func (d *commandSyncDb) Run() error {
fmt.Printf("create table `%s` \n", mi.table)
}
- queries := []string{sqls[i]}
+ queries := []string{createQueries[i]}
for _, idx := range indexes[mi.table] {
queries = append(queries, idx.SQL)
}
@@ -232,7 +245,7 @@ type commandSQLAll struct {
al *alias
}
-// parse orm command line arguments.
+// Parse orm command line arguments.
func (d *commandSQLAll) Parse(args []string) {
var name string
@@ -243,12 +256,15 @@ func (d *commandSQLAll) Parse(args []string) {
d.al = getDbAlias(name)
}
-// run orm line command.
+// Run orm line command.
func (d *commandSQLAll) Run() error {
- sqls, indexes := getDbCreateSQL(d.al)
+ createQueries, indexes, err := defaultModelCache.getDbCreateSQL(d.al)
+ if err != nil {
+ return err
+ }
var all []string
- for i, mi := range modelCache.allOrdered() {
- queries := []string{sqls[i]}
+ for i, mi := range defaultModelCache.allOrdered() {
+ queries := []string{createQueries[i]}
for _, idx := range indexes[mi.table] {
queries = append(queries, idx.SQL)
}
@@ -266,9 +282,9 @@ func init() {
}
// RunSyncdb run syncdb command line.
-// name means table's alias name. default is "default".
-// force means run next sql if the current is error.
-// verbose means show all info when running command or not.
+// name: Table's alias name (default is "default")
+// force: Run the next sql command even if the current gave an error
+// verbose: Print all information, useful for debugging
func RunSyncdb(name string, force bool, verbose bool) error {
BootStrap()
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/cmd_utils.go b/src/vendor/github.com/beego/beego/v2/client/orm/cmd_utils.go
new file mode 100644
index 000000000..7b795b22e
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/cmd_utils.go
@@ -0,0 +1,169 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "fmt"
+ "strings"
+)
+
+type dbIndex struct {
+ Table string
+ Name string
+ SQL string
+}
+
+// get database column type string.
+func getColumnTyp(al *alias, fi *fieldInfo) (col string) {
+ T := al.DbBaser.DbTypes()
+ fieldType := fi.fieldType
+ fieldSize := fi.size
+
+checkColumn:
+ switch fieldType {
+ case TypeBooleanField:
+ col = T["bool"]
+ case TypeVarCharField:
+ if al.Driver == DRPostgres && fi.toText {
+ col = T["string-text"]
+ } else {
+ col = fmt.Sprintf(T["string"], fieldSize)
+ }
+ case TypeCharField:
+ col = fmt.Sprintf(T["string-char"], fieldSize)
+ case TypeTextField:
+ col = T["string-text"]
+ case TypeTimeField:
+ col = T["time.Time-clock"]
+ case TypeDateField:
+ col = T["time.Time-date"]
+ case TypeDateTimeField:
+ // the precision of sqlite is not implemented
+ if al.Driver == 2 || fi.timePrecision == nil {
+ col = T["time.Time"]
+ } else {
+ s := T["time.Time-precision"]
+ col = fmt.Sprintf(s, *fi.timePrecision)
+ }
+
+ case TypeBitField:
+ col = T["int8"]
+ case TypeSmallIntegerField:
+ col = T["int16"]
+ case TypeIntegerField:
+ col = T["int32"]
+ case TypeBigIntegerField:
+ if al.Driver == DRSqlite {
+ fieldType = TypeIntegerField
+ goto checkColumn
+ }
+ col = T["int64"]
+ case TypePositiveBitField:
+ col = T["uint8"]
+ case TypePositiveSmallIntegerField:
+ col = T["uint16"]
+ case TypePositiveIntegerField:
+ col = T["uint32"]
+ case TypePositiveBigIntegerField:
+ col = T["uint64"]
+ case TypeFloatField:
+ col = T["float64"]
+ case TypeDecimalField:
+ s := T["float64-decimal"]
+ if !strings.Contains(s, "%d") {
+ col = s
+ } else {
+ col = fmt.Sprintf(s, fi.digits, fi.decimals)
+ }
+ case TypeJSONField:
+ if al.Driver != DRPostgres {
+ fieldType = TypeVarCharField
+ goto checkColumn
+ }
+ col = T["json"]
+ case TypeJsonbField:
+ if al.Driver != DRPostgres {
+ fieldType = TypeVarCharField
+ goto checkColumn
+ }
+ col = T["jsonb"]
+ case RelForeignKey, RelOneToOne:
+ fieldType = fi.relModelInfo.fields.pk.fieldType
+ fieldSize = fi.relModelInfo.fields.pk.size
+ goto checkColumn
+ }
+
+ return
+}
+
+// create alter sql string.
+func getColumnAddQuery(al *alias, fi *fieldInfo) string {
+ Q := al.DbBaser.TableQuote()
+ typ := getColumnTyp(al, fi)
+
+ if !fi.null {
+ typ += " " + "NOT NULL"
+ }
+
+ return fmt.Sprintf("ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s %s",
+ Q, fi.mi.table, Q,
+ Q, fi.column, Q,
+ typ, getColumnDefault(fi),
+ )
+}
+
+// Get string value for the attribute "DEFAULT" for the CREATE, ALTER commands
+func getColumnDefault(fi *fieldInfo) string {
+ var v, t, d string
+
+ // Skip default attribute if field is in relations
+ if fi.rel || fi.reverse {
+ return v
+ }
+
+ t = " DEFAULT '%s' "
+
+ // These defaults will be useful if there no config value orm:"default" and NOT NULL is on
+ switch fi.fieldType {
+ case TypeTimeField, TypeDateField, TypeDateTimeField, TypeTextField:
+ return v
+
+ case TypeBitField, TypeSmallIntegerField, TypeIntegerField,
+ TypeBigIntegerField, TypePositiveBitField, TypePositiveSmallIntegerField,
+ TypePositiveIntegerField, TypePositiveBigIntegerField, TypeFloatField,
+ TypeDecimalField:
+ t = " DEFAULT %s "
+ d = "0"
+ case TypeBooleanField:
+ t = " DEFAULT %s "
+ d = "FALSE"
+ case TypeJSONField, TypeJsonbField:
+ d = "{}"
+ }
+
+ if fi.colDefault {
+ if !fi.initial.Exist() {
+ v = fmt.Sprintf(t, "")
+ } else {
+ v = fmt.Sprintf(t, fi.initial.String())
+ }
+ } else {
+ if !fi.null {
+ v = fmt.Sprintf(t, d)
+ }
+ }
+
+ return v
+}
diff --git a/src/vendor/github.com/beego/beego/orm/db.go b/src/vendor/github.com/beego/beego/v2/client/orm/db.go
similarity index 81%
rename from src/vendor/github.com/beego/beego/orm/db.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db.go
index 7536a4224..cbaa81ad2 100644
--- a/src/vendor/github.com/beego/beego/orm/db.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db.go
@@ -15,12 +15,15 @@
package orm
import (
+ "context"
"database/sql"
"errors"
"fmt"
"reflect"
"strings"
"time"
+
+ "github.com/beego/beego/v2/client/orm/hints"
)
const (
@@ -29,41 +32,37 @@ const (
formatDateTime = "2006-01-02 15:04:05"
)
-var (
- // ErrMissPK missing pk error
- ErrMissPK = errors.New("missed pk value")
-)
+// ErrMissPK missing pk error
+var ErrMissPK = errors.New("missed pk value")
-var (
- operators = map[string]bool{
- "exact": true,
- "iexact": true,
- "strictexact": true,
- "contains": true,
- "icontains": true,
- // "regex": true,
- // "iregex": true,
- "gt": true,
- "gte": true,
- "lt": true,
- "lte": true,
- "eq": true,
- "nq": true,
- "ne": true,
- "startswith": true,
- "endswith": true,
- "istartswith": true,
- "iendswith": true,
- "in": true,
- "between": true,
- // "year": true,
- // "month": true,
- // "day": true,
- // "week_day": true,
- "isnull": true,
- // "search": true,
- }
-)
+var operators = map[string]bool{
+ "exact": true,
+ "iexact": true,
+ "strictexact": true,
+ "contains": true,
+ "icontains": true,
+ // "regex": true,
+ // "iregex": true,
+ "gt": true,
+ "gte": true,
+ "lt": true,
+ "lte": true,
+ "eq": true,
+ "nq": true,
+ "ne": true,
+ "startswith": true,
+ "endswith": true,
+ "istartswith": true,
+ "iendswith": true,
+ "in": true,
+ "between": true,
+ // "year": true,
+ // "month": true,
+ // "day": true,
+ // "week_day": true,
+ "isnull": true,
+ // "search": true,
+}
// an instance of dbBaser interface/
type dbBase struct {
@@ -265,8 +264,8 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
return value, nil
}
-// create insert sql preparation statement object.
-func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string, error) {
+// PrepareInsert create insert sql preparation statement object.
+func (d *dbBase) PrepareInsert(ctx context.Context, q dbQuerier, mi *modelInfo) (stmtQuerier, string, error) {
Q := d.ins.TableQuote()
dbcols := make([]string, 0, len(mi.fields.dbcols))
@@ -287,12 +286,12 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string,
d.ins.HasReturningID(mi, &query)
- stmt, err := q.Prepare(query)
+ stmt, err := q.PrepareContext(ctx, query)
return stmt, query, err
}
-// insert struct with prepared statement and given struct reflect value.
-func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
+// InsertStmt insert struct with prepared statement and given struct reflect value.
+func (d *dbBase) InsertStmt(ctx context.Context, stmt stmtQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, nil, tz)
if err != nil {
return 0, err
@@ -304,7 +303,7 @@ func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value,
err := row.Scan(&id)
return id, err
}
- res, err := stmt.Exec(values...)
+ res, err := stmt.ExecContext(ctx, values...)
if err == nil {
return res.LastInsertId()
}
@@ -312,7 +311,7 @@ func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value,
}
// query sql ,read records and persist in dbBaser.
-func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string, isForUpdate bool) error {
+func (d *dbBase) Read(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string, isForUpdate bool) error {
var whereCols []string
var args []interface{}
@@ -358,7 +357,7 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo
d.ins.ReplaceMarks(&query)
- row := q.QueryRow(query, args...)
+ row := q.QueryRowContext(ctx, query, args...)
if err := row.Scan(refs...); err != nil {
if err == sql.ErrNoRows {
return ErrNoRows
@@ -372,27 +371,27 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo
return nil
}
-// execute insert sql dbQuerier with given struct reflect.Value.
-func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
+// Insert execute insert sql dbQuerier with given struct reflect.Value.
+func (d *dbBase) Insert(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
names := make([]string, 0, len(mi.fields.dbcols))
values, autoFields, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz)
if err != nil {
return 0, err
}
- id, err := d.InsertValue(q, mi, false, names, values)
+ id, err := d.InsertValue(ctx, q, mi, false, names, values)
if err != nil {
return 0, err
}
if len(autoFields) > 0 {
- err = d.ins.setval(q, mi, autoFields)
+ err = d.ins.setval(ctx, q, mi, autoFields)
}
return id, err
}
-// multi-insert sql with given slice struct reflect.Value.
-func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bulk int, tz *time.Location) (int64, error) {
+// InsertMulti multi-insert sql with given slice struct reflect.Value.
+func (d *dbBase) InsertMulti(ctx context.Context, q dbQuerier, mi *modelInfo, sind reflect.Value, bulk int, tz *time.Location) (int64, error) {
var (
cnt int64
nums int
@@ -438,7 +437,7 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul
}
if i > 1 && i%bulk == 0 || length == i {
- num, err := d.InsertValue(q, mi, true, names, values[:nums])
+ num, err := d.InsertValue(ctx, q, mi, true, names, values[:nums])
if err != nil {
return cnt, err
}
@@ -449,15 +448,15 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul
var err error
if len(autoFields) > 0 {
- err = d.ins.setval(q, mi, autoFields)
+ err = d.ins.setval(ctx, q, mi, autoFields)
}
return cnt, err
}
-// execute insert sql with given struct and given values.
+// InsertValue execute insert sql with given struct and given values.
// insert the given values, not the field values in struct.
-func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) {
+func (d *dbBase) InsertValue(ctx context.Context, q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) {
Q := d.ins.TableQuote()
marks := make([]string, len(names))
@@ -480,16 +479,23 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s
d.ins.ReplaceMarks(&query)
if isMulti || !d.ins.HasReturningID(mi, &query) {
- res, err := q.Exec(query, values...)
+ res, err := q.ExecContext(ctx, query, values...)
if err == nil {
if isMulti {
return res.RowsAffected()
}
- return res.LastInsertId()
+
+ lastInsertId, err := res.LastInsertId()
+ if err != nil {
+ DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
+ return lastInsertId, ErrLastInsertIdUnavailable
+ } else {
+ return lastInsertId, nil
+ }
}
return 0, err
}
- row := q.QueryRow(query, values...)
+ row := q.QueryRowContext(ctx, query, values...)
var id int64
err := row.Scan(&id)
return id, err
@@ -498,7 +504,7 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s
// InsertOrUpdate a row
// If your primary key or unique column conflict will update
// If no will insert
-func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a *alias, args ...string) (int64, error) {
+func (d *dbBase) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, a *alias, args ...string) (int64, error) {
args0 := ""
iouStr := ""
argsMap := map[string]string{}
@@ -515,7 +521,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
return 0, fmt.Errorf("`%s` nonsupport InsertOrUpdate in beego", a.DriverName)
}
- //Get on the key-value pairs
+ // Get on the key-value pairs
for _, v := range args {
kv := strings.Split(v, "=")
if len(kv) == 2 {
@@ -527,7 +533,6 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
names := make([]string, 0, len(mi.fields.dbcols)-1)
Q := d.ins.TableQuote()
values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, a.TZ)
-
if err != nil {
return 0, err
}
@@ -550,7 +555,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
updates[i] = v + "=" + valueStr
case DRPostgres:
if conflitValue != nil {
- //postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
+ // postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args0)
updateValues = append(updateValues, conflitValue)
} else {
@@ -575,23 +580,30 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
if isMulti {
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
}
- //conflitValue maybe is a int,can`t use fmt.Sprintf
+ // conflitValue maybe is a int,can`t use fmt.Sprintf
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
d.ins.ReplaceMarks(&query)
if isMulti || !d.ins.HasReturningID(mi, &query) {
- res, err := q.Exec(query, values...)
+ res, err := q.ExecContext(ctx, query, values...)
if err == nil {
if isMulti {
return res.RowsAffected()
}
- return res.LastInsertId()
+
+ lastInsertId, err := res.LastInsertId()
+ if err != nil {
+ DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
+ return lastInsertId, ErrLastInsertIdUnavailable
+ } else {
+ return lastInsertId, nil
+ }
}
return 0, err
}
- row := q.QueryRow(query, values...)
+ row := q.QueryRowContext(ctx, query, values...)
var id int64
err = row.Scan(&id)
if err != nil && err.Error() == `pq: syntax error at or near "ON"` {
@@ -600,8 +612,8 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
return id, err
}
-// execute update sql dbQuerier with given struct reflect.Value.
-func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) {
+// Update execute update sql dbQuerier with given struct reflect.Value.
+func (d *dbBase) Update(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) {
pkName, pkValue, ok := getExistPk(mi, ind)
if !ok {
return 0, ErrMissPK
@@ -658,16 +670,16 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
d.ins.ReplaceMarks(&query)
- res, err := q.Exec(query, setValues...)
+ res, err := q.ExecContext(ctx, query, setValues...)
if err == nil {
return res.RowsAffected()
}
return 0, err
}
-// execute delete sql dbQuerier with given struct reflect.Value.
+// Delete execute delete sql dbQuerier with given struct reflect.Value.
// delete index is pk.
-func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) {
+func (d *dbBase) Delete(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) {
var whereCols []string
var args []interface{}
// if specify cols length > 0, then use it for where condition.
@@ -696,21 +708,14 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
query := fmt.Sprintf("DELETE FROM %s%s%s WHERE %s%s%s = ?", Q, mi.table, Q, Q, wheres, Q)
d.ins.ReplaceMarks(&query)
- res, err := q.Exec(query, args...)
+ res, err := q.ExecContext(ctx, query, args...)
if err == nil {
num, err := res.RowsAffected()
if err != nil {
return 0, err
}
if num > 0 {
- if mi.fields.pk.auto {
- if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
- ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(0)
- } else {
- ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(0)
- }
- }
- err := d.deleteRels(q, mi, args, tz)
+ err := d.deleteRels(ctx, q, mi, args, tz)
if err != nil {
return num, err
}
@@ -720,9 +725,9 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
return 0, err
}
-// update table-related record by querySet.
+// UpdateBatch update table-related record by querySet.
// need querySet not struct reflect.Value to update related records.
-func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, params Params, tz *time.Location) (int64, error) {
+func (d *dbBase) UpdateBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, params Params, tz *time.Location) (int64, error) {
columns := make([]string, 0, len(params))
values := make([]interface{}, 0, len(params))
for col, val := range params {
@@ -739,8 +744,10 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
}
tables := newDbTables(mi, d.ins)
+ var specifyIndexes string
if qs != nil {
tables.parseRelated(qs.related, qs.relDepth)
+ specifyIndexes = tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
}
where, args := tables.getCondSQL(cond, false, tz)
@@ -791,20 +798,17 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
sets := strings.Join(cols, ", ") + " "
if d.ins.SupportUpdateJoin() {
- query = fmt.Sprintf("UPDATE %s%s%s T0 %sSET %s%s", Q, mi.table, Q, join, sets, where)
+ query = fmt.Sprintf("UPDATE %s%s%s T0 %s%sSET %s%s", Q, mi.table, Q, specifyIndexes, join, sets, where)
} else {
- supQuery := fmt.Sprintf("SELECT T0.%s%s%s FROM %s%s%s T0 %s%s", Q, mi.fields.pk.column, Q, Q, mi.table, Q, join, where)
+ supQuery := fmt.Sprintf("SELECT T0.%s%s%s FROM %s%s%s T0 %s%s%s",
+ Q, mi.fields.pk.column, Q,
+ Q, mi.table, Q,
+ specifyIndexes, join, where)
query = fmt.Sprintf("UPDATE %s%s%s SET %sWHERE %s%s%s IN ( %s )", Q, mi.table, Q, sets, Q, mi.fields.pk.column, Q, supQuery)
}
d.ins.ReplaceMarks(&query)
- var err error
- var res sql.Result
- if qs != nil && qs.forContext {
- res, err = q.ExecContext(qs.ctx, query, values...)
- } else {
- res, err = q.Exec(query, values...)
- }
+ res, err := q.ExecContext(ctx, query, values...)
if err == nil {
return res.RowsAffected()
}
@@ -813,13 +817,13 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
// delete related records.
// do UpdateBanch or DeleteBanch by condition of tables' relationship.
-func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz *time.Location) error {
+func (d *dbBase) deleteRels(ctx context.Context, q dbQuerier, mi *modelInfo, args []interface{}, tz *time.Location) error {
for _, fi := range mi.fields.fieldsReverse {
fi = fi.reverseFieldInfo
switch fi.onDelete {
case odCascade:
cond := NewCondition().And(fmt.Sprintf("%s__in", fi.name), args...)
- _, err := d.DeleteBatch(q, nil, fi.mi, cond, tz)
+ _, err := d.DeleteBatch(ctx, q, nil, fi.mi, cond, tz)
if err != nil {
return err
}
@@ -829,7 +833,7 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz *
if fi.onDelete == odSetDefault {
params[fi.column] = fi.initial.String()
}
- _, err := d.UpdateBatch(q, nil, fi.mi, cond, params, tz)
+ _, err := d.UpdateBatch(ctx, q, nil, fi.mi, cond, params, tz)
if err != nil {
return err
}
@@ -839,13 +843,15 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz *
return nil
}
-// delete table-related records.
-func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (int64, error) {
+// DeleteBatch delete table-related records.
+func (d *dbBase) DeleteBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (int64, error) {
tables := newDbTables(mi, d.ins)
tables.skipEnd = true
+ var specifyIndexes string
if qs != nil {
tables.parseRelated(qs.related, qs.relDepth)
+ specifyIndexes = tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
}
if cond == nil || cond.IsEmpty() {
@@ -858,12 +864,12 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
join := tables.getJoinSQL()
cols := fmt.Sprintf("T0.%s%s%s", Q, mi.fields.pk.column, Q)
- query := fmt.Sprintf("SELECT %s FROM %s%s%s T0 %s%s", cols, Q, mi.table, Q, join, where)
+ query := fmt.Sprintf("SELECT %s FROM %s%s%s T0 %s%s%s", cols, Q, mi.table, Q, specifyIndexes, join, where)
d.ins.ReplaceMarks(&query)
var rs *sql.Rows
- r, err := q.Query(query, args...)
+ r, err := q.QueryContext(ctx, query, args...)
if err != nil {
return 0, err
}
@@ -897,19 +903,14 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
query = fmt.Sprintf("DELETE FROM %s%s%s WHERE %s%s%s %s", Q, mi.table, Q, Q, mi.fields.pk.column, Q, sqlIn)
d.ins.ReplaceMarks(&query)
- var res sql.Result
- if qs != nil && qs.forContext {
- res, err = q.ExecContext(qs.ctx, query, args...)
- } else {
- res, err = q.Exec(query, args...)
- }
+ res, err := q.ExecContext(ctx, query, args...)
if err == nil {
num, err := res.RowsAffected()
if err != nil {
return 0, err
}
if num > 0 {
- err := d.deleteRels(q, mi, args, tz)
+ err := d.deleteRels(ctx, q, mi, args, tz)
if err != nil {
return num, err
}
@@ -919,15 +920,15 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
return 0, err
}
-// read related records.
-func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}, tz *time.Location, cols []string) (int64, error) {
-
+// ReadBatch read related records.
+func (d *dbBase) ReadBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}, tz *time.Location, cols []string) (int64, error) {
val := reflect.ValueOf(container)
ind := reflect.Indirect(val)
- errTyp := true
+ unregister := true
one := true
isPtr := true
+ name := ""
if val.Kind() == reflect.Ptr {
fn := ""
@@ -940,19 +941,17 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
case reflect.Struct:
isPtr = false
fn = getFullName(typ)
+ name = getTableName(reflect.New(typ))
}
} else {
fn = getFullName(ind.Type())
+ name = getTableName(ind)
}
- errTyp = fn != mi.fullName
+ unregister = fn != mi.fullName
}
- if errTyp {
- if one {
- panic(fmt.Errorf("wrong object type `%s` for rows scan, need *%s", val.Type(), mi.fullName))
- } else {
- panic(fmt.Errorf("wrong object type `%s` for rows scan, need *[]*%s or *[]%s", val.Type(), mi.fullName, mi.fullName))
- }
+ if unregister {
+ RegisterModel(container)
}
rlimit := qs.limit
@@ -1003,6 +1002,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
orderBy := tables.getOrderSQL(qs.orders)
limit := tables.getLimitSQL(mi, offset, rlimit)
join := tables.getJoinSQL()
+ specifyIndexes := tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
for _, tbl := range tables.tables {
if tbl.sel {
@@ -1016,26 +1016,31 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
if qs.distinct {
sqlSelect += " DISTINCT"
}
- query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s", sqlSelect, sels, Q, mi.table, Q, join, where, groupBy, orderBy, limit)
+ if qs.aggregate != "" {
+ sels = qs.aggregate
+ }
+ query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s%s",
+ sqlSelect, sels, Q, mi.table, Q,
+ specifyIndexes, join, where, groupBy, orderBy, limit)
- if qs.forupdate {
+ if qs.forUpdate {
query += " FOR UPDATE"
}
d.ins.ReplaceMarks(&query)
- var rs *sql.Rows
- var err error
- if qs != nil && qs.forContext {
- rs, err = q.QueryContext(qs.ctx, query, args...)
- if err != nil {
- return 0, err
- }
- } else {
- rs, err = q.Query(query, args...)
- if err != nil {
- return 0, err
- }
+ rs, err := q.QueryContext(ctx, query, args...)
+ if err != nil {
+ return 0, err
+ }
+
+ defer rs.Close()
+
+ slice := ind
+ if unregister {
+ mi, _ = defaultModelCache.get(name)
+ tCols = mi.fields.dbcols
+ colsNum = len(tCols)
}
refs := make([]interface{}, colsNum)
@@ -1043,11 +1048,6 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
var ref interface{}
refs[i] = &ref
}
-
- defer rs.Close()
-
- slice := ind
-
var cnt int64
for rs.Next() {
if one && cnt == 0 || !one {
@@ -1111,7 +1111,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
ind.Set(mind)
} else {
if cnt == 0 {
- // you can use a empty & caped container list
+ // you can use an empty & caped container list
// orm will not replace it
if ind.Len() != 0 {
// if container is not empty
@@ -1135,7 +1135,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
ind.Set(slice)
} else {
// when a result is empty and container is nil
- // to set a empty container
+ // to set an empty container
if ind.IsNil() {
ind.Set(reflect.MakeSlice(ind.Type(), 0, 0))
}
@@ -1145,8 +1145,8 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
return cnt, nil
}
-// excute count sql and return count result int64.
-func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (cnt int64, err error) {
+// Count excute count sql and return count result int64.
+func (d *dbBase) Count(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (cnt int64, err error) {
tables := newDbTables(mi, d.ins)
tables.parseRelated(qs.related, qs.relDepth)
@@ -1154,10 +1154,13 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition
groupBy := tables.getGroupSQL(qs.groups)
tables.getOrderSQL(qs.orders)
join := tables.getJoinSQL()
+ specifyIndexes := tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
Q := d.ins.TableQuote()
- query := fmt.Sprintf("SELECT COUNT(*) FROM %s%s%s T0 %s%s%s", Q, mi.table, Q, join, where, groupBy)
+ query := fmt.Sprintf("SELECT COUNT(*) FROM %s%s%s T0 %s%s%s%s",
+ Q, mi.table, Q,
+ specifyIndexes, join, where, groupBy)
if groupBy != "" {
query = fmt.Sprintf("SELECT COUNT(*) FROM (%s) AS T", query)
@@ -1165,17 +1168,12 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition
d.ins.ReplaceMarks(&query)
- var row *sql.Row
- if qs != nil && qs.forContext {
- row = q.QueryRowContext(qs.ctx, query, args...)
- } else {
- row = q.QueryRow(query, args...)
- }
+ row := q.QueryRowContext(ctx, query, args...)
err = row.Scan(&cnt)
return
}
-// generate sql with replacing operator string placeholders and replaced values.
+// GenerateOperatorSQL generate sql with replacing operator string placeholders and replaced values.
func (d *dbBase) GenerateOperatorSQL(mi *modelInfo, fi *fieldInfo, operator string, args []interface{}, tz *time.Location) (string, []interface{}) {
var sql string
params := getFlatParams(fi, args, tz)
@@ -1203,7 +1201,7 @@ func (d *dbBase) GenerateOperatorSQL(mi *modelInfo, fi *fieldInfo, operator stri
}
sql = d.ins.OperatorSQL(operator)
switch operator {
- case "exact", "strictexact":
+ case "exact":
if arg == nil {
params[0] = "IS NULL"
}
@@ -1235,7 +1233,7 @@ func (d *dbBase) GenerateOperatorSQL(mi *modelInfo, fi *fieldInfo, operator stri
return sql, params
}
-// gernerate sql string with inner function, such as UPPER(text).
+// GenerateOperatorLeftCol gernerate sql string with inner function, such as UPPER(text).
func (d *dbBase) GenerateOperatorLeftCol(*fieldInfo, string, *string) {
// default not use
}
@@ -1327,7 +1325,14 @@ setValue:
t time.Time
err error
)
- if len(s) >= 19 {
+
+ if fi.timePrecision != nil && len(s) >= (20+*fi.timePrecision) {
+ layout := formatDateTime + "."
+ for i := 0; i < *fi.timePrecision; i++ {
+ layout += "0"
+ }
+ t, err = time.ParseInLocation(layout, s[:20+*fi.timePrecision], tz)
+ } else if len(s) >= 19 {
s = s[:19]
t, err = time.ParseInLocation(formatDateTime, s, tz)
} else if len(s) >= 10 {
@@ -1417,12 +1422,10 @@ end:
}
return value, nil
-
}
// set one value to struct column field.
func (d *dbBase) setFieldValue(fi *fieldInfo, value interface{}, field reflect.Value) (interface{}, error) {
-
fieldType := fi.fieldType
isNative := !fi.isFielder
@@ -1612,9 +1615,8 @@ setValue:
return value, nil
}
-// query sql, read values , save to *[]ParamList.
-func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}, tz *time.Location) (int64, error) {
-
+// ReadValues query sql, read values , save to *[]ParamList.
+func (d *dbBase) ReadValues(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}, tz *time.Location) (int64, error) {
var (
maps []Params
lists []ParamsList
@@ -1681,6 +1683,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
orderBy := tables.getOrderSQL(qs.orders)
limit := tables.getLimitSQL(mi, qs.offset, qs.limit)
join := tables.getJoinSQL()
+ specifyIndexes := tables.getIndexSql(mi.table, qs.useIndex, qs.indexes)
sels := strings.Join(cols, ", ")
@@ -1688,11 +1691,14 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
if qs.distinct {
sqlSelect += " DISTINCT"
}
- query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s", sqlSelect, sels, Q, mi.table, Q, join, where, groupBy, orderBy, limit)
+ query := fmt.Sprintf("%s %s FROM %s%s%s T0 %s%s%s%s%s%s",
+ sqlSelect, sels,
+ Q, mi.table, Q,
+ specifyIndexes, join, where, groupBy, orderBy, limit)
d.ins.ReplaceMarks(&query)
- rs, err := q.Query(query, args...)
+ rs, err := q.QueryContext(ctx, query, args...)
if err != nil {
return 0, err
}
@@ -1782,11 +1788,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
return cnt, nil
}
-func (d *dbBase) RowsTo(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, string, string, *time.Location) (int64, error) {
- return 0, nil
-}
-
-// flag of update joined record.
+// SupportUpdateJoin flag of update joined record.
func (d *dbBase) SupportUpdateJoin() bool {
return true
}
@@ -1795,12 +1797,12 @@ func (d *dbBase) MaxLimit() uint64 {
return 18446744073709551615
}
-// return quote.
+// TableQuote return quote.
func (d *dbBase) TableQuote() string {
return "`"
}
-// replace value placeholder in parametered sql string.
+// ReplaceMarks replace value placeholder in parametered sql string.
func (d *dbBase) ReplaceMarks(query *string) {
// default use `?` as mark, do nothing
}
@@ -1811,26 +1813,26 @@ func (d *dbBase) HasReturningID(*modelInfo, *string) bool {
}
// sync auto key
-func (d *dbBase) setval(db dbQuerier, mi *modelInfo, autoFields []string) error {
+func (d *dbBase) setval(ctx context.Context, db dbQuerier, mi *modelInfo, autoFields []string) error {
return nil
}
-// convert time from db.
+// TimeFromDB convert time from db.
func (d *dbBase) TimeFromDB(t *time.Time, tz *time.Location) {
*t = t.In(tz)
}
-// convert time to db.
+// TimeToDB convert time to db.
func (d *dbBase) TimeToDB(t *time.Time, tz *time.Location) {
*t = t.In(tz)
}
-// get database types.
+// DbTypes get database types.
func (d *dbBase) DbTypes() map[string]string {
return nil
}
-// gt all tables.
+// GetTables gt all tables.
func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) {
tables := make(map[string]bool)
query := d.ins.ShowTablesQuery()
@@ -1855,11 +1857,11 @@ func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) {
return tables, nil
}
-// get all cloumns in table.
-func (d *dbBase) GetColumns(db dbQuerier, table string) (map[string][3]string, error) {
+// GetColumns get all cloumns in table.
+func (d *dbBase) GetColumns(ctx context.Context, db dbQuerier, table string) (map[string][3]string, error) {
columns := make(map[string][3]string)
query := d.ins.ShowColumnsQuery(table)
- rows, err := db.Query(query)
+ rows, err := db.QueryContext(ctx, query)
if err != nil {
return columns, err
}
@@ -1898,6 +1900,32 @@ func (d *dbBase) ShowColumnsQuery(table string) string {
}
// not implement.
-func (d *dbBase) IndexExists(dbQuerier, string, string) bool {
+func (d *dbBase) IndexExists(context.Context, dbQuerier, string, string) bool {
panic(ErrNotImplement)
}
+
+// GenerateSpecifyIndex return a specifying index clause
+func (d *dbBase) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
+ var s []string
+ Q := d.TableQuote()
+ for _, index := range indexes {
+ tmp := fmt.Sprintf(`%s%s%s`, Q, index, Q)
+ s = append(s, tmp)
+ }
+
+ var useWay string
+
+ switch useIndex {
+ case hints.KeyUseIndex:
+ useWay = `USE`
+ case hints.KeyForceIndex:
+ useWay = `FORCE`
+ case hints.KeyIgnoreIndex:
+ useWay = `IGNORE`
+ default:
+ DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
+ return ``
+ }
+
+ return fmt.Sprintf(` %s INDEX(%s) `, useWay, strings.Join(s, `,`))
+}
diff --git a/src/vendor/github.com/beego/beego/orm/db_alias.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_alias.go
similarity index 63%
rename from src/vendor/github.com/beego/beego/orm/db_alias.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_alias.go
index 369802a71..28c8ab8ec 100644
--- a/src/vendor/github.com/beego/beego/orm/db_alias.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_alias.go
@@ -18,7 +18,6 @@ import (
"context"
"database/sql"
"fmt"
- "reflect"
"sync"
"time"
@@ -64,7 +63,7 @@ var (
"tidb": DRTiDB,
"oracle": DROracle,
"oci8": DROracle, // github.com/mattn/go-oci8
- "ora": DROracle, //https://github.com/rana/ora
+ "ora": DROracle, // https://github.com/rana/ora
}
dbBasers = map[DriverType]dbBaser{
DRMySQL: newdbBaseMysql(),
@@ -108,10 +107,16 @@ func (ac *_dbCache) getDefault() (al *alias) {
type DB struct {
*sync.RWMutex
- DB *sql.DB
- stmtDecorators *lru.Cache
+ DB *sql.DB
+ stmtDecorators *lru.Cache
+ stmtDecoratorsLimit int
}
+var (
+ _ dbQuerier = new(DB)
+ _ txer = new(DB)
+)
+
func (d *DB) Begin() (*sql.Tx, error) {
return d.DB.Begin()
}
@@ -120,7 +125,7 @@ func (d *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
return d.DB.BeginTx(ctx, opts)
}
-//su must call release to release *sql.Stmt after using
+// su must call release to release *sql.Stmt after using
func (d *DB) getStmtDecorator(query string) (*stmtDecorator, error) {
d.RLock()
c, ok := d.stmtDecorators.Get(query)
@@ -161,16 +166,14 @@ func (d *DB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error
}
func (d *DB) Exec(query string, args ...interface{}) (sql.Result, error) {
- sd, err := d.getStmtDecorator(query)
- if err != nil {
- return nil, err
- }
- stmt := sd.getStmt()
- defer sd.release()
- return stmt.Exec(args...)
+ return d.ExecContext(context.Background(), query, args...)
}
func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
+ if d.stmtDecorators == nil {
+ return d.DB.ExecContext(ctx, query, args...)
+ }
+
sd, err := d.getStmtDecorator(query)
if err != nil {
return nil, err
@@ -181,16 +184,14 @@ func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{})
}
func (d *DB) Query(query string, args ...interface{}) (*sql.Rows, error) {
- sd, err := d.getStmtDecorator(query)
- if err != nil {
- return nil, err
- }
- stmt := sd.getStmt()
- defer sd.release()
- return stmt.Query(args...)
+ return d.QueryContext(context.Background(), query, args...)
}
func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
+ if d.stmtDecorators == nil {
+ return d.DB.QueryContext(ctx, query, args...)
+ }
+
sd, err := d.getStmtDecorator(query)
if err != nil {
return nil, err
@@ -201,37 +202,98 @@ func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}
}
func (d *DB) QueryRow(query string, args ...interface{}) *sql.Row {
- sd, err := d.getStmtDecorator(query)
- if err != nil {
- panic(err)
- }
- stmt := sd.getStmt()
- defer sd.release()
- return stmt.QueryRow(args...)
-
+ return d.QueryRowContext(context.Background(), query, args...)
}
func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
+ if d.stmtDecorators == nil {
+ return d.DB.QueryRowContext(ctx, query, args...)
+ }
+
sd, err := d.getStmtDecorator(query)
if err != nil {
panic(err)
}
stmt := sd.getStmt()
defer sd.release()
- return stmt.QueryRowContext(ctx, args)
+ return stmt.QueryRowContext(ctx, args...)
+}
+
+type TxDB struct {
+ tx *sql.Tx
+}
+
+var (
+ _ dbQuerier = new(TxDB)
+ _ txEnder = new(TxDB)
+)
+
+func (t *TxDB) Commit() error {
+ return t.tx.Commit()
+}
+
+func (t *TxDB) Rollback() error {
+ return t.tx.Rollback()
+}
+
+func (t *TxDB) RollbackUnlessCommit() error {
+ err := t.tx.Rollback()
+ if err != sql.ErrTxDone {
+ return err
+ }
+ return nil
+}
+
+var (
+ _ dbQuerier = new(TxDB)
+ _ txEnder = new(TxDB)
+)
+
+func (t *TxDB) Prepare(query string) (*sql.Stmt, error) {
+ return t.PrepareContext(context.Background(), query)
+}
+
+func (t *TxDB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
+ return t.tx.PrepareContext(ctx, query)
+}
+
+func (t *TxDB) Exec(query string, args ...interface{}) (sql.Result, error) {
+ return t.ExecContext(context.Background(), query, args...)
+}
+
+func (t *TxDB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
+ return t.tx.ExecContext(ctx, query, args...)
+}
+
+func (t *TxDB) Query(query string, args ...interface{}) (*sql.Rows, error) {
+ return t.QueryContext(context.Background(), query, args...)
+}
+
+func (t *TxDB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
+ return t.tx.QueryContext(ctx, query, args...)
+}
+
+func (t *TxDB) QueryRow(query string, args ...interface{}) *sql.Row {
+ return t.QueryRowContext(context.Background(), query, args...)
+}
+
+func (t *TxDB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
+ return t.tx.QueryRowContext(ctx, query, args...)
}
type alias struct {
- Name string
- Driver DriverType
- DriverName string
- DataSource string
- MaxIdleConns int
- MaxOpenConns int
- DB *DB
- DbBaser dbBaser
- TZ *time.Location
- Engine string
+ Name string
+ Driver DriverType
+ DriverName string
+ DataSource string
+ MaxIdleConns int
+ MaxOpenConns int
+ ConnMaxLifetime time.Duration
+ StmtCacheSize int
+ DB *DB
+ DbBaser dbBaser
+ TZ *time.Location
+ Engine string
}
func detectTZ(al *alias) {
@@ -290,15 +352,52 @@ func detectTZ(al *alias) {
}
}
-func addAliasWthDB(aliasName, driverName string, db *sql.DB) (*alias, error) {
- al := new(alias)
+func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) {
+ existErr := fmt.Errorf("DataBase alias name `%s` already registered, cannot reuse", aliasName)
+ if _, ok := dataBaseCache.get(aliasName); ok {
+ return nil, existErr
+ }
+
+ al, err := newAliasWithDb(aliasName, driverName, db, params...)
+ if err != nil {
+ return nil, err
+ }
+
+ if !dataBaseCache.add(aliasName, al) {
+ return nil, existErr
+ }
+
+ return al, nil
+}
+
+func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...DBOption) (*alias, error) {
+ al := &alias{}
+ al.DB = &DB{
+ RWMutex: new(sync.RWMutex),
+ DB: db,
+ }
+
+ for _, p := range params {
+ p(al)
+ }
+
+ var stmtCache *lru.Cache
+ var stmtCacheSize int
+
+ if al.StmtCacheSize > 0 {
+ _stmtCache, errC := newStmtDecoratorLruWithEvict(al.StmtCacheSize)
+ if errC != nil {
+ return nil, errC
+ } else {
+ stmtCache = _stmtCache
+ stmtCacheSize = al.StmtCacheSize
+ }
+ }
+
al.Name = aliasName
al.DriverName = driverName
- al.DB = &DB{
- RWMutex: new(sync.RWMutex),
- DB: db,
- stmtDecorators: newStmtDecoratorLruWithEvict(),
- }
+ al.DB.stmtDecorators = stmtCache
+ al.DB.stmtDecoratorsLimit = stmtCacheSize
if dr, ok := drivers[driverName]; ok {
al.DbBaser = dbBasers[dr]
@@ -312,21 +411,50 @@ func addAliasWthDB(aliasName, driverName string, db *sql.DB) (*alias, error) {
return nil, fmt.Errorf("register db Ping `%s`, %s", aliasName, err.Error())
}
- if !dataBaseCache.add(aliasName, al) {
- return nil, fmt.Errorf("DataBase alias name `%s` already registered, cannot reuse", aliasName)
- }
+ detectTZ(al)
return al, nil
}
+// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
+// Deprecated you should not use this, we will remove it in the future
+func SetMaxIdleConns(aliasName string, maxIdleConns int) {
+ al := getDbAlias(aliasName)
+ al.SetMaxIdleConns(maxIdleConns)
+}
+
+// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
+// Deprecated you should not use this, we will remove it in the future
+func SetMaxOpenConns(aliasName string, maxOpenConns int) {
+ al := getDbAlias(aliasName)
+ al.SetMaxOpenConns(maxOpenConns)
+}
+
+// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
+func (al *alias) SetMaxIdleConns(maxIdleConns int) {
+ al.MaxIdleConns = maxIdleConns
+ al.DB.DB.SetMaxIdleConns(maxIdleConns)
+}
+
+// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
+func (al *alias) SetMaxOpenConns(maxOpenConns int) {
+ al.MaxOpenConns = maxOpenConns
+ al.DB.DB.SetMaxOpenConns(maxOpenConns)
+}
+
+func (al *alias) SetConnMaxLifetime(lifeTime time.Duration) {
+ al.ConnMaxLifetime = lifeTime
+ al.DB.DB.SetConnMaxLifetime(lifeTime)
+}
+
// AddAliasWthDB add a aliasName for the drivename
-func AddAliasWthDB(aliasName, driverName string, db *sql.DB) error {
- _, err := addAliasWthDB(aliasName, driverName, db)
+func AddAliasWthDB(aliasName, driverName string, db *sql.DB, params ...DBOption) error {
+ _, err := addAliasWthDB(aliasName, driverName, db, params...)
return err
}
// RegisterDataBase Setting the database connect params. Use the database driver self dataSource args.
-func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) error {
+func RegisterDataBase(aliasName, driverName, dataSource string, params ...DBOption) error {
var (
err error
db *sql.DB
@@ -339,24 +467,13 @@ func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) e
goto end
}
- al, err = addAliasWthDB(aliasName, driverName, db)
+ al, err = addAliasWthDB(aliasName, driverName, db, params...)
if err != nil {
goto end
}
al.DataSource = dataSource
- detectTZ(al)
-
- for i, v := range params {
- switch i {
- case 0:
- SetMaxIdleConns(al.Name, v)
- case 1:
- SetMaxOpenConns(al.Name, v)
- }
- }
-
end:
if err != nil {
if db != nil {
@@ -390,24 +507,6 @@ func SetDataBaseTZ(aliasName string, tz *time.Location) error {
return nil
}
-// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
-func SetMaxIdleConns(aliasName string, maxIdleConns int) {
- al := getDbAlias(aliasName)
- al.MaxIdleConns = maxIdleConns
- al.DB.DB.SetMaxIdleConns(maxIdleConns)
-}
-
-// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
-func SetMaxOpenConns(aliasName string, maxOpenConns int) {
- al := getDbAlias(aliasName)
- al.MaxOpenConns = maxOpenConns
- al.DB.DB.SetMaxOpenConns(maxOpenConns)
- // for tip go 1.2
- if fun := reflect.ValueOf(al.DB).MethodByName("SetMaxOpenConns"); fun.IsValid() {
- fun.Call([]reflect.Value{reflect.ValueOf(maxOpenConns)})
- }
-}
-
// GetDB Get *sql.DB from registered database by db alias name.
// Use "default" as alias name if you not set.
func GetDB(aliasNames ...string) (*sql.DB, error) {
@@ -445,7 +544,7 @@ func (s *stmtDecorator) release() {
s.wg.Done()
}
-//garbage recycle for stmt
+// garbage recycle for stmt
func (s *stmtDecorator) destroy() {
go func() {
s.wg.Wait()
@@ -459,11 +558,42 @@ func newStmtDecorator(sqlStmt *sql.Stmt) *stmtDecorator {
}
}
-func newStmtDecoratorLruWithEvict() *lru.Cache {
- // temporarily solution
- // we fixed this problem in v2.x
- cache, _ := lru.NewWithEvict(50, func(key interface{}, value interface{}) {
+func newStmtDecoratorLruWithEvict(cacheSize int) (*lru.Cache, error) {
+ cache, err := lru.NewWithEvict(cacheSize, func(key interface{}, value interface{}) {
value.(*stmtDecorator).destroy()
})
- return cache
+ if err != nil {
+ return nil, err
+ }
+ return cache, nil
+}
+
+type DBOption func(al *alias)
+
+// MaxIdleConnections return a hint about MaxIdleConnections
+func MaxIdleConnections(maxIdleConn int) DBOption {
+ return func(al *alias) {
+ al.SetMaxIdleConns(maxIdleConn)
+ }
+}
+
+// MaxOpenConnections return a hint about MaxOpenConnections
+func MaxOpenConnections(maxOpenConn int) DBOption {
+ return func(al *alias) {
+ al.SetMaxOpenConns(maxOpenConn)
+ }
+}
+
+// ConnMaxLifetime return a hint about ConnMaxLifetime
+func ConnMaxLifetime(v time.Duration) DBOption {
+ return func(al *alias) {
+ al.SetConnMaxLifetime(v)
+ }
+}
+
+// MaxStmtCacheSize return a hint about MaxStmtCacheSize
+func MaxStmtCacheSize(v int) DBOption {
+ return func(al *alias) {
+ al.StmtCacheSize = v
+ }
}
diff --git a/src/vendor/github.com/beego/beego/orm/db_mysql.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_mysql.go
similarity index 72%
rename from src/vendor/github.com/beego/beego/orm/db_mysql.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_mysql.go
index 8dd1e7550..75d24b2a7 100644
--- a/src/vendor/github.com/beego/beego/orm/db_mysql.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_mysql.go
@@ -15,6 +15,7 @@
package orm
import (
+ "context"
"fmt"
"reflect"
"strings"
@@ -43,24 +44,25 @@ var mysqlOperators = map[string]string{
// mysql column field types.
var mysqlTypes = map[string]string{
- "auto": "AUTO_INCREMENT NOT NULL PRIMARY KEY",
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "varchar(%d)",
- "string-char": "char(%d)",
- "string-text": "longtext",
- "time.Time-date": "date",
- "time.Time": "datetime",
- "int8": "tinyint",
- "int16": "smallint",
- "int32": "integer",
- "int64": "bigint",
- "uint8": "tinyint unsigned",
- "uint16": "smallint unsigned",
- "uint32": "integer unsigned",
- "uint64": "bigint unsigned",
- "float64": "double precision",
- "float64-decimal": "numeric(%d, %d)",
+ "auto": "AUTO_INCREMENT NOT NULL PRIMARY KEY",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "varchar(%d)",
+ "string-char": "char(%d)",
+ "string-text": "longtext",
+ "time.Time-date": "date",
+ "time.Time": "datetime",
+ "int8": "tinyint",
+ "int16": "smallint",
+ "int32": "integer",
+ "int64": "bigint",
+ "uint8": "tinyint unsigned",
+ "uint16": "smallint unsigned",
+ "uint32": "integer unsigned",
+ "uint64": "bigint unsigned",
+ "float64": "double precision",
+ "float64-decimal": "numeric(%d, %d)",
+ "time.Time-precision": "datetime(%d)",
}
// mysql dbBaser implementation.
@@ -92,8 +94,8 @@ func (d *dbBaseMysql) ShowColumnsQuery(table string) string {
}
// execute sql to check index exist.
-func (d *dbBaseMysql) IndexExists(db dbQuerier, table string, name string) bool {
- row := db.QueryRow("SELECT count(*) FROM information_schema.statistics "+
+func (d *dbBaseMysql) IndexExists(ctx context.Context, db dbQuerier, table string, name string) bool {
+ row := db.QueryRowContext(ctx, "SELECT count(*) FROM information_schema.statistics "+
"WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?", table, name)
var cnt int
row.Scan(&cnt)
@@ -104,13 +106,13 @@ func (d *dbBaseMysql) IndexExists(db dbQuerier, table string, name string) bool
// If your primary key or unique column conflict will update
// If no will insert
// Add "`" for mysql sql building
-func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a *alias, args ...string) (int64, error) {
+func (d *dbBaseMysql) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, a *alias, args ...string) (int64, error) {
var iouStr string
argsMap := map[string]string{}
iouStr = "ON DUPLICATE KEY UPDATE"
- //Get on the key-value pairs
+ // Get on the key-value pairs
for _, v := range args {
kv := strings.Split(v, "=")
if len(kv) == 2 {
@@ -122,7 +124,6 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
names := make([]string, 0, len(mi.fields.dbcols)-1)
Q := d.ins.TableQuote()
values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, a.TZ)
-
if err != nil {
return 0, err
}
@@ -154,23 +155,30 @@ func (d *dbBaseMysql) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Val
if isMulti {
qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks
}
- //conflitValue maybe is a int,can`t use fmt.Sprintf
+ // conflitValue maybe is an int,can`t use fmt.Sprintf
query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr)
d.ins.ReplaceMarks(&query)
if isMulti || !d.ins.HasReturningID(mi, &query) {
- res, err := q.Exec(query, values...)
+ res, err := q.ExecContext(ctx, query, values...)
if err == nil {
if isMulti {
return res.RowsAffected()
}
- return res.LastInsertId()
+
+ lastInsertId, err := res.LastInsertId()
+ if err != nil {
+ DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
+ return lastInsertId, ErrLastInsertIdUnavailable
+ } else {
+ return lastInsertId, nil
+ }
}
return 0, err
}
- row := q.QueryRow(query, values...)
+ row := q.QueryRowContext(ctx, query, values...)
var id int64
err = row.Scan(&id)
return id, err
diff --git a/src/vendor/github.com/beego/beego/orm/db_oracle.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_oracle.go
similarity index 57%
rename from src/vendor/github.com/beego/beego/orm/db_oracle.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_oracle.go
index 5d121f834..a3b93ff31 100644
--- a/src/vendor/github.com/beego/beego/orm/db_oracle.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_oracle.go
@@ -15,8 +15,11 @@
package orm
import (
+ "context"
"fmt"
"strings"
+
+ "github.com/beego/beego/v2/client/orm/hints"
)
// oracle operators.
@@ -31,23 +34,24 @@ var oracleOperators = map[string]string{
// oracle column field types.
var oracleTypes = map[string]string{
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "VARCHAR2(%d)",
- "string-char": "CHAR(%d)",
- "string-text": "VARCHAR2(%d)",
- "time.Time-date": "DATE",
- "time.Time": "TIMESTAMP",
- "int8": "INTEGER",
- "int16": "INTEGER",
- "int32": "INTEGER",
- "int64": "INTEGER",
- "uint8": "INTEGER",
- "uint16": "INTEGER",
- "uint32": "INTEGER",
- "uint64": "INTEGER",
- "float64": "NUMBER",
- "float64-decimal": "NUMBER(%d, %d)",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "VARCHAR2(%d)",
+ "string-char": "CHAR(%d)",
+ "string-text": "VARCHAR2(%d)",
+ "time.Time-date": "DATE",
+ "time.Time": "TIMESTAMP",
+ "int8": "INTEGER",
+ "int16": "INTEGER",
+ "int32": "INTEGER",
+ "int64": "INTEGER",
+ "uint8": "INTEGER",
+ "uint16": "INTEGER",
+ "uint32": "INTEGER",
+ "uint64": "INTEGER",
+ "float64": "NUMBER",
+ "float64-decimal": "NUMBER(%d, %d)",
+ "time.Time-precision": "TIMESTAMP(%d)",
}
// oracle dbBaser
@@ -74,7 +78,7 @@ func (d *dbBaseOracle) DbTypes() map[string]string {
return oracleTypes
}
-//ShowTablesQuery show all the tables in database
+// ShowTablesQuery show all the tables in database
func (d *dbBaseOracle) ShowTablesQuery() string {
return "SELECT TABLE_NAME FROM USER_TABLES"
}
@@ -86,8 +90,8 @@ func (d *dbBaseOracle) ShowColumnsQuery(table string) string {
}
// check index is exist
-func (d *dbBaseOracle) IndexExists(db dbQuerier, table string, name string) bool {
- row := db.QueryRow("SELECT COUNT(*) FROM USER_IND_COLUMNS, USER_INDEXES "+
+func (d *dbBaseOracle) IndexExists(ctx context.Context, db dbQuerier, table string, name string) bool {
+ row := db.QueryRowContext(ctx, "SELECT COUNT(*) FROM USER_IND_COLUMNS, USER_INDEXES "+
"WHERE USER_IND_COLUMNS.INDEX_NAME = USER_INDEXES.INDEX_NAME "+
"AND USER_IND_COLUMNS.TABLE_NAME = ? AND USER_IND_COLUMNS.INDEX_NAME = ?", strings.ToUpper(table), strings.ToUpper(name))
@@ -96,9 +100,32 @@ func (d *dbBaseOracle) IndexExists(db dbQuerier, table string, name string) bool
return cnt > 0
}
+func (d *dbBaseOracle) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
+ var s []string
+ Q := d.TableQuote()
+ for _, index := range indexes {
+ tmp := fmt.Sprintf(`%s%s%s`, Q, index, Q)
+ s = append(s, tmp)
+ }
+
+ var hint string
+
+ switch useIndex {
+ case hints.KeyUseIndex, hints.KeyForceIndex:
+ hint = `INDEX`
+ case hints.KeyIgnoreIndex:
+ hint = `NO_INDEX`
+ default:
+ DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
+ return ``
+ }
+
+ return fmt.Sprintf(` /*+ %s(%s %s)*/ `, hint, tableName, strings.Join(s, `,`))
+}
+
// execute insert sql with given struct and given values.
// insert the given values, not the field values in struct.
-func (d *dbBaseOracle) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) {
+func (d *dbBaseOracle) InsertValue(ctx context.Context, q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) {
Q := d.ins.TableQuote()
marks := make([]string, len(names))
@@ -121,16 +148,23 @@ func (d *dbBaseOracle) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, nam
d.ins.ReplaceMarks(&query)
if isMulti || !d.ins.HasReturningID(mi, &query) {
- res, err := q.Exec(query, values...)
+ res, err := q.ExecContext(ctx, query, values...)
if err == nil {
if isMulti {
return res.RowsAffected()
}
- return res.LastInsertId()
+
+ lastInsertId, err := res.LastInsertId()
+ if err != nil {
+ DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
+ return lastInsertId, ErrLastInsertIdUnavailable
+ } else {
+ return lastInsertId, nil
+ }
}
return 0, err
}
- row := q.QueryRow(query, values...)
+ row := q.QueryRowContext(ctx, query, values...)
var id int64
err := row.Scan(&id)
return id, err
diff --git a/src/vendor/github.com/beego/beego/orm/db_postgres.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_postgres.go
similarity index 72%
rename from src/vendor/github.com/beego/beego/orm/db_postgres.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_postgres.go
index c488fb388..b2f321db6 100644
--- a/src/vendor/github.com/beego/beego/orm/db_postgres.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_postgres.go
@@ -15,6 +15,7 @@
package orm
import (
+ "context"
"fmt"
"strconv"
)
@@ -39,26 +40,27 @@ var postgresOperators = map[string]string{
// postgresql column field types.
var postgresTypes = map[string]string{
- "auto": "serial NOT NULL PRIMARY KEY",
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "varchar(%d)",
- "string-char": "char(%d)",
- "string-text": "text",
- "time.Time-date": "date",
- "time.Time": "timestamp with time zone",
- "int8": `smallint CHECK("%COL%" >= -127 AND "%COL%" <= 128)`,
- "int16": "smallint",
- "int32": "integer",
- "int64": "bigint",
- "uint8": `smallint CHECK("%COL%" >= 0 AND "%COL%" <= 255)`,
- "uint16": `integer CHECK("%COL%" >= 0)`,
- "uint32": `bigint CHECK("%COL%" >= 0)`,
- "uint64": `bigint CHECK("%COL%" >= 0)`,
- "float64": "double precision",
- "float64-decimal": "numeric(%d, %d)",
- "json": "json",
- "jsonb": "jsonb",
+ "auto": "serial NOT NULL PRIMARY KEY",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "varchar(%d)",
+ "string-char": "char(%d)",
+ "string-text": "text",
+ "time.Time-date": "date",
+ "time.Time": "timestamp with time zone",
+ "int8": `smallint CHECK("%COL%" >= -127 AND "%COL%" <= 128)`,
+ "int16": "smallint",
+ "int32": "integer",
+ "int64": "bigint",
+ "uint8": `smallint CHECK("%COL%" >= 0 AND "%COL%" <= 255)`,
+ "uint16": `integer CHECK("%COL%" >= 0)`,
+ "uint32": `bigint CHECK("%COL%" >= 0)`,
+ "uint64": `bigint CHECK("%COL%" >= 0)`,
+ "float64": "double precision",
+ "float64-decimal": "numeric(%d, %d)",
+ "json": "json",
+ "jsonb": "jsonb",
+ "time.Time-precision": "timestamp(%d) with time zone",
}
// postgresql dbBaser.
@@ -139,7 +141,7 @@ func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) bool {
}
// sync auto key
-func (d *dbBasePostgres) setval(db dbQuerier, mi *modelInfo, autoFields []string) error {
+func (d *dbBasePostgres) setval(ctx context.Context, db dbQuerier, mi *modelInfo, autoFields []string) error {
if len(autoFields) == 0 {
return nil
}
@@ -150,7 +152,7 @@ func (d *dbBasePostgres) setval(db dbQuerier, mi *modelInfo, autoFields []string
mi.table, name,
Q, name, Q,
Q, mi.table, Q)
- if _, err := db.Exec(query); err != nil {
+ if _, err := db.ExecContext(ctx, query); err != nil {
return err
}
}
@@ -173,14 +175,20 @@ func (d *dbBasePostgres) DbTypes() map[string]string {
}
// check index exist in postgresql.
-func (d *dbBasePostgres) IndexExists(db dbQuerier, table string, name string) bool {
+func (d *dbBasePostgres) IndexExists(ctx context.Context, db dbQuerier, table string, name string) bool {
query := fmt.Sprintf("SELECT COUNT(*) FROM pg_indexes WHERE tablename = '%s' AND indexname = '%s'", table, name)
- row := db.QueryRow(query)
+ row := db.QueryRowContext(ctx, query)
var cnt int
row.Scan(&cnt)
return cnt > 0
}
+// GenerateSpecifyIndex return a specifying index clause
+func (d *dbBasePostgres) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
+ DebugLog.Println("[WARN] Not support any specifying index action, so that action is ignored")
+ return ``
+}
+
// create new postgresql dbBaser.
func newdbBasePostgres() dbBaser {
b := new(dbBasePostgres)
diff --git a/src/vendor/github.com/beego/beego/orm/db_sqlite.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_sqlite.go
similarity index 64%
rename from src/vendor/github.com/beego/beego/orm/db_sqlite.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_sqlite.go
index 1d62ee348..6a4b31312 100644
--- a/src/vendor/github.com/beego/beego/orm/db_sqlite.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_sqlite.go
@@ -15,10 +15,14 @@
package orm
import (
+ "context"
"database/sql"
"fmt"
"reflect"
+ "strings"
"time"
+
+ "github.com/beego/beego/v2/client/orm/hints"
)
// sqlite operators.
@@ -41,24 +45,25 @@ var sqliteOperators = map[string]string{
// sqlite column types.
var sqliteTypes = map[string]string{
- "auto": "integer NOT NULL PRIMARY KEY AUTOINCREMENT",
- "pk": "NOT NULL PRIMARY KEY",
- "bool": "bool",
- "string": "varchar(%d)",
- "string-char": "character(%d)",
- "string-text": "text",
- "time.Time-date": "date",
- "time.Time": "datetime",
- "int8": "tinyint",
- "int16": "smallint",
- "int32": "integer",
- "int64": "bigint",
- "uint8": "tinyint unsigned",
- "uint16": "smallint unsigned",
- "uint32": "integer unsigned",
- "uint64": "bigint unsigned",
- "float64": "real",
- "float64-decimal": "decimal",
+ "auto": "integer NOT NULL PRIMARY KEY AUTOINCREMENT",
+ "pk": "NOT NULL PRIMARY KEY",
+ "bool": "bool",
+ "string": "varchar(%d)",
+ "string-char": "character(%d)",
+ "string-text": "text",
+ "time.Time-date": "date",
+ "time.Time": "datetime",
+ "time.Time-precision": "datetime(%d)",
+ "int8": "tinyint",
+ "int16": "smallint",
+ "int32": "integer",
+ "int64": "bigint",
+ "uint8": "tinyint unsigned",
+ "uint16": "smallint unsigned",
+ "uint32": "integer unsigned",
+ "uint64": "bigint unsigned",
+ "float64": "real",
+ "float64-decimal": "decimal",
}
// sqlite dbBaser.
@@ -69,11 +74,11 @@ type dbBaseSqlite struct {
var _ dbBaser = new(dbBaseSqlite)
// override base db read for update behavior as SQlite does not support syntax
-func (d *dbBaseSqlite) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string, isForUpdate bool) error {
+func (d *dbBaseSqlite) Read(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string, isForUpdate bool) error {
if isForUpdate {
DebugLog.Println("[WARN] SQLite does not support SELECT FOR UPDATE query, isForUpdate param is ignored and always as false to do the work")
}
- return d.dbBase.Read(q, mi, ind, tz, cols, false)
+ return d.dbBase.Read(ctx, q, mi, ind, tz, cols, false)
}
// get sqlite operator.
@@ -110,9 +115,9 @@ func (d *dbBaseSqlite) ShowTablesQuery() string {
}
// get columns in sqlite.
-func (d *dbBaseSqlite) GetColumns(db dbQuerier, table string) (map[string][3]string, error) {
+func (d *dbBaseSqlite) GetColumns(ctx context.Context, db dbQuerier, table string) (map[string][3]string, error) {
query := d.ins.ShowColumnsQuery(table)
- rows, err := db.Query(query)
+ rows, err := db.QueryContext(ctx, query)
if err != nil {
return nil, err
}
@@ -136,9 +141,9 @@ func (d *dbBaseSqlite) ShowColumnsQuery(table string) string {
}
// check index exist in sqlite.
-func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool {
+func (d *dbBaseSqlite) IndexExists(ctx context.Context, db dbQuerier, table string, name string) bool {
query := fmt.Sprintf("PRAGMA index_list('%s')", table)
- rows, err := db.Query(query)
+ rows, err := db.QueryContext(ctx, query)
if err != nil {
panic(err)
}
@@ -153,6 +158,24 @@ func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool
return false
}
+// GenerateSpecifyIndex return a specifying index clause
+func (d *dbBaseSqlite) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
+ var s []string
+ Q := d.TableQuote()
+ for _, index := range indexes {
+ tmp := fmt.Sprintf(`%s%s%s`, Q, index, Q)
+ s = append(s, tmp)
+ }
+
+ switch useIndex {
+ case hints.KeyUseIndex, hints.KeyForceIndex:
+ return fmt.Sprintf(` INDEXED BY %s `, strings.Join(s, `,`))
+ default:
+ DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
+ return ``
+ }
+}
+
// create new sqlite dbBaser.
func newdbBaseSqlite() dbBaser {
b := new(dbBaseSqlite)
diff --git a/src/vendor/github.com/beego/beego/orm/db_tables.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_tables.go
similarity index 88%
rename from src/vendor/github.com/beego/beego/orm/db_tables.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_tables.go
index 4b21a6fc7..a0b355ca2 100644
--- a/src/vendor/github.com/beego/beego/orm/db_tables.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_tables.go
@@ -18,6 +18,9 @@ import (
"fmt"
"strings"
"time"
+
+ "github.com/beego/beego/v2/client/orm/clauses"
+ "github.com/beego/beego/v2/client/orm/clauses/order_clause"
)
// table info struct.
@@ -103,7 +106,6 @@ func (t *dbTables) loopDepth(depth int, prefix string, fi *fieldInfo, related []
// parse related fields.
func (t *dbTables) parseRelated(rels []string, depth int) {
-
relsNum := len(rels)
related := make([]string, relsNum)
copy(related, rels)
@@ -421,7 +423,7 @@ func (t *dbTables) getGroupSQL(groups []string) (groupSQL string) {
}
// generate order sql.
-func (t *dbTables) getOrderSQL(orders []string) (orderSQL string) {
+func (t *dbTables) getOrderSQL(orders []*order_clause.Order) (orderSQL string) {
if len(orders) == 0 {
return
}
@@ -430,19 +432,25 @@ func (t *dbTables) getOrderSQL(orders []string) (orderSQL string) {
orderSqls := make([]string, 0, len(orders))
for _, order := range orders {
- asc := "ASC"
- if order[0] == '-' {
- asc = "DESC"
- order = order[1:]
- }
- exprs := strings.Split(order, ExprSep)
+ column := order.GetColumn()
+ clause := strings.Split(column, clauses.ExprDot)
- index, _, fi, suc := t.parseExprs(t.mi, exprs)
- if !suc {
- panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(exprs, ExprSep)))
- }
+ if order.IsRaw() {
+ if len(clause) == 2 {
+ orderSqls = append(orderSqls, fmt.Sprintf("%s.%s%s%s %s", clause[0], Q, clause[1], Q, order.SortString()))
+ } else if len(clause) == 1 {
+ orderSqls = append(orderSqls, fmt.Sprintf("%s%s%s %s", Q, clause[0], Q, order.SortString()))
+ } else {
+ panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(clause, ExprSep)))
+ }
+ } else {
+ index, _, fi, suc := t.parseExprs(t.mi, clause)
+ if !suc {
+ panic(fmt.Errorf("unknown field/column name `%s`", strings.Join(clause, ExprSep)))
+ }
- orderSqls = append(orderSqls, fmt.Sprintf("%s.%s%s%s %s", index, Q, fi.column, Q, asc))
+ orderSqls = append(orderSqls, fmt.Sprintf("%s.%s%s%s %s", index, Q, fi.column, Q, order.SortString()))
+ }
}
orderSQL = fmt.Sprintf("ORDER BY %s ", strings.Join(orderSqls, ", "))
@@ -472,6 +480,15 @@ func (t *dbTables) getLimitSQL(mi *modelInfo, offset int64, limit int64) (limits
return
}
+// getIndexSql generate index sql.
+func (t *dbTables) getIndexSql(tableName string, useIndex int, indexes []string) (clause string) {
+ if len(indexes) == 0 {
+ return
+ }
+
+ return t.base.GenerateSpecifyIndex(tableName, useIndex, indexes)
+}
+
// crete new tables collection.
func newDbTables(mi *modelInfo, base dbBaser) *dbTables {
tables := &dbTables{}
diff --git a/src/vendor/github.com/beego/beego/orm/db_tidb.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_tidb.go
similarity index 89%
rename from src/vendor/github.com/beego/beego/orm/db_tidb.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_tidb.go
index 6020a488f..48c5b4e73 100644
--- a/src/vendor/github.com/beego/beego/orm/db_tidb.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_tidb.go
@@ -15,6 +15,7 @@
package orm
import (
+ "context"
"fmt"
)
@@ -47,8 +48,8 @@ func (d *dbBaseTidb) ShowColumnsQuery(table string) string {
}
// execute sql to check index exist.
-func (d *dbBaseTidb) IndexExists(db dbQuerier, table string, name string) bool {
- row := db.QueryRow("SELECT count(*) FROM information_schema.statistics "+
+func (d *dbBaseTidb) IndexExists(ctx context.Context, db dbQuerier, table string, name string) bool {
+ row := db.QueryRowContext(ctx, "SELECT count(*) FROM information_schema.statistics "+
"WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?", table, name)
var cnt int
row.Scan(&cnt)
diff --git a/src/vendor/github.com/beego/beego/orm/db_utils.go b/src/vendor/github.com/beego/beego/v2/client/orm/db_utils.go
similarity index 98%
rename from src/vendor/github.com/beego/beego/orm/db_utils.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/db_utils.go
index 7ae10ca5e..01f5a028f 100644
--- a/src/vendor/github.com/beego/beego/orm/db_utils.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/db_utils.go
@@ -55,16 +55,14 @@ func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interfac
// get fields description as flatted string.
func getFlatParams(fi *fieldInfo, args []interface{}, tz *time.Location) (params []interface{}) {
-
outFor:
for _, arg := range args {
- val := reflect.ValueOf(arg)
-
if arg == nil {
params = append(params, arg)
continue
}
+ val := reflect.ValueOf(arg)
kind := val.Kind()
if kind == reflect.Ptr {
val = val.Elem()
@@ -158,7 +156,7 @@ outFor:
typ := val.Type()
name := getFullName(typ)
var value interface{}
- if mmi, ok := modelCache.getByFullName(name); ok {
+ if mmi, ok := defaultModelCache.getByFullName(name); ok {
if _, vu, exist := getExistPk(mmi, val); exist {
value = vu
}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/do_nothing_orm.go b/src/vendor/github.com/beego/beego/v2/client/orm/do_nothing_orm.go
new file mode 100644
index 000000000..d9e574a50
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/do_nothing_orm.go
@@ -0,0 +1,181 @@
+// Copyright 2020 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "context"
+ "database/sql"
+
+ "github.com/beego/beego/v2/core/utils"
+)
+
+// DoNothingOrm won't do anything, usually you use this to custom your mock Ormer implementation
+// I think golang mocking interface is hard to use
+// this may help you to integrate with Ormer
+
+var _ Ormer = new(DoNothingOrm)
+
+type DoNothingOrm struct{}
+
+func (d *DoNothingOrm) Read(md interface{}, cols ...string) error {
+ return nil
+}
+
+func (d *DoNothingOrm) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ return nil
+}
+
+func (d *DoNothingOrm) ReadForUpdate(md interface{}, cols ...string) error {
+ return nil
+}
+
+func (d *DoNothingOrm) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ return nil
+}
+
+func (d *DoNothingOrm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ return false, 0, nil
+}
+
+func (d *DoNothingOrm) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ return false, 0, nil
+}
+
+func (d *DoNothingOrm) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) QueryM2M(md interface{}, name string) QueryM2Mer {
+ return nil
+}
+
+// NOTE: this method is deprecated, context parameter will not take effect.
+func (d *DoNothingOrm) QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer {
+ return nil
+}
+
+func (d *DoNothingOrm) QueryTable(ptrStructOrTableName interface{}) QuerySeter {
+ return nil
+}
+
+// NOTE: this method is deprecated, context parameter will not take effect.
+func (d *DoNothingOrm) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter {
+ return nil
+}
+
+func (d *DoNothingOrm) DBStats() *sql.DBStats {
+ return nil
+}
+
+func (d *DoNothingOrm) Insert(md interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) InsertMulti(bulk int, mds interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) Update(md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) Delete(md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ return 0, nil
+}
+
+func (d *DoNothingOrm) Raw(query string, args ...interface{}) RawSeter {
+ return nil
+}
+
+func (d *DoNothingOrm) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter {
+ return nil
+}
+
+func (d *DoNothingOrm) Driver() Driver {
+ return nil
+}
+
+func (d *DoNothingOrm) Begin() (TxOrmer, error) {
+ return nil, nil
+}
+
+func (d *DoNothingOrm) BeginWithCtx(ctx context.Context) (TxOrmer, error) {
+ return nil, nil
+}
+
+func (d *DoNothingOrm) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) {
+ return nil, nil
+}
+
+func (d *DoNothingOrm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
+ return nil, nil
+}
+
+func (d *DoNothingOrm) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return nil
+}
+
+func (d *DoNothingOrm) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return nil
+}
+
+func (d *DoNothingOrm) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return nil
+}
+
+func (d *DoNothingOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return nil
+}
+
+// DoNothingTxOrm is similar with DoNothingOrm, usually you use it to test
+type DoNothingTxOrm struct {
+ DoNothingOrm
+}
+
+func (d *DoNothingTxOrm) Commit() error {
+ return nil
+}
+
+func (d *DoNothingTxOrm) Rollback() error {
+ return nil
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/filter.go b/src/vendor/github.com/beego/beego/v2/client/orm/filter.go
new file mode 100644
index 000000000..bc13c3fa4
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/filter.go
@@ -0,0 +1,40 @@
+// Copyright 2020 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "context"
+)
+
+// FilterChain is used to build a Filter
+// don't forget to call next(...) inside your Filter
+type FilterChain func(next Filter) Filter
+
+// Filter's behavior is a little big strange.
+// it's only be called when users call methods of Ormer
+// return value is an array. it's a little bit hard to understand,
+// for example, the Ormer's Read method only return error
+// so the filter processing this method should return an array whose first element is error
+// and, Ormer's ReadOrCreateWithCtx return three values, so the Filter's result should contains three values
+type Filter func(ctx context.Context, inv *Invocation) []interface{}
+
+var globalFilterChains = make([]FilterChain, 0, 4)
+
+// AddGlobalFilterChain adds a new FilterChain
+// All orm instances built after this invocation will use this filterChain,
+// but instances built before this invocation will not be affected
+func AddGlobalFilterChain(filterChain ...FilterChain) {
+ globalFilterChains = append(globalFilterChains, filterChain...)
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/filter_orm_decorator.go b/src/vendor/github.com/beego/beego/v2/client/orm/filter_orm_decorator.go
new file mode 100644
index 000000000..3b23284d7
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/filter_orm_decorator.go
@@ -0,0 +1,534 @@
+// Copyright 2020 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "context"
+ "database/sql"
+ "reflect"
+ "time"
+
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/core/utils"
+)
+
+const (
+ TxNameKey = "TxName"
+)
+
+var (
+ _ Ormer = new(filterOrmDecorator)
+ _ TxOrmer = new(filterOrmDecorator)
+)
+
+type filterOrmDecorator struct {
+ ormer
+ TxBeginner
+ TxCommitter
+
+ root Filter
+
+ insideTx bool
+ txStartTime time.Time
+ txName string
+}
+
+func NewFilterOrmDecorator(delegate Ormer, filterChains ...FilterChain) Ormer {
+ res := &filterOrmDecorator{
+ ormer: delegate,
+ TxBeginner: delegate,
+ root: func(ctx context.Context, inv *Invocation) []interface{} {
+ return inv.execute(ctx)
+ },
+ }
+
+ for i := len(filterChains) - 1; i >= 0; i-- {
+ node := filterChains[i]
+ res.root = node(res.root)
+ }
+ return res
+}
+
+func NewFilterTxOrmDecorator(delegate TxOrmer, root Filter, txName string) TxOrmer {
+ res := &filterOrmDecorator{
+ ormer: delegate,
+ TxCommitter: delegate,
+ root: root,
+ insideTx: true,
+ txStartTime: time.Now(),
+ txName: txName,
+ }
+ return res
+}
+
+func (f *filterOrmDecorator) Read(md interface{}, cols ...string) error {
+ return f.ReadWithCtx(context.Background(), md, cols...)
+}
+
+func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "ReadWithCtx",
+ Args: []interface{}{md, cols},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ err := f.ormer.ReadWithCtx(c, md, cols...)
+ return []interface{}{err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return f.convertError(res[0])
+}
+
+func (f *filterOrmDecorator) ReadForUpdate(md interface{}, cols ...string) error {
+ return f.ReadForUpdateWithCtx(context.Background(), md, cols...)
+}
+
+func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "ReadForUpdateWithCtx",
+ Args: []interface{}{md, cols},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ err := f.ormer.ReadForUpdateWithCtx(c, md, cols...)
+ return []interface{}{err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return f.convertError(res[0])
+}
+
+func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ return f.ReadOrCreateWithCtx(context.Background(), md, col1, cols...)
+}
+
+func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "ReadOrCreateWithCtx",
+ Args: []interface{}{md, col1, cols},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ ok, res, err := f.ormer.ReadOrCreateWithCtx(c, md, col1, cols...)
+ return []interface{}{ok, res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(bool), res[1].(int64), f.convertError(res[2])
+}
+
+func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) {
+ return f.LoadRelatedWithCtx(context.Background(), md, name, args...)
+}
+
+func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "LoadRelatedWithCtx",
+ Args: []interface{}{md, name, args},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res, err := f.ormer.LoadRelatedWithCtx(c, md, name, args...)
+ return []interface{}{res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(int64), f.convertError(res[1])
+}
+
+func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "QueryM2M",
+ Args: []interface{}{md, name},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res := f.ormer.QueryM2M(md, name)
+ return []interface{}{res}
+ },
+ }
+ res := f.root(context.Background(), inv)
+ if res[0] == nil {
+ return nil
+ }
+ return res[0].(QueryM2Mer)
+}
+
+// NOTE: this method is deprecated, context parameter will not take effect.
+func (f *filterOrmDecorator) QueryM2MWithCtx(_ context.Context, md interface{}, name string) QueryM2Mer {
+ logs.Warn("QueryM2MWithCtx is DEPRECATED. Use methods with `WithCtx` on QueryM2Mer suffix as replacement.")
+ return f.QueryM2M(md, name)
+}
+
+func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QuerySeter {
+ var (
+ name string
+ md interface{}
+ mi *modelInfo
+ )
+
+ if table, ok := ptrStructOrTableName.(string); ok {
+ name = table
+ } else {
+ name = getFullName(indirectType(reflect.TypeOf(ptrStructOrTableName)))
+ md = ptrStructOrTableName
+ }
+
+ if m, ok := defaultModelCache.getByFullName(name); ok {
+ mi = m
+ }
+
+ inv := &Invocation{
+ Method: "QueryTable",
+ Args: []interface{}{ptrStructOrTableName},
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ Md: md,
+ mi: mi,
+ f: func(c context.Context) []interface{} {
+ res := f.ormer.QueryTable(ptrStructOrTableName)
+ return []interface{}{res}
+ },
+ }
+ res := f.root(context.Background(), inv)
+
+ if res[0] == nil {
+ return nil
+ }
+ return res[0].(QuerySeter)
+}
+
+// NOTE: this method is deprecated, context parameter will not take effect.
+func (f *filterOrmDecorator) QueryTableWithCtx(_ context.Context, ptrStructOrTableName interface{}) QuerySeter {
+ logs.Warn("QueryTableWithCtx is DEPRECATED. Use methods with `WithCtx`on QuerySeter suffix as replacement.")
+ return f.QueryTable(ptrStructOrTableName)
+}
+
+func (f *filterOrmDecorator) DBStats() *sql.DBStats {
+ inv := &Invocation{
+ Method: "DBStats",
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res := f.ormer.DBStats()
+ return []interface{}{res}
+ },
+ }
+ res := f.root(context.Background(), inv)
+
+ if res[0] == nil {
+ return nil
+ }
+
+ return res[0].(*sql.DBStats)
+}
+
+func (f *filterOrmDecorator) Insert(md interface{}) (int64, error) {
+ return f.InsertWithCtx(context.Background(), md)
+}
+
+func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "InsertWithCtx",
+ Args: []interface{}{md},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res, err := f.ormer.InsertWithCtx(c, md)
+ return []interface{}{res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(int64), f.convertError(res[1])
+}
+
+func (f *filterOrmDecorator) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
+ return f.InsertOrUpdateWithCtx(context.Background(), md, colConflitAndArgs...)
+}
+
+func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "InsertOrUpdateWithCtx",
+ Args: []interface{}{md, colConflitAndArgs},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res, err := f.ormer.InsertOrUpdateWithCtx(c, md, colConflitAndArgs...)
+ return []interface{}{res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(int64), f.convertError(res[1])
+}
+
+func (f *filterOrmDecorator) InsertMulti(bulk int, mds interface{}) (int64, error) {
+ return f.InsertMultiWithCtx(context.Background(), bulk, mds)
+}
+
+// InsertMultiWithCtx uses the first element's model info
+func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
+ var (
+ md interface{}
+ mi *modelInfo
+ )
+
+ sind := reflect.Indirect(reflect.ValueOf(mds))
+
+ if (sind.Kind() == reflect.Array || sind.Kind() == reflect.Slice) && sind.Len() > 0 {
+ ind := reflect.Indirect(sind.Index(0))
+ md = ind.Interface()
+ mi, _ = defaultModelCache.getByMd(md)
+ }
+
+ inv := &Invocation{
+ Method: "InsertMultiWithCtx",
+ Args: []interface{}{bulk, mds},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res, err := f.ormer.InsertMultiWithCtx(c, bulk, mds)
+ return []interface{}{res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(int64), f.convertError(res[1])
+}
+
+func (f *filterOrmDecorator) Update(md interface{}, cols ...string) (int64, error) {
+ return f.UpdateWithCtx(context.Background(), md, cols...)
+}
+
+func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "UpdateWithCtx",
+ Args: []interface{}{md, cols},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res, err := f.ormer.UpdateWithCtx(c, md, cols...)
+ return []interface{}{res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(int64), f.convertError(res[1])
+}
+
+func (f *filterOrmDecorator) Delete(md interface{}, cols ...string) (int64, error) {
+ return f.DeleteWithCtx(context.Background(), md, cols...)
+}
+
+func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ mi, _ := defaultModelCache.getByMd(md)
+ inv := &Invocation{
+ Method: "DeleteWithCtx",
+ Args: []interface{}{md, cols},
+ Md: md,
+ mi: mi,
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res, err := f.ormer.DeleteWithCtx(c, md, cols...)
+ return []interface{}{res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(int64), f.convertError(res[1])
+}
+
+func (f *filterOrmDecorator) Raw(query string, args ...interface{}) RawSeter {
+ return f.RawWithCtx(context.Background(), query, args...)
+}
+
+func (f *filterOrmDecorator) RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter {
+ inv := &Invocation{
+ Method: "RawWithCtx",
+ Args: []interface{}{query, args},
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res := f.ormer.RawWithCtx(c, query, args...)
+ return []interface{}{res}
+ },
+ }
+ res := f.root(ctx, inv)
+
+ if res[0] == nil {
+ return nil
+ }
+ return res[0].(RawSeter)
+}
+
+func (f *filterOrmDecorator) Driver() Driver {
+ inv := &Invocation{
+ Method: "Driver",
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res := f.ormer.Driver()
+ return []interface{}{res}
+ },
+ }
+ res := f.root(context.Background(), inv)
+ if res[0] == nil {
+ return nil
+ }
+ return res[0].(Driver)
+}
+
+func (f *filterOrmDecorator) Begin() (TxOrmer, error) {
+ return f.BeginWithCtxAndOpts(context.Background(), nil)
+}
+
+func (f *filterOrmDecorator) BeginWithCtx(ctx context.Context) (TxOrmer, error) {
+ return f.BeginWithCtxAndOpts(ctx, nil)
+}
+
+func (f *filterOrmDecorator) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) {
+ return f.BeginWithCtxAndOpts(context.Background(), opts)
+}
+
+func (f *filterOrmDecorator) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
+ inv := &Invocation{
+ Method: "BeginWithCtxAndOpts",
+ Args: []interface{}{opts},
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ f: func(c context.Context) []interface{} {
+ res, err := f.TxBeginner.BeginWithCtxAndOpts(c, opts)
+ res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(c))
+ return []interface{}{res, err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return res[0].(TxOrmer), f.convertError(res[1])
+}
+
+func (f *filterOrmDecorator) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return f.DoTxWithCtxAndOpts(context.Background(), nil, task)
+}
+
+func (f *filterOrmDecorator) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return f.DoTxWithCtxAndOpts(ctx, nil, task)
+}
+
+func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return f.DoTxWithCtxAndOpts(context.Background(), opts, task)
+}
+
+func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ inv := &Invocation{
+ Method: "DoTxWithCtxAndOpts",
+ Args: []interface{}{opts, task},
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ TxName: getTxNameFromCtx(ctx),
+ f: func(c context.Context) []interface{} {
+ err := doTxTemplate(c, f, opts, task)
+ return []interface{}{err}
+ },
+ }
+ res := f.root(ctx, inv)
+ return f.convertError(res[0])
+}
+
+func (f *filterOrmDecorator) Commit() error {
+ inv := &Invocation{
+ Method: "Commit",
+ Args: []interface{}{},
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ TxName: f.txName,
+ f: func(c context.Context) []interface{} {
+ err := f.TxCommitter.Commit()
+ return []interface{}{err}
+ },
+ }
+ res := f.root(context.Background(), inv)
+ return f.convertError(res[0])
+}
+
+func (f *filterOrmDecorator) Rollback() error {
+ inv := &Invocation{
+ Method: "Rollback",
+ Args: []interface{}{},
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ TxName: f.txName,
+ f: func(c context.Context) []interface{} {
+ err := f.TxCommitter.Rollback()
+ return []interface{}{err}
+ },
+ }
+ res := f.root(context.Background(), inv)
+ return f.convertError(res[0])
+}
+
+func (f *filterOrmDecorator) RollbackUnlessCommit() error {
+ inv := &Invocation{
+ Method: "RollbackUnlessCommit",
+ Args: []interface{}{},
+ InsideTx: f.insideTx,
+ TxStartTime: f.txStartTime,
+ TxName: f.txName,
+ f: func(c context.Context) []interface{} {
+ err := f.TxCommitter.RollbackUnlessCommit()
+ return []interface{}{err}
+ },
+ }
+ res := f.root(context.Background(), inv)
+ return f.convertError(res[0])
+}
+
+func (*filterOrmDecorator) convertError(v interface{}) error {
+ if v == nil {
+ return nil
+ }
+ return v.(error)
+}
+
+func getTxNameFromCtx(ctx context.Context) string {
+ txName := ""
+ if n, ok := ctx.Value(TxNameKey).(string); ok {
+ txName = n
+ }
+ return txName
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/hints/db_hints.go b/src/vendor/github.com/beego/beego/v2/client/orm/hints/db_hints.go
new file mode 100644
index 000000000..6578a5955
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/hints/db_hints.go
@@ -0,0 +1,103 @@
+// Copyright 2020 beego-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hints
+
+import (
+ "github.com/beego/beego/v2/core/utils"
+)
+
+const (
+ // query level
+ KeyForceIndex = iota
+ KeyUseIndex
+ KeyIgnoreIndex
+ KeyForUpdate
+ KeyLimit
+ KeyOffset
+ KeyOrderBy
+ KeyRelDepth
+)
+
+type Hint struct {
+ key interface{}
+ value interface{}
+}
+
+var _ utils.KV = new(Hint)
+
+// GetKey return key
+func (s *Hint) GetKey() interface{} {
+ return s.key
+}
+
+// GetValue return value
+func (s *Hint) GetValue() interface{} {
+ return s.value
+}
+
+var _ utils.KV = new(Hint)
+
+// ForceIndex return a hint about ForceIndex
+func ForceIndex(indexes ...string) *Hint {
+ return NewHint(KeyForceIndex, indexes)
+}
+
+// UseIndex return a hint about UseIndex
+func UseIndex(indexes ...string) *Hint {
+ return NewHint(KeyUseIndex, indexes)
+}
+
+// IgnoreIndex return a hint about IgnoreIndex
+func IgnoreIndex(indexes ...string) *Hint {
+ return NewHint(KeyIgnoreIndex, indexes)
+}
+
+// ForUpdate return a hint about ForUpdate
+func ForUpdate() *Hint {
+ return NewHint(KeyForUpdate, true)
+}
+
+// DefaultRelDepth return a hint about DefaultRelDepth
+func DefaultRelDepth() *Hint {
+ return NewHint(KeyRelDepth, true)
+}
+
+// RelDepth return a hint about RelDepth
+func RelDepth(d int) *Hint {
+ return NewHint(KeyRelDepth, d)
+}
+
+// Limit return a hint about Limit
+func Limit(d int64) *Hint {
+ return NewHint(KeyLimit, d)
+}
+
+// Offset return a hint about Offset
+func Offset(d int64) *Hint {
+ return NewHint(KeyOffset, d)
+}
+
+// OrderBy return a hint about OrderBy
+func OrderBy(s string) *Hint {
+ return NewHint(KeyOrderBy, s)
+}
+
+// NewHint return a hint
+func NewHint(key interface{}, value interface{}) *Hint {
+ return &Hint{
+ key: key,
+ value: value,
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/invocation.go b/src/vendor/github.com/beego/beego/v2/client/orm/invocation.go
new file mode 100644
index 000000000..9e7c1974c
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/invocation.go
@@ -0,0 +1,58 @@
+// Copyright 2020 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "context"
+ "time"
+)
+
+// Invocation represents an "Orm" invocation
+type Invocation struct {
+ Method string
+ // Md may be nil in some cases. It depends on method
+ Md interface{}
+ // the args are all arguments except context.Context
+ Args []interface{}
+
+ mi *modelInfo
+ // f is the Orm operation
+ f func(ctx context.Context) []interface{}
+
+ // insideTx indicates whether this is inside a transaction
+ InsideTx bool
+ TxStartTime time.Time
+ TxName string
+}
+
+func (inv *Invocation) GetTableName() string {
+ if inv.mi != nil {
+ return inv.mi.table
+ }
+ return ""
+}
+
+func (inv *Invocation) execute(ctx context.Context) []interface{} {
+ return inv.f(ctx)
+}
+
+// GetPkFieldName return the primary key of this table
+// if not found, "" is returned
+func (inv *Invocation) GetPkFieldName() string {
+ if inv.mi.fields.pk != nil {
+ return inv.mi.fields.pk.name
+ }
+ return ""
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/models.go b/src/vendor/github.com/beego/beego/v2/client/orm/models.go
new file mode 100644
index 000000000..94630ba52
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/models.go
@@ -0,0 +1,573 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "runtime/debug"
+ "strings"
+ "sync"
+)
+
+const (
+ odCascade = "cascade"
+ odSetNULL = "set_null"
+ odSetDefault = "set_default"
+ odDoNothing = "do_nothing"
+ defaultStructTagName = "orm"
+ defaultStructTagDelim = ";"
+)
+
+var defaultModelCache = NewModelCacheHandler()
+
+// model info collection
+type modelCache struct {
+ sync.RWMutex // only used outsite for bootStrap
+ orders []string
+ cache map[string]*modelInfo
+ cacheByFullName map[string]*modelInfo
+ done bool
+}
+
+// NewModelCacheHandler generator of modelCache
+func NewModelCacheHandler() *modelCache {
+ return &modelCache{
+ cache: make(map[string]*modelInfo),
+ cacheByFullName: make(map[string]*modelInfo),
+ }
+}
+
+// get all model info
+func (mc *modelCache) all() map[string]*modelInfo {
+ m := make(map[string]*modelInfo, len(mc.cache))
+ for k, v := range mc.cache {
+ m[k] = v
+ }
+ return m
+}
+
+// get ordered model info
+func (mc *modelCache) allOrdered() []*modelInfo {
+ m := make([]*modelInfo, 0, len(mc.orders))
+ for _, table := range mc.orders {
+ m = append(m, mc.cache[table])
+ }
+ return m
+}
+
+// get model info by table name
+func (mc *modelCache) get(table string) (mi *modelInfo, ok bool) {
+ mi, ok = mc.cache[table]
+ return
+}
+
+// get model info by full name
+func (mc *modelCache) getByFullName(name string) (mi *modelInfo, ok bool) {
+ mi, ok = mc.cacheByFullName[name]
+ return
+}
+
+func (mc *modelCache) getByMd(md interface{}) (*modelInfo, bool) {
+ val := reflect.ValueOf(md)
+ ind := reflect.Indirect(val)
+ typ := ind.Type()
+ name := getFullName(typ)
+ return mc.getByFullName(name)
+}
+
+// set model info to collection
+func (mc *modelCache) set(table string, mi *modelInfo) *modelInfo {
+ mii := mc.cache[table]
+ mc.cache[table] = mi
+ mc.cacheByFullName[mi.fullName] = mi
+ if mii == nil {
+ mc.orders = append(mc.orders, table)
+ }
+ return mii
+}
+
+// clean all model info.
+func (mc *modelCache) clean() {
+ mc.Lock()
+ defer mc.Unlock()
+
+ mc.orders = make([]string, 0)
+ mc.cache = make(map[string]*modelInfo)
+ mc.cacheByFullName = make(map[string]*modelInfo)
+ mc.done = false
+}
+
+// bootstrap bootstrap for models
+func (mc *modelCache) bootstrap() {
+ mc.Lock()
+ defer mc.Unlock()
+ if mc.done {
+ return
+ }
+ var (
+ err error
+ models map[string]*modelInfo
+ )
+ if dataBaseCache.getDefault() == nil {
+ err = fmt.Errorf("must have one register DataBase alias named `default`")
+ goto end
+ }
+
+ // set rel and reverse model
+ // RelManyToMany set the relTable
+ models = mc.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.columns {
+ if fi.rel || fi.reverse {
+ elm := fi.addrValue.Type().Elem()
+ if fi.fieldType == RelReverseMany || fi.fieldType == RelManyToMany {
+ elm = elm.Elem()
+ }
+ // check the rel or reverse model already register
+ name := getFullName(elm)
+ mii, ok := mc.getByFullName(name)
+ if !ok || mii.pkg != elm.PkgPath() {
+ err = fmt.Errorf("can not find rel in field `%s`, `%s` may be miss register", fi.fullName, elm.String())
+ goto end
+ }
+ fi.relModelInfo = mii
+
+ switch fi.fieldType {
+ case RelManyToMany:
+ if fi.relThrough != "" {
+ if i := strings.LastIndex(fi.relThrough, "."); i != -1 && len(fi.relThrough) > (i+1) {
+ pn := fi.relThrough[:i]
+ rmi, ok := mc.getByFullName(fi.relThrough)
+ if !ok || pn != rmi.pkg {
+ err = fmt.Errorf("field `%s` wrong rel_through value `%s` cannot find table", fi.fullName, fi.relThrough)
+ goto end
+ }
+ fi.relThroughModelInfo = rmi
+ fi.relTable = rmi.table
+ } else {
+ err = fmt.Errorf("field `%s` wrong rel_through value `%s`", fi.fullName, fi.relThrough)
+ goto end
+ }
+ } else {
+ i := newM2MModelInfo(mi, mii)
+ if fi.relTable != "" {
+ i.table = fi.relTable
+ }
+ if v := mc.set(i.table, i); v != nil {
+ err = fmt.Errorf("the rel table name `%s` already registered, cannot be use, please change one", fi.relTable)
+ goto end
+ }
+ fi.relTable = i.table
+ fi.relThroughModelInfo = i
+ }
+
+ fi.relThroughModelInfo.isThrough = true
+ }
+ }
+ }
+ }
+
+ // check the rel filed while the relModelInfo also has filed point to current model
+ // if not exist, add a new field to the relModelInfo
+ models = mc.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.fieldsRel {
+ switch fi.fieldType {
+ case RelForeignKey, RelOneToOne, RelManyToMany:
+ inModel := false
+ for _, ffi := range fi.relModelInfo.fields.fieldsReverse {
+ if ffi.relModelInfo == mi {
+ inModel = true
+ break
+ }
+ }
+ if !inModel {
+ rmi := fi.relModelInfo
+ ffi := new(fieldInfo)
+ ffi.name = mi.name
+ ffi.column = ffi.name
+ ffi.fullName = rmi.fullName + "." + ffi.name
+ ffi.reverse = true
+ ffi.relModelInfo = mi
+ ffi.mi = rmi
+ if fi.fieldType == RelOneToOne {
+ ffi.fieldType = RelReverseOne
+ } else {
+ ffi.fieldType = RelReverseMany
+ }
+ if !rmi.fields.Add(ffi) {
+ added := false
+ for cnt := 0; cnt < 5; cnt++ {
+ ffi.name = fmt.Sprintf("%s%d", mi.name, cnt)
+ ffi.column = ffi.name
+ ffi.fullName = rmi.fullName + "." + ffi.name
+ if added = rmi.fields.Add(ffi); added {
+ break
+ }
+ }
+ if !added {
+ panic(fmt.Errorf("cannot generate auto reverse field info `%s` to `%s`", fi.fullName, ffi.fullName))
+ }
+ }
+ }
+ }
+ }
+ }
+
+ models = mc.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.fieldsRel {
+ switch fi.fieldType {
+ case RelManyToMany:
+ for _, ffi := range fi.relThroughModelInfo.fields.fieldsRel {
+ switch ffi.fieldType {
+ case RelOneToOne, RelForeignKey:
+ if ffi.relModelInfo == fi.relModelInfo {
+ fi.reverseFieldInfoTwo = ffi
+ }
+ if ffi.relModelInfo == mi {
+ fi.reverseField = ffi.name
+ fi.reverseFieldInfo = ffi
+ }
+ }
+ }
+ if fi.reverseFieldInfoTwo == nil {
+ err = fmt.Errorf("can not find m2m field for m2m model `%s`, ensure your m2m model defined correct",
+ fi.relThroughModelInfo.fullName)
+ goto end
+ }
+ }
+ }
+ }
+
+ models = mc.all()
+ for _, mi := range models {
+ for _, fi := range mi.fields.fieldsReverse {
+ switch fi.fieldType {
+ case RelReverseOne:
+ found := false
+ mForA:
+ for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelOneToOne] {
+ if ffi.relModelInfo == mi {
+ found = true
+ fi.reverseField = ffi.name
+ fi.reverseFieldInfo = ffi
+
+ ffi.reverseField = fi.name
+ ffi.reverseFieldInfo = fi
+ break mForA
+ }
+ }
+ if !found {
+ err = fmt.Errorf("reverse field `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
+ goto end
+ }
+ case RelReverseMany:
+ found := false
+ mForB:
+ for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelForeignKey] {
+ if ffi.relModelInfo == mi {
+ found = true
+ fi.reverseField = ffi.name
+ fi.reverseFieldInfo = ffi
+
+ ffi.reverseField = fi.name
+ ffi.reverseFieldInfo = fi
+
+ break mForB
+ }
+ }
+ if !found {
+ mForC:
+ for _, ffi := range fi.relModelInfo.fields.fieldsByType[RelManyToMany] {
+ conditions := fi.relThrough != "" && fi.relThrough == ffi.relThrough ||
+ fi.relTable != "" && fi.relTable == ffi.relTable ||
+ fi.relThrough == "" && fi.relTable == ""
+ if ffi.relModelInfo == mi && conditions {
+ found = true
+
+ fi.reverseField = ffi.reverseFieldInfoTwo.name
+ fi.reverseFieldInfo = ffi.reverseFieldInfoTwo
+ fi.relThroughModelInfo = ffi.relThroughModelInfo
+ fi.reverseFieldInfoTwo = ffi.reverseFieldInfo
+ fi.reverseFieldInfoM2M = ffi
+ ffi.reverseFieldInfoM2M = fi
+
+ break mForC
+ }
+ }
+ }
+ if !found {
+ err = fmt.Errorf("reverse field for `%s` not found in model `%s`", fi.fullName, fi.relModelInfo.fullName)
+ goto end
+ }
+ }
+ }
+ }
+
+end:
+ if err != nil {
+ fmt.Println(err)
+ debug.PrintStack()
+ }
+ mc.done = true
+}
+
+// register register models to model cache
+func (mc *modelCache) register(prefixOrSuffixStr string, prefixOrSuffix bool, models ...interface{}) (err error) {
+ for _, model := range models {
+ val := reflect.ValueOf(model)
+ typ := reflect.Indirect(val).Type()
+
+ if val.Kind() != reflect.Ptr {
+ err = fmt.Errorf(" cannot use non-ptr model struct `%s`", getFullName(typ))
+ return
+ }
+ // For this case:
+ // u := &User{}
+ // registerModel(&u)
+ if typ.Kind() == reflect.Ptr {
+ err = fmt.Errorf(" only allow ptr model struct, it looks you use two reference to the struct `%s`", typ)
+ return
+ }
+ if val.Elem().Kind() == reflect.Slice {
+ val = reflect.New(val.Elem().Type().Elem())
+ }
+ table := getTableName(val)
+
+ if prefixOrSuffixStr != "" {
+ if prefixOrSuffix {
+ table = prefixOrSuffixStr + table
+ } else {
+ table = table + prefixOrSuffixStr
+ }
+ }
+
+ // models's fullname is pkgpath + struct name
+ name := getFullName(typ)
+ if _, ok := mc.getByFullName(name); ok {
+ err = fmt.Errorf(" model `%s` repeat register, must be unique\n", name)
+ return
+ }
+
+ if _, ok := mc.get(table); ok {
+ return nil
+ }
+
+ mi := newModelInfo(val)
+ if mi.fields.pk == nil {
+ outFor:
+ for _, fi := range mi.fields.fieldsDB {
+ if strings.ToLower(fi.name) == "id" {
+ switch fi.addrValue.Elem().Kind() {
+ case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64:
+ fi.auto = true
+ fi.pk = true
+ mi.fields.pk = fi
+ break outFor
+ }
+ }
+ }
+ }
+
+ mi.table = table
+ mi.pkg = typ.PkgPath()
+ mi.model = model
+ mi.manual = true
+
+ mc.set(table, mi)
+ }
+ return
+}
+
+// getDbDropSQL get database scheme drop sql queries
+func (mc *modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
+ if len(mc.cache) == 0 {
+ err = errors.New("no Model found, need register your model")
+ return
+ }
+
+ Q := al.DbBaser.TableQuote()
+
+ for _, mi := range mc.allOrdered() {
+ queries = append(queries, fmt.Sprintf(`DROP TABLE IF EXISTS %s%s%s`, Q, mi.table, Q))
+ }
+ return queries, nil
+}
+
+// getDbCreateSQL get database scheme creation sql queries
+func (mc *modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes map[string][]dbIndex, err error) {
+ if len(mc.cache) == 0 {
+ err = errors.New("no Model found, need register your model")
+ return
+ }
+
+ Q := al.DbBaser.TableQuote()
+ T := al.DbBaser.DbTypes()
+ sep := fmt.Sprintf("%s, %s", Q, Q)
+
+ tableIndexes = make(map[string][]dbIndex)
+
+ for _, mi := range mc.allOrdered() {
+ sql := fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
+ sql += fmt.Sprintf("-- Table Structure for `%s`\n", mi.fullName)
+ sql += fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
+
+ sql += fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s%s%s (\n", Q, mi.table, Q)
+
+ columns := make([]string, 0, len(mi.fields.fieldsDB))
+
+ sqlIndexes := [][]string{}
+ var commentIndexes []int // store comment indexes for postgres
+
+ for i, fi := range mi.fields.fieldsDB {
+ column := fmt.Sprintf(" %s%s%s ", Q, fi.column, Q)
+ col := getColumnTyp(al, fi)
+
+ if fi.auto {
+ switch al.Driver {
+ case DRSqlite, DRPostgres:
+ column += T["auto"]
+ default:
+ column += col + " " + T["auto"]
+ }
+ } else if fi.pk {
+ column += col + " " + T["pk"]
+ } else {
+ column += col
+
+ if !fi.null {
+ column += " " + "NOT NULL"
+ }
+
+ // if fi.initial.String() != "" {
+ // column += " DEFAULT " + fi.initial.String()
+ // }
+
+ // Append attribute DEFAULT
+ column += getColumnDefault(fi)
+
+ if fi.unique {
+ column += " " + "UNIQUE"
+ }
+
+ if fi.index {
+ sqlIndexes = append(sqlIndexes, []string{fi.column})
+ }
+ }
+
+ if strings.Contains(column, "%COL%") {
+ column = strings.Replace(column, "%COL%", fi.column, -1)
+ }
+
+ if fi.description != "" && al.Driver != DRSqlite {
+ if al.Driver == DRPostgres {
+ commentIndexes = append(commentIndexes, i)
+ } else {
+ column += " " + fmt.Sprintf("COMMENT '%s'", fi.description)
+ }
+ }
+
+ columns = append(columns, column)
+ }
+
+ if mi.model != nil {
+ allnames := getTableUnique(mi.addrField)
+ if !mi.manual && len(mi.uniques) > 0 {
+ allnames = append(allnames, mi.uniques)
+ }
+ for _, names := range allnames {
+ cols := make([]string, 0, len(names))
+ for _, name := range names {
+ if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
+ cols = append(cols, fi.column)
+ } else {
+ panic(fmt.Errorf("cannot found column `%s` when parse UNIQUE in `%s.TableUnique`", name, mi.fullName))
+ }
+ }
+ column := fmt.Sprintf(" UNIQUE (%s%s%s)", Q, strings.Join(cols, sep), Q)
+ columns = append(columns, column)
+ }
+ }
+
+ sql += strings.Join(columns, ",\n")
+ sql += "\n)"
+
+ if al.Driver == DRMySQL {
+ var engine string
+ if mi.model != nil {
+ engine = getTableEngine(mi.addrField)
+ }
+ if engine == "" {
+ engine = al.Engine
+ }
+ sql += " ENGINE=" + engine
+ }
+
+ sql += ";"
+ if al.Driver == DRPostgres && len(commentIndexes) > 0 {
+ // append comments for postgres only
+ for _, index := range commentIndexes {
+ sql += fmt.Sprintf("\nCOMMENT ON COLUMN %s%s%s.%s%s%s is '%s';",
+ Q,
+ mi.table,
+ Q,
+ Q,
+ mi.fields.fieldsDB[index].column,
+ Q,
+ mi.fields.fieldsDB[index].description)
+ }
+ }
+ queries = append(queries, sql)
+
+ if mi.model != nil {
+ for _, names := range getTableIndex(mi.addrField) {
+ cols := make([]string, 0, len(names))
+ for _, name := range names {
+ if fi, ok := mi.fields.GetByAny(name); ok && fi.dbcol {
+ cols = append(cols, fi.column)
+ } else {
+ panic(fmt.Errorf("cannot found column `%s` when parse INDEX in `%s.TableIndex`", name, mi.fullName))
+ }
+ }
+ sqlIndexes = append(sqlIndexes, cols)
+ }
+ }
+
+ for _, names := range sqlIndexes {
+ name := mi.table + "_" + strings.Join(names, "_")
+ cols := strings.Join(names, sep)
+ sql := fmt.Sprintf("CREATE INDEX %s%s%s ON %s%s%s (%s%s%s);", Q, name, Q, Q, mi.table, Q, Q, cols, Q)
+
+ index := dbIndex{}
+ index.Table = mi.table
+ index.Name = name
+ index.SQL = sql
+
+ tableIndexes[mi.table] = append(tableIndexes[mi.table], index)
+ }
+
+ }
+
+ return
+}
+
+// ResetModelCache Clean model cache. Then you can re-RegisterModel.
+// Common use this api for test case.
+func ResetModelCache() {
+ defaultModelCache.clean()
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/models_boot.go b/src/vendor/github.com/beego/beego/v2/client/orm/models_boot.go
new file mode 100644
index 000000000..6916f3ba9
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/models_boot.go
@@ -0,0 +1,40 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+// RegisterModel register models
+func RegisterModel(models ...interface{}) {
+ RegisterModelWithPrefix("", models...)
+}
+
+// RegisterModelWithPrefix register models with a prefix
+func RegisterModelWithPrefix(prefix string, models ...interface{}) {
+ if err := defaultModelCache.register(prefix, true, models...); err != nil {
+ panic(err)
+ }
+}
+
+// RegisterModelWithSuffix register models with a suffix
+func RegisterModelWithSuffix(suffix string, models ...interface{}) {
+ if err := defaultModelCache.register(suffix, false, models...); err != nil {
+ panic(err)
+ }
+}
+
+// BootStrap bootstrap models.
+// make all model parsed and can not add more models
+func BootStrap() {
+ defaultModelCache.bootstrap()
+}
diff --git a/src/vendor/github.com/beego/beego/orm/models_fields.go b/src/vendor/github.com/beego/beego/v2/client/orm/models_fields.go
similarity index 100%
rename from src/vendor/github.com/beego/beego/orm/models_fields.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/models_fields.go
diff --git a/src/vendor/github.com/beego/beego/orm/models_info_f.go b/src/vendor/github.com/beego/beego/v2/client/orm/models_info_f.go
similarity index 96%
rename from src/vendor/github.com/beego/beego/orm/models_info_f.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/models_info_f.go
index 970bbbfa6..6a9e7a99f 100644
--- a/src/vendor/github.com/beego/beego/orm/models_info_f.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/models_info_f.go
@@ -101,29 +101,30 @@ func newFields() *fields {
// single field info
type fieldInfo struct {
- mi *modelInfo
- fieldIndex []int
- fieldType int
dbcol bool // table column fk and onetoone
inModel bool
- name string
- fullName string
- column string
- addrValue reflect.Value
- sf reflect.StructField
auto bool
pk bool
null bool
index bool
unique bool
- colDefault bool // whether has default tag
- initial StrTo // store the default value
- size int
+ colDefault bool // whether has default tag
toText bool
autoNow bool
autoNowAdd bool
rel bool // if type equal to RelForeignKey, RelOneToOne, RelManyToMany then true
reverse bool
+ isFielder bool // implement Fielder interface
+ mi *modelInfo
+ fieldIndex []int
+ fieldType int
+ name string
+ fullName string
+ column string
+ addrValue reflect.Value
+ sf reflect.StructField
+ initial StrTo // store the default value
+ size int
reverseField string
reverseFieldInfo *fieldInfo
reverseFieldInfoTwo *fieldInfo
@@ -134,9 +135,9 @@ type fieldInfo struct {
relModelInfo *modelInfo
digits int
decimals int
- isFielder bool // implement Fielder interface
onDelete string
description string
+ timePrecision *int
}
// new field info
@@ -177,7 +178,7 @@ func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField, mN
decimals := tags["decimals"]
size := tags["size"]
onDelete := tags["on_delete"]
-
+ precision := tags["precision"]
initial.Clear()
if v, ok := tags["default"]; ok {
initial.Set(v)
@@ -193,7 +194,7 @@ checkType:
}
fieldType = f.FieldType()
if fieldType&IsRelField > 0 {
- err = fmt.Errorf("unsupport type custom field, please refer to https://github.com/beego/beego/blob/master/orm/models_fields.go#L24-L42")
+ err = fmt.Errorf("unsupport type custom field, please refer to https://github.com/beego/beego/v2/blob/master/orm/models_fields.go#L24-L42")
goto end
}
default:
@@ -377,6 +378,17 @@ checkType:
fi.index = false
fi.unique = false
case TypeTimeField, TypeDateField, TypeDateTimeField:
+ if fieldType == TypeDateTimeField {
+ if precision != "" {
+ v, e := StrTo(precision).Int()
+ if e != nil {
+ err = fmt.Errorf("convert %s to int error:%v", precision, e)
+ } else {
+ fi.timePrecision = &v
+ }
+ }
+ }
+
if attrs["auto_now"] {
fi.autoNow = true
} else if attrs["auto_now_add"] {
diff --git a/src/vendor/github.com/beego/beego/orm/models_info_m.go b/src/vendor/github.com/beego/beego/v2/client/orm/models_info_m.go
similarity index 97%
rename from src/vendor/github.com/beego/beego/orm/models_info_m.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/models_info_m.go
index a4d733b6c..b94480ca0 100644
--- a/src/vendor/github.com/beego/beego/orm/models_info_m.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/models_info_m.go
@@ -22,16 +22,16 @@ import (
// single model info
type modelInfo struct {
+ manual bool
+ isThrough bool
pkg string
name string
fullName string
table string
model interface{}
fields *fields
- manual bool
- addrField reflect.Value //store the original struct value
+ addrField reflect.Value // store the original struct value
uniques []string
- isThrough bool
}
// new model info
@@ -74,7 +74,7 @@ func addModelFields(mi *modelInfo, ind reflect.Value, mName string, index []int)
} else if err != nil {
break
}
- //record current field index
+ // record current field index
fi.fieldIndex = append(fi.fieldIndex, index...)
fi.fieldIndex = append(fi.fieldIndex, i)
fi.mi = mi
diff --git a/src/vendor/github.com/beego/beego/orm/models_utils.go b/src/vendor/github.com/beego/beego/v2/client/orm/models_utils.go
similarity index 93%
rename from src/vendor/github.com/beego/beego/orm/models_utils.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/models_utils.go
index 71127a6ba..b2e5760ee 100644
--- a/src/vendor/github.com/beego/beego/orm/models_utils.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/models_utils.go
@@ -45,6 +45,7 @@ var supportTag = map[string]int{
"on_delete": 2,
"type": 2,
"description": 2,
+ "precision": 2,
}
// get reflect.Type name with package path.
@@ -106,6 +107,21 @@ func getTableUnique(val reflect.Value) [][]string {
return nil
}
+// get whether the table needs to be created for the database alias
+func isApplicableTableForDB(val reflect.Value, db string) bool {
+ if !val.IsValid() {
+ return true
+ }
+ fun := val.MethodByName("IsApplicableTableForDB")
+ if fun.IsValid() {
+ vals := fun.Call([]reflect.Value{reflect.ValueOf(db)})
+ if len(vals) > 0 && vals[0].Kind() == reflect.Bool {
+ return vals[0].Bool()
+ }
+ }
+ return true
+}
+
// get snaked column name
func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string {
column := col
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/orm.go b/src/vendor/github.com/beego/beego/v2/client/orm/orm.go
new file mode 100644
index 000000000..05614beb2
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/orm.go
@@ -0,0 +1,661 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build go1.8
+// +build go1.8
+
+// Package orm provide ORM for MySQL/PostgreSQL/sqlite
+// Simple Usage
+//
+// package main
+//
+// import (
+// "fmt"
+// "github.com/beego/beego/v2/client/orm"
+// _ "github.com/go-sql-driver/mysql" // import your used driver
+// )
+//
+// // Model Struct
+// type User struct {
+// Id int `orm:"auto"`
+// Name string `orm:"size(100)"`
+// }
+//
+// func init() {
+// orm.RegisterDataBase("default", "mysql", "root:root@/my_db?charset=utf8", 30)
+// }
+//
+// func main() {
+// o := orm.NewOrm()
+// user := User{Name: "slene"}
+// // insert
+// id, err := o.Insert(&user)
+// // update
+// user.Name = "astaxie"
+// num, err := o.Update(&user)
+// // read one
+// u := User{Id: user.Id}
+// err = o.Read(&u)
+// // delete
+// num, err = o.Delete(&u)
+// }
+//
+// more docs: http://beego.vip/docs/mvc/model/overview.md
+package orm
+
+import (
+ "context"
+ "database/sql"
+ "errors"
+ "fmt"
+ "os"
+ "reflect"
+ "time"
+
+ "github.com/beego/beego/v2/client/orm/clauses/order_clause"
+ "github.com/beego/beego/v2/client/orm/hints"
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/core/utils"
+)
+
+// DebugQueries define the debug
+const (
+ DebugQueries = iota
+)
+
+// Define common vars
+var (
+ Debug = false
+ DebugLog = NewLog(os.Stdout)
+ DefaultRowsLimit = -1
+ DefaultRelsDepth = 2
+ DefaultTimeLoc = time.Local
+ ErrTxDone = errors.New(" transaction already done")
+ ErrMultiRows = errors.New(" return multi rows")
+ ErrNoRows = errors.New(" no row found")
+ ErrStmtClosed = errors.New(" stmt already closed")
+ ErrArgs = errors.New(" args error may be empty")
+ ErrNotImplement = errors.New("have not implement")
+
+ ErrLastInsertIdUnavailable = errors.New(" last insert id is unavailable")
+)
+
+// Params stores the Params
+type Params map[string]interface{}
+
+// ParamsList stores paramslist
+type ParamsList []interface{}
+
+type ormBase struct {
+ alias *alias
+ db dbQuerier
+}
+
+var (
+ _ DQL = new(ormBase)
+ _ DML = new(ormBase)
+ _ DriverGetter = new(ormBase)
+)
+
+// get model info and model reflect value
+func (*ormBase) getMi(md interface{}) (mi *modelInfo) {
+ val := reflect.ValueOf(md)
+ ind := reflect.Indirect(val)
+ typ := ind.Type()
+ mi = getTypeMi(typ)
+ return
+}
+
+// get need ptr model info and model reflect value
+func (*ormBase) getPtrMiInd(md interface{}) (mi *modelInfo, ind reflect.Value) {
+ val := reflect.ValueOf(md)
+ ind = reflect.Indirect(val)
+ typ := ind.Type()
+ if val.Kind() != reflect.Ptr {
+ panic(fmt.Errorf(" cannot use non-ptr model struct `%s`", getFullName(typ)))
+ }
+ mi = getTypeMi(typ)
+ return
+}
+
+func getTypeMi(mdTyp reflect.Type) *modelInfo {
+ name := getFullName(mdTyp)
+ if mi, ok := defaultModelCache.getByFullName(name); ok {
+ return mi
+ }
+ panic(fmt.Errorf(" table: `%s` not found, make sure it was registered with `RegisterModel()`", name))
+}
+
+// get field info from model info by given field name
+func (*ormBase) getFieldInfo(mi *modelInfo, name string) *fieldInfo {
+ fi, ok := mi.fields.GetByAny(name)
+ if !ok {
+ panic(fmt.Errorf(" cannot find field `%s` for model `%s`", name, mi.fullName))
+ }
+ return fi
+}
+
+// read data to model
+func (o *ormBase) Read(md interface{}, cols ...string) error {
+ return o.ReadWithCtx(context.Background(), md, cols...)
+}
+
+func (o *ormBase) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ mi, ind := o.getPtrMiInd(md)
+ return o.alias.DbBaser.Read(ctx, o.db, mi, ind, o.alias.TZ, cols, false)
+}
+
+// read data to model, like Read(), but use "SELECT FOR UPDATE" form
+func (o *ormBase) ReadForUpdate(md interface{}, cols ...string) error {
+ return o.ReadForUpdateWithCtx(context.Background(), md, cols...)
+}
+
+func (o *ormBase) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
+ mi, ind := o.getPtrMiInd(md)
+ return o.alias.DbBaser.Read(ctx, o.db, mi, ind, o.alias.TZ, cols, true)
+}
+
+// Try to read a row from the database, or insert one if it doesn't exist
+func (o *ormBase) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ return o.ReadOrCreateWithCtx(context.Background(), md, col1, cols...)
+}
+
+func (o *ormBase) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
+ cols = append([]string{col1}, cols...)
+ mi, ind := o.getPtrMiInd(md)
+ err := o.alias.DbBaser.Read(ctx, o.db, mi, ind, o.alias.TZ, cols, false)
+ if err == ErrNoRows {
+ // Create
+ id, err := o.InsertWithCtx(ctx, md)
+ return err == nil, id, err
+ }
+
+ id, vid := int64(0), ind.FieldByIndex(mi.fields.pk.fieldIndex)
+ if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
+ id = int64(vid.Uint())
+ } else if mi.fields.pk.rel {
+ return o.ReadOrCreateWithCtx(ctx, vid.Interface(), mi.fields.pk.relModelInfo.fields.pk.name)
+ } else {
+ id = vid.Int()
+ }
+
+ return false, id, err
+}
+
+// insert model data to database
+func (o *ormBase) Insert(md interface{}) (int64, error) {
+ return o.InsertWithCtx(context.Background(), md)
+}
+
+func (o *ormBase) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
+ mi, ind := o.getPtrMiInd(md)
+ id, err := o.alias.DbBaser.Insert(ctx, o.db, mi, ind, o.alias.TZ)
+ if err != nil {
+ return id, err
+ }
+
+ o.setPk(mi, ind, id)
+
+ return id, nil
+}
+
+// set auto pk field
+func (*ormBase) setPk(mi *modelInfo, ind reflect.Value, id int64) {
+ if mi.fields.pk.auto {
+ if mi.fields.pk.fieldType&IsPositiveIntegerField > 0 {
+ ind.FieldByIndex(mi.fields.pk.fieldIndex).SetUint(uint64(id))
+ } else {
+ ind.FieldByIndex(mi.fields.pk.fieldIndex).SetInt(id)
+ }
+ }
+}
+
+// insert some models to database
+func (o *ormBase) InsertMulti(bulk int, mds interface{}) (int64, error) {
+ return o.InsertMultiWithCtx(context.Background(), bulk, mds)
+}
+
+func (o *ormBase) InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) {
+ var cnt int64
+
+ sind := reflect.Indirect(reflect.ValueOf(mds))
+
+ switch sind.Kind() {
+ case reflect.Array, reflect.Slice:
+ if sind.Len() == 0 {
+ return cnt, ErrArgs
+ }
+ default:
+ return cnt, ErrArgs
+ }
+
+ if bulk <= 1 {
+ for i := 0; i < sind.Len(); i++ {
+ ind := reflect.Indirect(sind.Index(i))
+ mi := o.getMi(ind.Interface())
+ id, err := o.alias.DbBaser.Insert(ctx, o.db, mi, ind, o.alias.TZ)
+ if err != nil {
+ return cnt, err
+ }
+
+ o.setPk(mi, ind, id)
+
+ cnt++
+ }
+ } else {
+ mi := o.getMi(sind.Index(0).Interface())
+ return o.alias.DbBaser.InsertMulti(ctx, o.db, mi, sind, bulk, o.alias.TZ)
+ }
+ return cnt, nil
+}
+
+// InsertOrUpdate data to database
+func (o *ormBase) InsertOrUpdate(md interface{}, colConflictAndArgs ...string) (int64, error) {
+ return o.InsertOrUpdateWithCtx(context.Background(), md, colConflictAndArgs...)
+}
+
+func (o *ormBase) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
+ mi, ind := o.getPtrMiInd(md)
+ id, err := o.alias.DbBaser.InsertOrUpdate(ctx, o.db, mi, ind, o.alias, colConflitAndArgs...)
+ if err != nil {
+ return id, err
+ }
+
+ o.setPk(mi, ind, id)
+
+ return id, nil
+}
+
+// update model to database.
+// cols set the columns those want to update.
+func (o *ormBase) Update(md interface{}, cols ...string) (int64, error) {
+ return o.UpdateWithCtx(context.Background(), md, cols...)
+}
+
+func (o *ormBase) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ mi, ind := o.getPtrMiInd(md)
+ return o.alias.DbBaser.Update(ctx, o.db, mi, ind, o.alias.TZ, cols)
+}
+
+// delete model in database
+// cols shows the delete conditions values read from. default is pk
+func (o *ormBase) Delete(md interface{}, cols ...string) (int64, error) {
+ return o.DeleteWithCtx(context.Background(), md, cols...)
+}
+
+func (o *ormBase) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
+ mi, ind := o.getPtrMiInd(md)
+ num, err := o.alias.DbBaser.Delete(ctx, o.db, mi, ind, o.alias.TZ, cols)
+ return num, err
+}
+
+// create a models to models queryer
+func (o *ormBase) QueryM2M(md interface{}, name string) QueryM2Mer {
+ mi, ind := o.getPtrMiInd(md)
+ fi := o.getFieldInfo(mi, name)
+
+ switch {
+ case fi.fieldType == RelManyToMany:
+ case fi.fieldType == RelReverseMany && fi.reverseFieldInfo.mi.isThrough:
+ default:
+ panic(fmt.Errorf(" model `%s` . name `%s` is not a m2m field", fi.name, mi.fullName))
+ }
+
+ return newQueryM2M(md, o, mi, fi, ind)
+}
+
+// NOTE: this method is deprecated, context parameter will not take effect.
+func (o *ormBase) QueryM2MWithCtx(_ context.Context, md interface{}, name string) QueryM2Mer {
+ logs.Warn("QueryM2MWithCtx is DEPRECATED. Use methods with `WithCtx` suffix on QueryM2M as replacement please.")
+ return o.QueryM2M(md, name)
+}
+
+// load related models to md model.
+// args are limit, offset int and order string.
+//
+// example:
+// orm.LoadRelated(post,"Tags")
+// for _,tag := range post.Tags{...}
+//
+// make sure the relation is defined in model struct tags.
+func (o *ormBase) LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) {
+ return o.LoadRelatedWithCtx(context.Background(), md, name, args...)
+}
+
+func (o *ormBase) LoadRelatedWithCtx(_ context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
+ _, fi, ind, qs := o.queryRelated(md, name)
+
+ var relDepth int
+ var limit, offset int64
+ var order string
+
+ kvs := utils.NewKVs(args...)
+ kvs.IfContains(hints.KeyRelDepth, func(value interface{}) {
+ if v, ok := value.(bool); ok {
+ if v {
+ relDepth = DefaultRelsDepth
+ }
+ } else if v, ok := value.(int); ok {
+ relDepth = v
+ }
+ }).IfContains(hints.KeyLimit, func(value interface{}) {
+ if v, ok := value.(int64); ok {
+ limit = v
+ }
+ }).IfContains(hints.KeyOffset, func(value interface{}) {
+ if v, ok := value.(int64); ok {
+ offset = v
+ }
+ }).IfContains(hints.KeyOrderBy, func(value interface{}) {
+ if v, ok := value.(string); ok {
+ order = v
+ }
+ })
+
+ switch fi.fieldType {
+ case RelOneToOne, RelForeignKey, RelReverseOne:
+ limit = 1
+ offset = 0
+ }
+
+ qs.limit = limit
+ qs.offset = offset
+ qs.relDepth = relDepth
+
+ if len(order) > 0 {
+ qs.orders = order_clause.ParseOrder(order)
+ }
+
+ find := ind.FieldByIndex(fi.fieldIndex)
+
+ var nums int64
+ var err error
+ switch fi.fieldType {
+ case RelOneToOne, RelForeignKey, RelReverseOne:
+ val := reflect.New(find.Type().Elem())
+ container := val.Interface()
+ err = qs.One(container)
+ if err == nil {
+ find.Set(val)
+ nums = 1
+ }
+ default:
+ nums, err = qs.All(find.Addr().Interface())
+ }
+
+ return nums, err
+}
+
+// get QuerySeter for related models to md model
+func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, *querySet) {
+ mi, ind := o.getPtrMiInd(md)
+ fi := o.getFieldInfo(mi, name)
+
+ _, _, exist := getExistPk(mi, ind)
+ if !exist {
+ panic(ErrMissPK)
+ }
+
+ var qs *querySet
+
+ switch fi.fieldType {
+ case RelOneToOne, RelForeignKey, RelManyToMany:
+ if !fi.inModel {
+ break
+ }
+ qs = o.getRelQs(md, mi, fi)
+ case RelReverseOne, RelReverseMany:
+ if !fi.inModel {
+ break
+ }
+ qs = o.getReverseQs(md, mi, fi)
+ }
+
+ if qs == nil {
+ panic(fmt.Errorf(" name `%s` for model `%s` is not an available rel/reverse field", md, name))
+ }
+
+ return mi, fi, ind, qs
+}
+
+// get reverse relation QuerySeter
+func (o *ormBase) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
+ switch fi.fieldType {
+ case RelReverseOne, RelReverseMany:
+ default:
+ panic(fmt.Errorf(" name `%s` for model `%s` is not an available reverse field", fi.name, mi.fullName))
+ }
+
+ var q *querySet
+
+ if fi.fieldType == RelReverseMany && fi.reverseFieldInfo.mi.isThrough {
+ q = newQuerySet(o, fi.relModelInfo).(*querySet)
+ q.cond = NewCondition().And(fi.reverseFieldInfoM2M.column+ExprSep+fi.reverseFieldInfo.column, md)
+ } else {
+ q = newQuerySet(o, fi.reverseFieldInfo.mi).(*querySet)
+ q.cond = NewCondition().And(fi.reverseFieldInfo.column, md)
+ }
+
+ return q
+}
+
+// get relation QuerySeter
+func (o *ormBase) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
+ switch fi.fieldType {
+ case RelOneToOne, RelForeignKey, RelManyToMany:
+ default:
+ panic(fmt.Errorf(" name `%s` for model `%s` is not an available rel field", fi.name, mi.fullName))
+ }
+
+ q := newQuerySet(o, fi.relModelInfo).(*querySet)
+ q.cond = NewCondition()
+
+ if fi.fieldType == RelManyToMany {
+ q.cond = q.cond.And(fi.reverseFieldInfoM2M.column+ExprSep+fi.reverseFieldInfo.column, md)
+ } else {
+ q.cond = q.cond.And(fi.reverseFieldInfo.column, md)
+ }
+
+ return q
+}
+
+// return a QuerySeter for table operations.
+// table name can be string or struct.
+// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
+func (o *ormBase) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
+ var name string
+ if table, ok := ptrStructOrTableName.(string); ok {
+ name = nameStrategyMap[defaultNameStrategy](table)
+ if mi, ok := defaultModelCache.get(name); ok {
+ qs = newQuerySet(o, mi)
+ }
+ } else {
+ name = getFullName(indirectType(reflect.TypeOf(ptrStructOrTableName)))
+ if mi, ok := defaultModelCache.getByFullName(name); ok {
+ qs = newQuerySet(o, mi)
+ }
+ }
+ if qs == nil {
+ panic(fmt.Errorf(" table name: `%s` not exists", name))
+ }
+ return qs
+}
+
+// NOTE: this method is deprecated, context parameter will not take effect.
+func (o *ormBase) QueryTableWithCtx(_ context.Context, ptrStructOrTableName interface{}) (qs QuerySeter) {
+ logs.Warn("QueryTableWithCtx is DEPRECATED. Use methods with `WithCtx` suffix on QuerySeter as replacement please.")
+ return o.QueryTable(ptrStructOrTableName)
+}
+
+// return a raw query seter for raw sql string.
+func (o *ormBase) Raw(query string, args ...interface{}) RawSeter {
+ return o.RawWithCtx(context.Background(), query, args...)
+}
+
+func (o *ormBase) RawWithCtx(_ context.Context, query string, args ...interface{}) RawSeter {
+ return newRawSet(o, query, args)
+}
+
+// return current using database Driver
+func (o *ormBase) Driver() Driver {
+ return driver(o.alias.Name)
+}
+
+// return sql.DBStats for current database
+func (o *ormBase) DBStats() *sql.DBStats {
+ if o.alias != nil && o.alias.DB != nil {
+ stats := o.alias.DB.DB.Stats()
+ return &stats
+ }
+ return nil
+}
+
+type orm struct {
+ ormBase
+}
+
+var _ Ormer = new(orm)
+
+func (o *orm) Begin() (TxOrmer, error) {
+ return o.BeginWithCtx(context.Background())
+}
+
+func (o *orm) BeginWithCtx(ctx context.Context) (TxOrmer, error) {
+ return o.BeginWithCtxAndOpts(ctx, nil)
+}
+
+func (o *orm) BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) {
+ return o.BeginWithCtxAndOpts(context.Background(), opts)
+}
+
+func (o *orm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) {
+ tx, err := o.db.(txer).BeginTx(ctx, opts)
+ if err != nil {
+ return nil, err
+ }
+
+ _txOrm := &txOrm{
+ ormBase: ormBase{
+ alias: o.alias,
+ db: &TxDB{tx: tx},
+ },
+ }
+
+ if Debug {
+ _txOrm.db = newDbQueryLog(o.alias, _txOrm.db)
+ }
+
+ var taskTxOrm TxOrmer = _txOrm
+ return taskTxOrm, nil
+}
+
+func (o *orm) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return o.DoTxWithCtx(context.Background(), task)
+}
+
+func (o *orm) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return o.DoTxWithCtxAndOpts(ctx, nil, task)
+}
+
+func (o *orm) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return o.DoTxWithCtxAndOpts(context.Background(), opts, task)
+}
+
+func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error {
+ return doTxTemplate(ctx, o, opts, task)
+}
+
+func doTxTemplate(ctx context.Context, o TxBeginner, opts *sql.TxOptions,
+ task func(ctx context.Context, txOrm TxOrmer) error) error {
+ _txOrm, err := o.BeginWithCtxAndOpts(ctx, opts)
+ if err != nil {
+ return err
+ }
+ panicked := true
+ defer func() {
+ if panicked || err != nil {
+ e := _txOrm.Rollback()
+ if e != nil {
+ logs.Error("rollback transaction failed: %v,%v", e, panicked)
+ }
+ } else {
+ e := _txOrm.Commit()
+ if e != nil {
+ logs.Error("commit transaction failed: %v,%v", e, panicked)
+ }
+ }
+ }()
+ taskTxOrm := _txOrm
+ err = task(ctx, taskTxOrm)
+ panicked = false
+ return err
+}
+
+type txOrm struct {
+ ormBase
+}
+
+var _ TxOrmer = new(txOrm)
+
+func (t *txOrm) Commit() error {
+ return t.db.(txEnder).Commit()
+}
+
+func (t *txOrm) Rollback() error {
+ return t.db.(txEnder).Rollback()
+}
+
+func (t *txOrm) RollbackUnlessCommit() error {
+ return t.db.(txEnder).RollbackUnlessCommit()
+}
+
+// NewOrm create new orm
+func NewOrm() Ormer {
+ BootStrap() // execute only once
+ return NewOrmUsingDB(`default`)
+}
+
+// NewOrmUsingDB create new orm with the name
+func NewOrmUsingDB(aliasName string) Ormer {
+ if al, ok := dataBaseCache.get(aliasName); ok {
+ return newDBWithAlias(al)
+ }
+ panic(fmt.Errorf(" unknown db alias name `%s`", aliasName))
+}
+
+// NewOrmWithDB create a new ormer object with specify *sql.DB for query
+func NewOrmWithDB(driverName, aliasName string, db *sql.DB, params ...DBOption) (Ormer, error) {
+ al, err := newAliasWithDb(aliasName, driverName, db, params...)
+ if err != nil {
+ return nil, err
+ }
+
+ return newDBWithAlias(al), nil
+}
+
+func newDBWithAlias(al *alias) Ormer {
+ o := new(orm)
+ o.alias = al
+
+ if Debug {
+ o.db = newDbQueryLog(al, al.DB)
+ } else {
+ o.db = al.DB
+ }
+
+ if len(globalFilterChains) > 0 {
+ return NewFilterOrmDecorator(o, globalFilterChains...)
+ }
+ return o
+}
diff --git a/src/vendor/github.com/beego/beego/orm/orm_conds.go b/src/vendor/github.com/beego/beego/v2/client/orm/orm_conds.go
similarity index 92%
rename from src/vendor/github.com/beego/beego/orm/orm_conds.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/orm_conds.go
index f3fd66f0b..9946e595a 100644
--- a/src/vendor/github.com/beego/beego/orm/orm_conds.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/orm_conds.go
@@ -17,11 +17,13 @@ package orm
import (
"fmt"
"strings"
+
+ "github.com/beego/beego/v2/client/orm/clauses"
)
// ExprSep define the expression separation
const (
- ExprSep = "__"
+ ExprSep = clauses.ExprSep
)
type condValue struct {
@@ -76,17 +78,19 @@ func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
// AndCond combine a condition to current condition
func (c *Condition) AndCond(cond *Condition) *Condition {
- c = c.clone()
if c == cond {
panic(fmt.Errorf(" cannot use self as sub cond"))
}
+
+ c = c.clone()
+
if cond != nil {
c.params = append(c.params, condValue{cond: cond, isCond: true})
}
return c
}
-// AndNotCond combine a AND NOT condition to current condition
+// AndNotCond combine an AND NOT condition to current condition
func (c *Condition) AndNotCond(cond *Condition) *Condition {
c = c.clone()
if c == cond {
@@ -117,7 +121,7 @@ func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
return &c
}
-// OrCond combine a OR condition to current condition
+// OrCond combine an OR condition to current condition
func (c *Condition) OrCond(cond *Condition) *Condition {
c = c.clone()
if c == cond {
@@ -129,7 +133,7 @@ func (c *Condition) OrCond(cond *Condition) *Condition {
return c
}
-// OrNotCond combine a OR NOT condition to current condition
+// OrNotCond combine an OR NOT condition to current condition
func (c *Condition) OrNotCond(cond *Condition) *Condition {
c = c.clone()
if c == cond {
@@ -149,5 +153,8 @@ func (c *Condition) IsEmpty() bool {
// clone clone a condition
func (c Condition) clone() *Condition {
+ params := make([]condValue, len(c.params))
+ copy(params, c.params)
+ c.params = params
return &c
}
diff --git a/src/vendor/github.com/beego/beego/orm/orm_log.go b/src/vendor/github.com/beego/beego/v2/client/orm/orm_log.go
similarity index 80%
rename from src/vendor/github.com/beego/beego/orm/orm_log.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/orm_log.go
index 5bb3a24f8..e6f8bc83c 100644
--- a/src/vendor/github.com/beego/beego/orm/orm_log.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/orm_log.go
@@ -29,7 +29,7 @@ type Log struct {
*log.Logger
}
-//costomer log func
+// costomer log func
var LogFunc func(query map[string]interface{})
// NewLog set io.Writer to create a Logger.
@@ -40,8 +40,8 @@ func NewLog(out io.Writer) *Log {
}
func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error, args ...interface{}) {
- var logMap = make(map[string]interface{})
- sub := time.Now().Sub(t) / 1e5
+ logMap := make(map[string]interface{})
+ sub := time.Since(t) / 1e5
elsp := float64(int(sub)) / 10.0
logMap["cost_time"] = elsp
flag := " OK"
@@ -85,20 +85,32 @@ func (d *stmtQueryLog) Close() error {
}
func (d *stmtQueryLog) Exec(args ...interface{}) (sql.Result, error) {
+ return d.ExecContext(context.Background(), args...)
+}
+
+func (d *stmtQueryLog) ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error) {
a := time.Now()
- res, err := d.stmt.Exec(args...)
+ res, err := d.stmt.ExecContext(ctx, args...)
debugLogQueies(d.alias, "st.Exec", d.query, a, err, args...)
return res, err
}
func (d *stmtQueryLog) Query(args ...interface{}) (*sql.Rows, error) {
+ return d.QueryContext(context.Background(), args...)
+}
+
+func (d *stmtQueryLog) QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error) {
a := time.Now()
- res, err := d.stmt.Query(args...)
+ res, err := d.stmt.QueryContext(ctx, args...)
debugLogQueies(d.alias, "st.Query", d.query, a, err, args...)
return res, err
}
func (d *stmtQueryLog) QueryRow(args ...interface{}) *sql.Row {
+ return d.QueryRowContext(context.Background(), args...)
+}
+
+func (d *stmtQueryLog) QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row {
a := time.Now()
res := d.stmt.QueryRow(args...)
debugLogQueies(d.alias, "st.QueryRow", d.query, a, nil, args...)
@@ -122,15 +134,14 @@ type dbQueryLog struct {
txe txEnder
}
-var _ dbQuerier = new(dbQueryLog)
-var _ txer = new(dbQueryLog)
-var _ txEnder = new(dbQueryLog)
+var (
+ _ dbQuerier = new(dbQueryLog)
+ _ txer = new(dbQueryLog)
+ _ txEnder = new(dbQueryLog)
+)
func (d *dbQueryLog) Prepare(query string) (*sql.Stmt, error) {
- a := time.Now()
- stmt, err := d.db.Prepare(query)
- debugLogQueies(d.alias, "db.Prepare", query, a, err)
- return stmt, err
+ return d.PrepareContext(context.Background(), query)
}
func (d *dbQueryLog) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
@@ -141,10 +152,7 @@ func (d *dbQueryLog) PrepareContext(ctx context.Context, query string) (*sql.Stm
}
func (d *dbQueryLog) Exec(query string, args ...interface{}) (sql.Result, error) {
- a := time.Now()
- res, err := d.db.Exec(query, args...)
- debugLogQueies(d.alias, "db.Exec", query, a, err, args...)
- return res, err
+ return d.ExecContext(context.Background(), query, args...)
}
func (d *dbQueryLog) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
@@ -155,10 +163,7 @@ func (d *dbQueryLog) ExecContext(ctx context.Context, query string, args ...inte
}
func (d *dbQueryLog) Query(query string, args ...interface{}) (*sql.Rows, error) {
- a := time.Now()
- res, err := d.db.Query(query, args...)
- debugLogQueies(d.alias, "db.Query", query, a, err, args...)
- return res, err
+ return d.QueryContext(context.Background(), query, args...)
}
func (d *dbQueryLog) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
@@ -169,10 +174,7 @@ func (d *dbQueryLog) QueryContext(ctx context.Context, query string, args ...int
}
func (d *dbQueryLog) QueryRow(query string, args ...interface{}) *sql.Row {
- a := time.Now()
- res := d.db.QueryRow(query, args...)
- debugLogQueies(d.alias, "db.QueryRow", query, a, nil, args...)
- return res
+ return d.QueryRowContext(context.Background(), query, args...)
}
func (d *dbQueryLog) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
@@ -183,10 +185,7 @@ func (d *dbQueryLog) QueryRowContext(ctx context.Context, query string, args ...
}
func (d *dbQueryLog) Begin() (*sql.Tx, error) {
- a := time.Now()
- tx, err := d.db.(txer).Begin()
- debugLogQueies(d.alias, "db.Begin", "START TRANSACTION", a, err)
- return tx, err
+ return d.BeginTx(context.Background(), nil)
}
func (d *dbQueryLog) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
@@ -210,6 +209,13 @@ func (d *dbQueryLog) Rollback() error {
return err
}
+func (d *dbQueryLog) RollbackUnlessCommit() error {
+ a := time.Now()
+ err := d.db.(txEnder).RollbackUnlessCommit()
+ debugLogQueies(d.alias, "tx.RollbackUnlessCommit", "ROLLBACK UNLESS COMMIT", a, err)
+ return err
+}
+
func (d *dbQueryLog) SetDB(db dbQuerier) {
d.db = db
}
diff --git a/src/vendor/github.com/beego/beego/orm/orm_object.go b/src/vendor/github.com/beego/beego/v2/client/orm/orm_object.go
similarity index 82%
rename from src/vendor/github.com/beego/beego/orm/orm_object.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/orm_object.go
index de3181ce2..50c1ca416 100644
--- a/src/vendor/github.com/beego/beego/orm/orm_object.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/orm_object.go
@@ -15,6 +15,7 @@
package orm
import (
+ "context"
"fmt"
"reflect"
)
@@ -22,7 +23,7 @@ import (
// an insert queryer struct
type insertSet struct {
mi *modelInfo
- orm *orm
+ orm *ormBase
stmt stmtQuerier
closed bool
}
@@ -31,6 +32,10 @@ var _ Inserter = new(insertSet)
// insert model ignore it's registered or not.
func (o *insertSet) Insert(md interface{}) (int64, error) {
+ return o.InsertWithCtx(context.Background(), md)
+}
+
+func (o *insertSet) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
if o.closed {
return 0, ErrStmtClosed
}
@@ -44,7 +49,7 @@ func (o *insertSet) Insert(md interface{}) (int64, error) {
if name != o.mi.fullName {
panic(fmt.Errorf(" need model `%s` but found `%s`", o.mi.fullName, name))
}
- id, err := o.orm.alias.DbBaser.InsertStmt(o.stmt, o.mi, ind, o.orm.alias.TZ)
+ id, err := o.orm.alias.DbBaser.InsertStmt(ctx, o.stmt, o.mi, ind, o.orm.alias.TZ)
if err != nil {
return id, err
}
@@ -70,11 +75,11 @@ func (o *insertSet) Close() error {
}
// create new insert queryer.
-func newInsertSet(orm *orm, mi *modelInfo) (Inserter, error) {
+func newInsertSet(ctx context.Context, orm *ormBase, mi *modelInfo) (Inserter, error) {
bi := new(insertSet)
bi.orm = orm
bi.mi = mi
- st, query, err := orm.alias.DbBaser.PrepareInsert(orm.db, mi)
+ st, query, err := orm.alias.DbBaser.PrepareInsert(ctx, orm.db, mi)
if err != nil {
return nil, err
}
diff --git a/src/vendor/github.com/beego/beego/orm/orm_querym2m.go b/src/vendor/github.com/beego/beego/v2/client/orm/orm_querym2m.go
similarity index 76%
rename from src/vendor/github.com/beego/beego/orm/orm_querym2m.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/orm_querym2m.go
index 6a270a0d8..9da49bba9 100644
--- a/src/vendor/github.com/beego/beego/orm/orm_querym2m.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/orm_querym2m.go
@@ -14,7 +14,10 @@
package orm
-import "reflect"
+import (
+ "context"
+ "reflect"
+)
// model to model struct
type queryM2M struct {
@@ -33,6 +36,10 @@ type queryM2M struct {
//
// make sure the relation is defined in post model struct tag.
func (o *queryM2M) Add(mds ...interface{}) (int64, error) {
+ return o.AddWithCtx(context.Background(), mds...)
+}
+
+func (o *queryM2M) AddWithCtx(ctx context.Context, mds ...interface{}) (int64, error) {
fi := o.fi
mi := fi.relThroughModelInfo
mfi := fi.reverseFieldInfo
@@ -96,11 +103,15 @@ func (o *queryM2M) Add(mds ...interface{}) (int64, error) {
}
names = append(names, otherNames...)
values = append(values, otherValues...)
- return dbase.InsertValue(orm.db, mi, true, names, values)
+ return dbase.InsertValue(ctx, orm.db, mi, true, names, values)
}
// remove models following the origin model relationship
func (o *queryM2M) Remove(mds ...interface{}) (int64, error) {
+ return o.RemoveWithCtx(context.Background(), mds...)
+}
+
+func (o *queryM2M) RemoveWithCtx(ctx context.Context, mds ...interface{}) (int64, error) {
fi := o.fi
qs := o.qs.Filter(fi.reverseFieldInfo.name, o.md)
@@ -109,27 +120,39 @@ func (o *queryM2M) Remove(mds ...interface{}) (int64, error) {
// check model is existed in relationship of origin model
func (o *queryM2M) Exist(md interface{}) bool {
+ return o.ExistWithCtx(context.Background(), md)
+}
+
+func (o *queryM2M) ExistWithCtx(ctx context.Context, md interface{}) bool {
fi := o.fi
return o.qs.Filter(fi.reverseFieldInfo.name, o.md).
- Filter(fi.reverseFieldInfoTwo.name, md).Exist()
+ Filter(fi.reverseFieldInfoTwo.name, md).ExistWithCtx(ctx)
}
// clean all models in related of origin model
func (o *queryM2M) Clear() (int64, error) {
+ return o.ClearWithCtx(context.Background())
+}
+
+func (o *queryM2M) ClearWithCtx(ctx context.Context) (int64, error) {
fi := o.fi
- return o.qs.Filter(fi.reverseFieldInfo.name, o.md).Delete()
+ return o.qs.Filter(fi.reverseFieldInfo.name, o.md).DeleteWithCtx(ctx)
}
// count all related models of origin model
func (o *queryM2M) Count() (int64, error) {
+ return o.CountWithCtx(context.Background())
+}
+
+func (o *queryM2M) CountWithCtx(ctx context.Context) (int64, error) {
fi := o.fi
- return o.qs.Filter(fi.reverseFieldInfo.name, o.md).Count()
+ return o.qs.Filter(fi.reverseFieldInfo.name, o.md).CountWithCtx(ctx)
}
var _ QueryM2Mer = new(queryM2M)
// create new M2M queryer.
-func newQueryM2M(md interface{}, o *orm, mi *modelInfo, fi *fieldInfo, ind reflect.Value) QueryM2Mer {
+func newQueryM2M(md interface{}, o *ormBase, mi *modelInfo, fi *fieldInfo, ind reflect.Value) QueryM2Mer {
qm2m := new(queryM2M)
qm2m.md = md
qm2m.mi = mi
diff --git a/src/vendor/github.com/beego/beego/orm/orm_queryset.go b/src/vendor/github.com/beego/beego/v2/client/orm/orm_queryset.go
similarity index 61%
rename from src/vendor/github.com/beego/beego/orm/orm_queryset.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/orm_queryset.go
index 878b836b8..823258990 100644
--- a/src/vendor/github.com/beego/beego/orm/orm_queryset.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/orm_queryset.go
@@ -17,6 +17,9 @@ package orm
import (
"context"
"fmt"
+
+ "github.com/beego/beego/v2/client/orm/clauses/order_clause"
+ "github.com/beego/beego/v2/client/orm/hints"
)
type colValue struct {
@@ -62,19 +65,20 @@ func ColValue(opt operator, value interface{}) interface{} {
// real query struct
type querySet struct {
- mi *modelInfo
- cond *Condition
- related []string
- relDepth int
- limit int64
- offset int64
- groups []string
- orders []string
- distinct bool
- forupdate bool
- orm *orm
- ctx context.Context
- forContext bool
+ mi *modelInfo
+ cond *Condition
+ related []string
+ relDepth int
+ limit int64
+ offset int64
+ groups []string
+ orders []*order_clause.Order
+ distinct bool
+ forUpdate bool
+ useIndex int
+ indexes []string
+ orm *ormBase
+ aggregate string
}
var _ QuerySeter = new(querySet)
@@ -135,8 +139,20 @@ func (o querySet) GroupBy(exprs ...string) QuerySeter {
// add ORDER expression.
// "column" means ASC, "-column" means DESC.
-func (o querySet) OrderBy(exprs ...string) QuerySeter {
- o.orders = exprs
+func (o querySet) OrderBy(expressions ...string) QuerySeter {
+ if len(expressions) <= 0 {
+ return &o
+ }
+ o.orders = order_clause.ParseOrder(expressions...)
+ return &o
+}
+
+// add ORDER expression.
+func (o querySet) OrderClauses(orders ...*order_clause.Order) QuerySeter {
+ if len(orders) <= 0 {
+ return &o
+ }
+ o.orders = orders
return &o
}
@@ -148,7 +164,28 @@ func (o querySet) Distinct() QuerySeter {
// add FOR UPDATE to SELECT
func (o querySet) ForUpdate() QuerySeter {
- o.forupdate = true
+ o.forUpdate = true
+ return &o
+}
+
+// ForceIndex force index for query
+func (o querySet) ForceIndex(indexes ...string) QuerySeter {
+ o.useIndex = hints.KeyForceIndex
+ o.indexes = indexes
+ return &o
+}
+
+// UseIndex use index for query
+func (o querySet) UseIndex(indexes ...string) QuerySeter {
+ o.useIndex = hints.KeyUseIndex
+ o.indexes = indexes
+ return &o
+}
+
+// IgnoreIndex ignore index for query
+func (o querySet) IgnoreIndex(indexes ...string) QuerySeter {
+ o.useIndex = hints.KeyIgnoreIndex
+ o.indexes = indexes
return &o
}
@@ -185,45 +222,73 @@ func (o querySet) GetCond() *Condition {
// return QuerySeter execution result number
func (o *querySet) Count() (int64, error) {
- return o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
+ return o.CountWithCtx(context.Background())
+}
+
+func (o *querySet) CountWithCtx(ctx context.Context) (int64, error) {
+ return o.orm.alias.DbBaser.Count(ctx, o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
}
// check result empty or not after QuerySeter executed
func (o *querySet) Exist() bool {
- cnt, _ := o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
+ return o.ExistWithCtx(context.Background())
+}
+
+func (o *querySet) ExistWithCtx(ctx context.Context) bool {
+ cnt, _ := o.orm.alias.DbBaser.Count(ctx, o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
return cnt > 0
}
// execute update with parameters
func (o *querySet) Update(values Params) (int64, error) {
- return o.orm.alias.DbBaser.UpdateBatch(o.orm.db, o, o.mi, o.cond, values, o.orm.alias.TZ)
+ return o.UpdateWithCtx(context.Background(), values)
+}
+
+func (o *querySet) UpdateWithCtx(ctx context.Context, values Params) (int64, error) {
+ return o.orm.alias.DbBaser.UpdateBatch(ctx, o.orm.db, o, o.mi, o.cond, values, o.orm.alias.TZ)
}
// execute delete
func (o *querySet) Delete() (int64, error) {
- return o.orm.alias.DbBaser.DeleteBatch(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
+ return o.DeleteWithCtx(context.Background())
}
-// return a insert queryer.
+func (o *querySet) DeleteWithCtx(ctx context.Context) (int64, error) {
+ return o.orm.alias.DbBaser.DeleteBatch(ctx, o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
+}
+
+// return an insert queryer.
// it can be used in times.
// example:
// i,err := sq.PrepareInsert()
// i.Add(&user1{},&user2{})
func (o *querySet) PrepareInsert() (Inserter, error) {
- return newInsertSet(o.orm, o.mi)
+ return o.PrepareInsertWithCtx(context.Background())
+}
+
+func (o *querySet) PrepareInsertWithCtx(ctx context.Context) (Inserter, error) {
+ return newInsertSet(ctx, o.orm, o.mi)
}
// query all data and map to containers.
// cols means the columns when querying.
func (o *querySet) All(container interface{}, cols ...string) (int64, error) {
- return o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols)
+ return o.AllWithCtx(context.Background(), container, cols...)
+}
+
+func (o *querySet) AllWithCtx(ctx context.Context, container interface{}, cols ...string) (int64, error) {
+ return o.orm.alias.DbBaser.ReadBatch(ctx, o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols)
}
// query one row data and map to containers.
// cols means the columns when querying.
func (o *querySet) One(container interface{}, cols ...string) error {
+ return o.OneWithCtx(context.Background(), container, cols...)
+}
+
+func (o *querySet) OneWithCtx(ctx context.Context, container interface{}, cols ...string) error {
o.limit = 1
- num, err := o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols)
+ num, err := o.orm.alias.DbBaser.ReadBatch(ctx, o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols)
if err != nil {
return err
}
@@ -241,19 +306,31 @@ func (o *querySet) One(container interface{}, cols ...string) error {
// expres means condition expression.
// it converts data to []map[column]value.
func (o *querySet) Values(results *[]Params, exprs ...string) (int64, error) {
- return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
+ return o.ValuesWithCtx(context.Background(), results, exprs...)
+}
+
+func (o *querySet) ValuesWithCtx(ctx context.Context, results *[]Params, exprs ...string) (int64, error) {
+ return o.orm.alias.DbBaser.ReadValues(ctx, o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
}
// query all data and map to [][]interface
// it converts data to [][column_index]value
func (o *querySet) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) {
- return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
+ return o.ValuesListWithCtx(context.Background(), results, exprs...)
+}
+
+func (o *querySet) ValuesListWithCtx(ctx context.Context, results *[]ParamsList, exprs ...string) (int64, error) {
+ return o.orm.alias.DbBaser.ReadValues(ctx, o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
}
// query all data and map to []interface.
// it's designed for one row record set, auto change to []value, not [][column]value.
func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) {
- return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ)
+ return o.ValuesFlatWithCtx(context.Background(), result, expr)
+}
+
+func (o *querySet) ValuesFlatWithCtx(ctx context.Context, result *ParamsList, expr string) (int64, error) {
+ return o.orm.alias.DbBaser.ReadValues(ctx, o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ)
}
// query all rows into map[string]interface with specify key and value column name.
@@ -284,17 +361,16 @@ func (o *querySet) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string)
panic(ErrNotImplement)
}
-// set context to QuerySeter.
-func (o querySet) WithContext(ctx context.Context) QuerySeter {
- o.ctx = ctx
- o.forContext = true
- return &o
-}
-
// create new QuerySeter.
-func newQuerySet(orm *orm, mi *modelInfo) QuerySeter {
+func newQuerySet(orm *ormBase, mi *modelInfo) QuerySeter {
o := new(querySet)
o.mi = mi
o.orm = orm
return o
}
+
+// aggregate func
+func (o querySet) Aggregate(s string) QuerySeter {
+ o.aggregate = s
+ return &o
+}
diff --git a/src/vendor/github.com/beego/beego/orm/orm_raw.go b/src/vendor/github.com/beego/beego/v2/client/orm/orm_raw.go
similarity index 92%
rename from src/vendor/github.com/beego/beego/orm/orm_raw.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/orm_raw.go
index 1bdefc789..f4f3a62e8 100644
--- a/src/vendor/github.com/beego/beego/orm/orm_raw.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/orm_raw.go
@@ -34,7 +34,8 @@ func (o *rawPrepare) Exec(args ...interface{}) (sql.Result, error) {
if o.closed {
return nil, ErrStmtClosed
}
- return o.stmt.Exec(args...)
+ flatParams := getFlatParams(nil, args, o.rs.orm.alias.TZ)
+ return o.stmt.Exec(flatParams...)
}
func (o *rawPrepare) Close() error {
@@ -65,7 +66,7 @@ func newRawPreparer(rs *rawSet) (RawPreparer, error) {
type rawSet struct {
query string
args []interface{}
- orm *orm
+ orm *ormBase
}
var _ RawSeter = new(rawSet)
@@ -180,6 +181,12 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
if err == nil {
ind.Set(reflect.ValueOf(t))
}
+ } else if len(str) >= 8 {
+ str = str[:8]
+ t, err := time.ParseInLocation(formatTime, str, DefaultTimeLoc)
+ if err == nil {
+ ind.Set(reflect.ValueOf(t))
+ }
}
}
case sql.NullString, sql.NullInt64, sql.NullFloat64, sql.NullBool:
@@ -246,7 +253,6 @@ func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr
}
cur++
}
-
} else {
value := reflect.ValueOf(refs[cur]).Elem().Interface()
if isPtr && value == nil {
@@ -308,7 +314,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
structMode = true
fn := getFullName(typ)
- if mi, ok := modelCache.getByFullName(fn); ok {
+ if mi, ok := defaultModelCache.getByFullName(fn); ok {
sMi = mi
}
} else {
@@ -329,6 +335,8 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
return err
}
+ structTagMap := make(map[reflect.StructTag]map[string]string)
+
defer rows.Close()
if rows.Next() {
@@ -382,19 +390,38 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
}
}
} else {
- for i := 0; i < ind.NumField(); i++ {
- f := ind.Field(i)
- fe := ind.Type().Field(i)
- _, tags := parseStructTag(fe.Tag.Get(defaultStructTagName))
- var col string
- if col = tags["column"]; col == "" {
- col = nameStrategyMap[nameStrategy](fe.Name)
- }
- if v, ok := columnsMp[col]; ok {
- value := reflect.ValueOf(v).Elem().Interface()
- o.setFieldValue(f, value)
+ // define recursive function
+ var recursiveSetField func(rv reflect.Value)
+ recursiveSetField = func(rv reflect.Value) {
+ for i := 0; i < rv.NumField(); i++ {
+ f := rv.Field(i)
+ fe := rv.Type().Field(i)
+
+ // check if the field is a Struct
+ // recursive the Struct type
+ if fe.Type.Kind() == reflect.Struct {
+ recursiveSetField(f)
+ }
+
+ // thanks @Gazeboxu.
+ tags := structTagMap[fe.Tag]
+ if tags == nil {
+ _, tags = parseStructTag(fe.Tag.Get(defaultStructTagName))
+ structTagMap[fe.Tag] = tags
+ }
+ var col string
+ if col = tags["column"]; col == "" {
+ col = nameStrategyMap[nameStrategy](fe.Name)
+ }
+ if v, ok := columnsMp[col]; ok {
+ value := reflect.ValueOf(v).Elem().Interface()
+ o.setFieldValue(f, value)
+ }
}
}
+
+ // init call the recursive function
+ recursiveSetField(ind)
}
} else {
@@ -409,7 +436,6 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
sInd.Set(nInd)
}
}
-
} else {
return ErrNoRows
}
@@ -449,7 +475,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
structMode = true
fn := getFullName(typ)
- if mi, ok := modelCache.getByFullName(fn); ok {
+ if mi, ok := defaultModelCache.getByFullName(fn); ok {
sMi = mi
}
} else {
@@ -578,7 +604,6 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
}
if cnt > 0 {
-
if structMode {
sInds[0].Set(sInd)
} else {
@@ -876,7 +901,7 @@ func (o *rawSet) Prepare() (RawPreparer, error) {
return newRawPreparer(o)
}
-func newRawSet(orm *orm, query string, args []interface{}) RawSeter {
+func newRawSet(orm *ormBase, query string, args []interface{}) RawSeter {
o := new(rawSet)
o.query = query
o.args = args
diff --git a/src/vendor/github.com/beego/beego/orm/qb.go b/src/vendor/github.com/beego/beego/v2/client/orm/qb.go
similarity index 96%
rename from src/vendor/github.com/beego/beego/orm/qb.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/qb.go
index e0655a178..c82d2255d 100644
--- a/src/vendor/github.com/beego/beego/orm/qb.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/qb.go
@@ -52,7 +52,7 @@ func NewQueryBuilder(driver string) (qb QueryBuilder, err error) {
} else if driver == "tidb" {
qb = new(TiDBQueryBuilder)
} else if driver == "postgres" {
- err = errors.New("postgres query builder is not supported yet")
+ qb = new(PostgresQueryBuilder)
} else if driver == "sqlite" {
err = errors.New("sqlite query builder is not supported yet")
} else {
diff --git a/src/vendor/github.com/beego/beego/orm/qb_mysql.go b/src/vendor/github.com/beego/beego/v2/client/orm/qb_mysql.go
similarity index 71%
rename from src/vendor/github.com/beego/beego/orm/qb_mysql.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/qb_mysql.go
index 23bdc9eef..191304967 100644
--- a/src/vendor/github.com/beego/beego/orm/qb_mysql.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/qb_mysql.go
@@ -25,144 +25,144 @@ const CommaSpace = ", "
// MySQLQueryBuilder is the SQL build
type MySQLQueryBuilder struct {
- Tokens []string
+ tokens []string
}
// Select will join the fields
func (qb *MySQLQueryBuilder) Select(fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "SELECT", strings.Join(fields, CommaSpace))
+ qb.tokens = append(qb.tokens, "SELECT", strings.Join(fields, CommaSpace))
return qb
}
// ForUpdate add the FOR UPDATE clause
func (qb *MySQLQueryBuilder) ForUpdate() QueryBuilder {
- qb.Tokens = append(qb.Tokens, "FOR UPDATE")
+ qb.tokens = append(qb.tokens, "FOR UPDATE")
return qb
}
// From join the tables
func (qb *MySQLQueryBuilder) From(tables ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "FROM", strings.Join(tables, CommaSpace))
+ qb.tokens = append(qb.tokens, "FROM", strings.Join(tables, CommaSpace))
return qb
}
// InnerJoin INNER JOIN the table
func (qb *MySQLQueryBuilder) InnerJoin(table string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "INNER JOIN", table)
+ qb.tokens = append(qb.tokens, "INNER JOIN", table)
return qb
}
// LeftJoin LEFT JOIN the table
func (qb *MySQLQueryBuilder) LeftJoin(table string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "LEFT JOIN", table)
+ qb.tokens = append(qb.tokens, "LEFT JOIN", table)
return qb
}
// RightJoin RIGHT JOIN the table
func (qb *MySQLQueryBuilder) RightJoin(table string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "RIGHT JOIN", table)
+ qb.tokens = append(qb.tokens, "RIGHT JOIN", table)
return qb
}
// On join with on cond
func (qb *MySQLQueryBuilder) On(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "ON", cond)
+ qb.tokens = append(qb.tokens, "ON", cond)
return qb
}
// Where join the Where cond
func (qb *MySQLQueryBuilder) Where(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "WHERE", cond)
+ qb.tokens = append(qb.tokens, "WHERE", cond)
return qb
}
// And join the and cond
func (qb *MySQLQueryBuilder) And(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "AND", cond)
+ qb.tokens = append(qb.tokens, "AND", cond)
return qb
}
// Or join the or cond
func (qb *MySQLQueryBuilder) Or(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "OR", cond)
+ qb.tokens = append(qb.tokens, "OR", cond)
return qb
}
// In join the IN (vals)
func (qb *MySQLQueryBuilder) In(vals ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
+ qb.tokens = append(qb.tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
return qb
}
// OrderBy join the Order by fields
func (qb *MySQLQueryBuilder) OrderBy(fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "ORDER BY", strings.Join(fields, CommaSpace))
+ qb.tokens = append(qb.tokens, "ORDER BY", strings.Join(fields, CommaSpace))
return qb
}
// Asc join the asc
func (qb *MySQLQueryBuilder) Asc() QueryBuilder {
- qb.Tokens = append(qb.Tokens, "ASC")
+ qb.tokens = append(qb.tokens, "ASC")
return qb
}
// Desc join the desc
func (qb *MySQLQueryBuilder) Desc() QueryBuilder {
- qb.Tokens = append(qb.Tokens, "DESC")
+ qb.tokens = append(qb.tokens, "DESC")
return qb
}
// Limit join the limit num
func (qb *MySQLQueryBuilder) Limit(limit int) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "LIMIT", strconv.Itoa(limit))
+ qb.tokens = append(qb.tokens, "LIMIT", strconv.Itoa(limit))
return qb
}
// Offset join the offset num
func (qb *MySQLQueryBuilder) Offset(offset int) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "OFFSET", strconv.Itoa(offset))
+ qb.tokens = append(qb.tokens, "OFFSET", strconv.Itoa(offset))
return qb
}
// GroupBy join the Group by fields
func (qb *MySQLQueryBuilder) GroupBy(fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "GROUP BY", strings.Join(fields, CommaSpace))
+ qb.tokens = append(qb.tokens, "GROUP BY", strings.Join(fields, CommaSpace))
return qb
}
// Having join the Having cond
func (qb *MySQLQueryBuilder) Having(cond string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "HAVING", cond)
+ qb.tokens = append(qb.tokens, "HAVING", cond)
return qb
}
// Update join the update table
func (qb *MySQLQueryBuilder) Update(tables ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "UPDATE", strings.Join(tables, CommaSpace))
+ qb.tokens = append(qb.tokens, "UPDATE", strings.Join(tables, CommaSpace))
return qb
}
// Set join the set kv
func (qb *MySQLQueryBuilder) Set(kv ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "SET", strings.Join(kv, CommaSpace))
+ qb.tokens = append(qb.tokens, "SET", strings.Join(kv, CommaSpace))
return qb
}
// Delete join the Delete tables
func (qb *MySQLQueryBuilder) Delete(tables ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "DELETE")
+ qb.tokens = append(qb.tokens, "DELETE")
if len(tables) != 0 {
- qb.Tokens = append(qb.Tokens, strings.Join(tables, CommaSpace))
+ qb.tokens = append(qb.tokens, strings.Join(tables, CommaSpace))
}
return qb
}
// InsertInto join the insert SQL
func (qb *MySQLQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
- qb.Tokens = append(qb.Tokens, "INSERT INTO", table)
+ qb.tokens = append(qb.tokens, "INSERT INTO", table)
if len(fields) != 0 {
fieldsStr := strings.Join(fields, CommaSpace)
- qb.Tokens = append(qb.Tokens, "(", fieldsStr, ")")
+ qb.tokens = append(qb.tokens, "(", fieldsStr, ")")
}
return qb
}
@@ -170,7 +170,7 @@ func (qb *MySQLQueryBuilder) InsertInto(table string, fields ...string) QueryBui
// Values join the Values(vals)
func (qb *MySQLQueryBuilder) Values(vals ...string) QueryBuilder {
valsStr := strings.Join(vals, CommaSpace)
- qb.Tokens = append(qb.Tokens, "VALUES", "(", valsStr, ")")
+ qb.tokens = append(qb.tokens, "VALUES", "(", valsStr, ")")
return qb
}
@@ -179,7 +179,9 @@ func (qb *MySQLQueryBuilder) Subquery(sub string, alias string) string {
return fmt.Sprintf("(%s) AS %s", sub, alias)
}
-// String join all Tokens
+// String join all tokens
func (qb *MySQLQueryBuilder) String() string {
- return strings.Join(qb.Tokens, " ")
+ s := strings.Join(qb.tokens, " ")
+ qb.tokens = qb.tokens[:0]
+ return s
}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/qb_postgres.go b/src/vendor/github.com/beego/beego/v2/client/orm/qb_postgres.go
new file mode 100644
index 000000000..d7f216921
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/qb_postgres.go
@@ -0,0 +1,219 @@
+package orm
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+var quote string = `"`
+
+// PostgresQueryBuilder is the SQL build
+type PostgresQueryBuilder struct {
+ tokens []string
+}
+
+func processingStr(str []string) string {
+ s := strings.Join(str, `","`)
+ s = fmt.Sprintf("%s%s%s", quote, s, quote)
+ return s
+}
+
+// Select will join the fields
+func (qb *PostgresQueryBuilder) Select(fields ...string) QueryBuilder {
+ var str string
+ n := len(fields)
+
+ if fields[0] == "*" {
+ str = "*"
+ } else {
+ for i := 0; i < n; i++ {
+ sli := strings.Split(fields[i], ".")
+ s := strings.Join(sli, `"."`)
+ s = fmt.Sprintf("%s%s%s", quote, s, quote)
+ if n == 1 || i == n-1 {
+ str += s
+ } else {
+ str += s + ","
+ }
+ }
+ }
+
+ qb.tokens = append(qb.tokens, "SELECT", str)
+ return qb
+}
+
+// ForUpdate add the FOR UPDATE clause
+func (qb *PostgresQueryBuilder) ForUpdate() QueryBuilder {
+ qb.tokens = append(qb.tokens, "FOR UPDATE")
+ return qb
+}
+
+// From join the tables
+func (qb *PostgresQueryBuilder) From(tables ...string) QueryBuilder {
+ str := processingStr(tables)
+ qb.tokens = append(qb.tokens, "FROM", str)
+ return qb
+}
+
+// InnerJoin INNER JOIN the table
+func (qb *PostgresQueryBuilder) InnerJoin(table string) QueryBuilder {
+ str := fmt.Sprintf("%s%s%s", quote, table, quote)
+ qb.tokens = append(qb.tokens, "INNER JOIN", str)
+ return qb
+}
+
+// LeftJoin LEFT JOIN the table
+func (qb *PostgresQueryBuilder) LeftJoin(table string) QueryBuilder {
+ str := fmt.Sprintf("%s%s%s", quote, table, quote)
+ qb.tokens = append(qb.tokens, "LEFT JOIN", str)
+ return qb
+}
+
+// RightJoin RIGHT JOIN the table
+func (qb *PostgresQueryBuilder) RightJoin(table string) QueryBuilder {
+ str := fmt.Sprintf("%s%s%s", quote, table, quote)
+ qb.tokens = append(qb.tokens, "RIGHT JOIN", str)
+ return qb
+}
+
+// On join with on cond
+func (qb *PostgresQueryBuilder) On(cond string) QueryBuilder {
+ var str string
+ cond = strings.Replace(cond, " ", "", -1)
+ slice := strings.Split(cond, "=")
+ for i := 0; i < len(slice); i++ {
+ sli := strings.Split(slice[i], ".")
+ s := strings.Join(sli, `"."`)
+ s = fmt.Sprintf("%s%s%s", quote, s, quote)
+ if i == 0 {
+ str = s + " =" + " "
+ } else {
+ str += s
+ }
+ }
+
+ qb.tokens = append(qb.tokens, "ON", str)
+ return qb
+}
+
+// Where join the Where cond
+func (qb *PostgresQueryBuilder) Where(cond string) QueryBuilder {
+ qb.tokens = append(qb.tokens, "WHERE", cond)
+ return qb
+}
+
+// And join the and cond
+func (qb *PostgresQueryBuilder) And(cond string) QueryBuilder {
+ qb.tokens = append(qb.tokens, "AND", cond)
+ return qb
+}
+
+// Or join the or cond
+func (qb *PostgresQueryBuilder) Or(cond string) QueryBuilder {
+ qb.tokens = append(qb.tokens, "OR", cond)
+ return qb
+}
+
+// In join the IN (vals)
+func (qb *PostgresQueryBuilder) In(vals ...string) QueryBuilder {
+ qb.tokens = append(qb.tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
+ return qb
+}
+
+// OrderBy join the Order by fields
+func (qb *PostgresQueryBuilder) OrderBy(fields ...string) QueryBuilder {
+ str := processingStr(fields)
+ qb.tokens = append(qb.tokens, "ORDER BY", str)
+ return qb
+}
+
+// Asc join the asc
+func (qb *PostgresQueryBuilder) Asc() QueryBuilder {
+ qb.tokens = append(qb.tokens, "ASC")
+ return qb
+}
+
+// Desc join the desc
+func (qb *PostgresQueryBuilder) Desc() QueryBuilder {
+ qb.tokens = append(qb.tokens, "DESC")
+ return qb
+}
+
+// Limit join the limit num
+func (qb *PostgresQueryBuilder) Limit(limit int) QueryBuilder {
+ qb.tokens = append(qb.tokens, "LIMIT", strconv.Itoa(limit))
+ return qb
+}
+
+// Offset join the offset num
+func (qb *PostgresQueryBuilder) Offset(offset int) QueryBuilder {
+ qb.tokens = append(qb.tokens, "OFFSET", strconv.Itoa(offset))
+ return qb
+}
+
+// GroupBy join the Group by fields
+func (qb *PostgresQueryBuilder) GroupBy(fields ...string) QueryBuilder {
+ str := processingStr(fields)
+ qb.tokens = append(qb.tokens, "GROUP BY", str)
+ return qb
+}
+
+// Having join the Having cond
+func (qb *PostgresQueryBuilder) Having(cond string) QueryBuilder {
+ qb.tokens = append(qb.tokens, "HAVING", cond)
+ return qb
+}
+
+// Update join the update table
+func (qb *PostgresQueryBuilder) Update(tables ...string) QueryBuilder {
+ str := processingStr(tables)
+ qb.tokens = append(qb.tokens, "UPDATE", str)
+ return qb
+}
+
+// Set join the set kv
+func (qb *PostgresQueryBuilder) Set(kv ...string) QueryBuilder {
+ qb.tokens = append(qb.tokens, "SET", strings.Join(kv, CommaSpace))
+ return qb
+}
+
+// Delete join the Delete tables
+func (qb *PostgresQueryBuilder) Delete(tables ...string) QueryBuilder {
+ qb.tokens = append(qb.tokens, "DELETE")
+ if len(tables) != 0 {
+ str := processingStr(tables)
+ qb.tokens = append(qb.tokens, str)
+ }
+ return qb
+}
+
+// InsertInto join the insert SQL
+func (qb *PostgresQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
+ str := fmt.Sprintf("%s%s%s", quote, table, quote)
+ qb.tokens = append(qb.tokens, "INSERT INTO", str)
+ if len(fields) != 0 {
+ fieldsStr := strings.Join(fields, CommaSpace)
+ qb.tokens = append(qb.tokens, "(", fieldsStr, ")")
+ }
+ return qb
+}
+
+// Values join the Values(vals)
+func (qb *PostgresQueryBuilder) Values(vals ...string) QueryBuilder {
+ valsStr := strings.Join(vals, CommaSpace)
+ qb.tokens = append(qb.tokens, "VALUES", "(", valsStr, ")")
+ return qb
+}
+
+// Subquery join the sub as alias
+func (qb *PostgresQueryBuilder) Subquery(sub string, alias string) string {
+ return fmt.Sprintf("(%s) AS %s", sub, alias)
+}
+
+// String join all tokens
+func (qb *PostgresQueryBuilder) String() string {
+ s := strings.Join(qb.tokens, " ")
+ qb.tokens = qb.tokens[:0]
+ return s
+}
diff --git a/src/vendor/github.com/beego/beego/v2/client/orm/qb_tidb.go b/src/vendor/github.com/beego/beego/v2/client/orm/qb_tidb.go
new file mode 100644
index 000000000..772edb5d5
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/qb_tidb.go
@@ -0,0 +1,21 @@
+// Copyright 2015 TiDB Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package orm
+
+// TiDBQueryBuilder is the SQL build
+type TiDBQueryBuilder struct {
+ MySQLQueryBuilder
+ tokens []string
+}
diff --git a/src/vendor/github.com/beego/beego/orm/types.go b/src/vendor/github.com/beego/beego/v2/client/orm/types.go
similarity index 61%
rename from src/vendor/github.com/beego/beego/orm/types.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/types.go
index 2fd10774f..df50a500d 100644
--- a/src/vendor/github.com/beego/beego/orm/types.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/types.go
@@ -19,8 +19,68 @@ import (
"database/sql"
"reflect"
"time"
+
+ "github.com/beego/beego/v2/client/orm/clauses/order_clause"
+ "github.com/beego/beego/v2/core/utils"
)
+// TableNaming is usually used by model
+// when you custom your table name, please implement this interfaces
+// for example:
+// type User struct {
+// ...
+// }
+// func (u *User) TableName() string {
+// return "USER_TABLE"
+// }
+type TableNameI interface {
+ TableName() string
+}
+
+// TableEngineI is usually used by model
+// when you want to use specific engine, like myisam, you can implement this interface
+// for example:
+// type User struct {
+// ...
+// }
+// func (u *User) TableEngine() string {
+// return "myisam"
+// }
+type TableEngineI interface {
+ TableEngine() string
+}
+
+// TableIndexI is usually used by model
+// when you want to create indexes, you can implement this interface
+// for example:
+// type User struct {
+// ...
+// }
+// func (u *User) TableIndex() [][]string {
+// return [][]string{{"Name"}}
+// }
+type TableIndexI interface {
+ TableIndex() [][]string
+}
+
+// TableUniqueI is usually used by model
+// when you want to create unique indexes, you can implement this interface
+// for example:
+// type User struct {
+// ...
+// }
+// func (u *User) TableUnique() [][]string {
+// return [][]string{{"Email"}}
+// }
+type TableUniqueI interface {
+ TableUnique() [][]string
+}
+
+// IsApplicableTableForDB if return false, we won't create table to this db
+type IsApplicableTableForDB interface {
+ IsApplicableTableForDB(db string) bool
+}
+
// Driver define database driver
type Driver interface {
Name() string
@@ -35,35 +95,67 @@ type Fielder interface {
RawValue() interface{}
}
-// Ormer define the orm interface
-type Ormer interface {
- // read data to model
- // for example:
- // this will find User by Id field
- // u = &User{Id: user.Id}
- // err = Ormer.Read(u)
- // this will find User by UserName field
- // u = &User{UserName: "astaxie", Password: "pass"}
- // err = Ormer.Read(u, "UserName")
- Read(md interface{}, cols ...string) error
- // Like Read(), but with "FOR UPDATE" clause, useful in transaction.
- // Some databases are not support this feature.
- ReadForUpdate(md interface{}, cols ...string) error
- // Try to read a row from the database, or insert one if it doesn't exist
- ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error)
+type TxBeginner interface {
+ // self control transaction
+ Begin() (TxOrmer, error)
+ BeginWithCtx(ctx context.Context) (TxOrmer, error)
+ BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error)
+ BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error)
+
+ // closure control transaction
+ DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error
+ DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error
+ DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
+ DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error
+}
+
+type TxCommitter interface {
+ txEnder
+}
+
+// transaction beginner
+type txer interface {
+ Begin() (*sql.Tx, error)
+ BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
+}
+
+// transaction ending
+type txEnder interface {
+ Commit() error
+ Rollback() error
+
+ // RollbackUnlessCommit if the transaction has been committed, do nothing, or transaction will be rollback
+ // For example:
+ // ```go
+ // txOrm := orm.Begin()
+ // defer txOrm.RollbackUnlessCommit()
+ // err := txOrm.Insert() // do something
+ // if err != nil {
+ // return err
+ // }
+ // txOrm.Commit()
+ // ```
+ RollbackUnlessCommit() error
+}
+
+// Data Manipulation Language
+type DML interface {
// insert model data to database
// for example:
// user := new(User)
// id, err = Ormer.Insert(user)
// user must be a pointer and Insert will set user's pk field
- Insert(interface{}) (int64, error)
+ Insert(md interface{}) (int64, error)
+ InsertWithCtx(ctx context.Context, md interface{}) (int64, error)
// mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value")
// if colu type is integer : can use(+-*/), string : convert(colu,"value")
// postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value")
// if colu type is integer : can use(+-*/), string : colu || "value"
InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error)
+ InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error)
// insert some models to database
InsertMulti(bulk int, mds interface{}) (int64, error)
+ InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error)
// update model to database.
// cols set the columns those want to update.
// find model by Id(pk) field and update columns specified by fields, if cols is null then update all columns
@@ -74,66 +166,105 @@ type Ormer interface {
// user.Extra.Data = "orm"
// num, err = Ormer.Update(&user, "Langs", "Extra")
Update(md interface{}, cols ...string) (int64, error)
+ UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error)
// delete model in database
Delete(md interface{}, cols ...string) (int64, error)
+ DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error)
+
+ // return a raw query seter for raw sql string.
+ // for example:
+ // ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec()
+ // // update user testing's name to slene
+ Raw(query string, args ...interface{}) RawSeter
+ RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter
+}
+
+// Data Query Language
+type DQL interface {
+ // read data to model
+ // for example:
+ // this will find User by Id field
+ // u = &User{Id: user.Id}
+ // err = Ormer.Read(u)
+ // this will find User by UserName field
+ // u = &User{UserName: "astaxie", Password: "pass"}
+ // err = Ormer.Read(u, "UserName")
+ Read(md interface{}, cols ...string) error
+ ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error
+
+ // Like Read(), but with "FOR UPDATE" clause, useful in transaction.
+ // Some databases are not support this feature.
+ ReadForUpdate(md interface{}, cols ...string) error
+ ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error
+
+ // Try to read a row from the database, or insert one if it doesn't exist
+ ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error)
+ ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error)
+
// load related models to md model.
// args are limit, offset int and order string.
//
// example:
// Ormer.LoadRelated(post,"Tags")
// for _,tag := range post.Tags{...}
- //args[0] bool true useDefaultRelsDepth ; false depth 0
- //args[0] int loadRelationDepth
- //args[1] int limit default limit 1000
- //args[2] int offset default offset 0
- //args[3] string order for example : "-Id"
+ // hints.DefaultRelDepth useDefaultRelsDepth ; or depth 0
+ // hints.RelDepth loadRelationDepth
+ // hints.Limit limit default limit 1000
+ // hints.Offset int offset default offset 0
+ // hints.OrderBy string order for example : "-Id"
// make sure the relation is defined in model struct tags.
- LoadRelated(md interface{}, name string, args ...interface{}) (int64, error)
+ LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error)
+ LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error)
+
// create a models to models queryer
// for example:
// post := Post{Id: 4}
// m2m := Ormer.QueryM2M(&post, "Tags")
QueryM2M(md interface{}, name string) QueryM2Mer
+ // NOTE: this method is deprecated, context parameter will not take effect.
+ // Use context.Context directly on methods with `WithCtx` suffix such as InsertWithCtx/UpdateWithCtx
+ QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer
+
// return a QuerySeter for table operations.
// table name can be string or struct.
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
QueryTable(ptrStructOrTableName interface{}) QuerySeter
- // switch to another registered database driver by given name.
- Using(name string) error
- // begin transaction
- // for example:
- // o := NewOrm()
- // err := o.Begin()
- // ...
- // err = o.Rollback()
- Begin() error
- // begin transaction with provided context and option
- // the provided context is used until the transaction is committed or rolled back.
- // if the context is canceled, the transaction will be rolled back.
- // the provided TxOptions is optional and may be nil if defaults should be used.
- // if a non-default isolation level is used that the driver doesn't support, an error will be returned.
- // for example:
- // o := NewOrm()
- // err := o.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
- // ...
- // err = o.Rollback()
- BeginTx(ctx context.Context, opts *sql.TxOptions) error
- // commit transaction
- Commit() error
- // rollback transaction
- Rollback() error
- // return a raw query seter for raw sql string.
- // for example:
- // ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec()
- // // update user testing's name to slene
- Raw(query string, args ...interface{}) RawSeter
- Driver() Driver
+ // NOTE: this method is deprecated, context parameter will not take effect.
+ // Use context.Context directly on methods with `WithCtx` suffix such as InsertWithCtx/UpdateWithCtx
+ QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter
+
DBStats() *sql.DBStats
}
+type DriverGetter interface {
+ Driver() Driver
+}
+
+type ormer interface {
+ DQL
+ DML
+ DriverGetter
+}
+
+// QueryExecutor wrapping for ormer
+type QueryExecutor interface {
+ ormer
+}
+
+type Ormer interface {
+ QueryExecutor
+ TxBeginner
+}
+
+type TxOrmer interface {
+ QueryExecutor
+ TxCommitter
+}
+
// Inserter insert prepared statement
type Inserter interface {
Insert(interface{}) (int64, error)
+ InsertWithCtx(context.Context, interface{}) (int64, error)
Close() error
}
@@ -193,6 +324,43 @@ type QuerySeter interface {
// for example:
// qs.OrderBy("-status")
OrderBy(exprs ...string) QuerySeter
+ // add ORDER expression by order clauses
+ // for example:
+ // OrderClauses(
+ // order_clause.Clause(
+ // order.Column("Id"),
+ // order.SortAscending(),
+ // ),
+ // order_clause.Clause(
+ // order.Column("status"),
+ // order.SortDescending(),
+ // ),
+ // )
+ // OrderClauses(order_clause.Clause(
+ // order_clause.Column(`user__status`),
+ // order_clause.SortDescending(),//default None
+ // ))
+ // OrderClauses(order_clause.Clause(
+ // order_clause.Column(`random()`),
+ // order_clause.SortNone(),//default None
+ // order_clause.Raw(),//default false.if true, do not check field is valid or not
+ // ))
+ OrderClauses(orders ...*order_clause.Order) QuerySeter
+ // add FORCE INDEX expression.
+ // for example:
+ // qs.ForceIndex(`idx_name1`,`idx_name2`)
+ // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive
+ ForceIndex(indexes ...string) QuerySeter
+ // add USE INDEX expression.
+ // for example:
+ // qs.UseIndex(`idx_name1`,`idx_name2`)
+ // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive
+ UseIndex(indexes ...string) QuerySeter
+ // add IGNORE INDEX expression.
+ // for example:
+ // qs.IgnoreIndex(`idx_name1`,`idx_name2`)
+ // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive
+ IgnoreIndex(indexes ...string) QuerySeter
// set relation model to query together.
// it will query relation models and assign to parent model.
// for example:
@@ -216,9 +384,11 @@ type QuerySeter interface {
// for example:
// num, err = qs.Filter("profile__age__gt", 28).Count()
Count() (int64, error)
+ CountWithCtx(context.Context) (int64, error)
// check result empty or not after QuerySeter executed
// the same as QuerySeter.Count > 0
Exist() bool
+ ExistWithCtx(context.Context) bool
// execute update with parameters
// for example:
// num, err = qs.Filter("user_name", "slene").Update(Params{
@@ -228,12 +398,14 @@ type QuerySeter interface {
// "user_name": "slene2"
// }) // user slene's name will change to slene2
Update(values Params) (int64, error)
+ UpdateWithCtx(ctx context.Context, values Params) (int64, error)
// delete from table
- //for example:
+ // for example:
// num ,err = qs.Filter("user_name__in", "testing1", "testing2").Delete()
// //delete two user who's name is testing1 or testing2
Delete() (int64, error)
- // return a insert queryer.
+ DeleteWithCtx(context.Context) (int64, error)
+ // return an insert queryer.
// it can be used in times.
// example:
// i,err := sq.PrepareInsert()
@@ -241,18 +413,21 @@ type QuerySeter interface {
// num, err = i.Insert(&user2) // user table will add one record user2 at once
// err = i.Close() //don't forget call Close
PrepareInsert() (Inserter, error)
+ PrepareInsertWithCtx(context.Context) (Inserter, error)
// query all data and map to containers.
// cols means the columns when querying.
// for example:
// var users []*User
// qs.All(&users) // users[0],users[1],users[2] ...
All(container interface{}, cols ...string) (int64, error)
+ AllWithCtx(ctx context.Context, container interface{}, cols ...string) (int64, error)
// query one row data and map to containers.
// cols means the columns when querying.
// for example:
// var user User
// qs.One(&user) //user.UserName == "slene"
One(container interface{}, cols ...string) error
+ OneWithCtx(ctx context.Context, container interface{}, cols ...string) error
// query all data and map to []map[string]interface.
// expres means condition expression.
// it converts data to []map[column]value.
@@ -260,18 +435,21 @@ type QuerySeter interface {
// var maps []Params
// qs.Values(&maps) //maps[0]["UserName"]=="slene"
Values(results *[]Params, exprs ...string) (int64, error)
+ ValuesWithCtx(ctx context.Context, results *[]Params, exprs ...string) (int64, error)
// query all data and map to [][]interface
// it converts data to [][column_index]value
// for example:
// var list []ParamsList
// qs.ValuesList(&list) // list[0][1] == "slene"
ValuesList(results *[]ParamsList, exprs ...string) (int64, error)
+ ValuesListWithCtx(ctx context.Context, results *[]ParamsList, exprs ...string) (int64, error)
// query all data and map to []interface.
// it's designed for one column record set, auto change to []value, not [][column]value.
// for example:
// var list ParamsList
// qs.ValuesFlat(&list, "UserName") // list[0] == "slene"
ValuesFlat(result *ParamsList, expr string) (int64, error)
+ ValuesFlatWithCtx(ctx context.Context, result *ParamsList, expr string) (int64, error)
// query all rows into map[string]interface with specify key and value column name.
// keyCol = "name", valueCol = "value"
// table data
@@ -294,6 +472,15 @@ type QuerySeter interface {
// Found int
// }
RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error)
+ // aggregate func.
+ // for example:
+ // type result struct {
+ // DeptName string
+ // Total int
+ // }
+ // var res []result
+ // o.QueryTable("dept_info").Aggregate("dept_name,sum(salary) as total").GroupBy("dept_name").All(&res)
+ Aggregate(s string) QuerySeter
}
// QueryM2Mer model to model query struct
@@ -311,18 +498,23 @@ type QueryM2Mer interface {
// insert one or more rows to m2m table
// make sure the relation is defined in post model struct tag.
Add(...interface{}) (int64, error)
+ AddWithCtx(context.Context, ...interface{}) (int64, error)
// remove models following the origin model relationship
// only delete rows from m2m table
// for example:
- //tag3 := &Tag{Id:5,Name: "TestTag3"}
- //num, err = m2m.Remove(tag3)
+ // tag3 := &Tag{Id:5,Name: "TestTag3"}
+ // num, err = m2m.Remove(tag3)
Remove(...interface{}) (int64, error)
+ RemoveWithCtx(context.Context, ...interface{}) (int64, error)
// check model is existed in relationship of origin model
Exist(interface{}) bool
+ ExistWithCtx(context.Context, interface{}) bool
// clean all models in related of origin model
Clear() (int64, error)
+ ClearWithCtx(context.Context) (int64, error)
// count all related models of origin model
Count() (int64, error)
+ CountWithCtx(context.Context) (int64, error)
}
// RawPreparer raw query statement
@@ -337,10 +529,10 @@ type RawPreparer interface {
// sql := fmt.Sprintf("SELECT %sid%s,%sname%s FROM %suser%s WHERE id = ?",Q,Q,Q,Q,Q,Q)
// rs := Ormer.Raw(sql, 1)
type RawSeter interface {
- //execute sql and get result
+ // execute sql and get result
Exec() (sql.Result, error)
- //query data and map to container
- //for example:
+ // query data and map to container
+ // for example:
// var name string
// var id int
// rs.QueryRow(&id,&name) // id==2 name=="slene"
@@ -396,11 +588,11 @@ type RawSeter interface {
type stmtQuerier interface {
Close() error
Exec(args ...interface{}) (sql.Result, error)
- //ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error)
+ ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error)
Query(args ...interface{}) (*sql.Rows, error)
- //QueryContext(args ...interface{}) (*sql.Rows, error)
+ QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error)
QueryRow(args ...interface{}) *sql.Row
- //QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row
+ QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row
}
// db querier
@@ -423,39 +615,30 @@ type dbQuerier interface {
// QueryRow(query string, args ...interface{}) *sql.Row
// }
-// transaction beginner
-type txer interface {
- Begin() (*sql.Tx, error)
- BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
-}
-
-// transaction ending
-type txEnder interface {
- Commit() error
- Rollback() error
-}
-
// base database struct
type dbBaser interface {
- Read(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string, bool) error
- Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
- InsertOrUpdate(dbQuerier, *modelInfo, reflect.Value, *alias, ...string) (int64, error)
- InsertMulti(dbQuerier, *modelInfo, reflect.Value, int, *time.Location) (int64, error)
- InsertValue(dbQuerier, *modelInfo, bool, []string, []interface{}) (int64, error)
- InsertStmt(stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
- Update(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error)
- Delete(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error)
- ReadBatch(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, *time.Location, []string) (int64, error)
+ Read(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location, []string, bool) error
+ ReadBatch(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, interface{}, *time.Location, []string) (int64, error)
+ Count(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
+ ReadValues(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error)
+
+ Insert(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
+ InsertOrUpdate(context.Context, dbQuerier, *modelInfo, reflect.Value, *alias, ...string) (int64, error)
+ InsertMulti(context.Context, dbQuerier, *modelInfo, reflect.Value, int, *time.Location) (int64, error)
+ InsertValue(context.Context, dbQuerier, *modelInfo, bool, []string, []interface{}) (int64, error)
+ InsertStmt(context.Context, stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
+
+ Update(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error)
+ UpdateBatch(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, Params, *time.Location) (int64, error)
+
+ Delete(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error)
+ DeleteBatch(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
+
SupportUpdateJoin() bool
- UpdateBatch(dbQuerier, *querySet, *modelInfo, *Condition, Params, *time.Location) (int64, error)
- DeleteBatch(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
- Count(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
OperatorSQL(string) string
GenerateOperatorSQL(*modelInfo, *fieldInfo, string, []interface{}, *time.Location) (string, []interface{})
GenerateOperatorLeftCol(*fieldInfo, string, *string)
- PrepareInsert(dbQuerier, *modelInfo) (stmtQuerier, string, error)
- ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error)
- RowsTo(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, string, string, *time.Location) (int64, error)
+ PrepareInsert(context.Context, dbQuerier, *modelInfo) (stmtQuerier, string, error)
MaxLimit() uint64
TableQuote() string
ReplaceMarks(*string)
@@ -464,10 +647,12 @@ type dbBaser interface {
TimeToDB(*time.Time, *time.Location)
DbTypes() map[string]string
GetTables(dbQuerier) (map[string]bool, error)
- GetColumns(dbQuerier, string) (map[string][3]string, error)
+ GetColumns(context.Context, dbQuerier, string) (map[string][3]string, error)
ShowTablesQuery() string
ShowColumnsQuery(string) string
- IndexExists(dbQuerier, string, string) bool
+ IndexExists(context.Context, dbQuerier, string, string) bool
collectFieldValue(*modelInfo, *fieldInfo, reflect.Value, bool, *time.Location) (interface{}, error)
- setval(dbQuerier, *modelInfo, []string) error
+ setval(context.Context, dbQuerier, *modelInfo, []string) error
+
+ GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string
}
diff --git a/src/vendor/github.com/beego/beego/orm/utils.go b/src/vendor/github.com/beego/beego/v2/client/orm/utils.go
similarity index 97%
rename from src/vendor/github.com/beego/beego/orm/utils.go
rename to src/vendor/github.com/beego/beego/v2/client/orm/utils.go
index 3ff76772e..8d05c0801 100644
--- a/src/vendor/github.com/beego/beego/orm/utils.go
+++ b/src/vendor/github.com/beego/beego/v2/client/orm/utils.go
@@ -49,12 +49,12 @@ func (f *StrTo) Set(v string) {
// Clear string
func (f *StrTo) Clear() {
- *f = StrTo(0x1E)
+ *f = StrTo(rune(0x1E))
}
// Exist check string exist
func (f StrTo) Exist() bool {
- return string(f) != string(0x1E)
+ return string(f) != string(rune(0x1E))
}
// Bool string to bool
@@ -228,7 +228,7 @@ func snakeStringWithAcronym(s string) string {
}
data = append(data, d)
}
- return strings.ToLower(string(data[:]))
+ return strings.ToLower(string(data))
}
// snake string, XxYy to xx_yy , XxYY to xx_y_y
@@ -246,7 +246,7 @@ func snakeString(s string) string {
}
data = append(data, d)
}
- return strings.ToLower(string(data[:]))
+ return strings.ToLower(string(data))
}
// SetNameStrategy set different name strategy
@@ -274,7 +274,7 @@ func camelString(s string) string {
}
data = append(data, d)
}
- return string(data[:])
+ return string(data)
}
type argString []string
diff --git a/src/vendor/github.com/beego/beego/v2/core/admin/command.go b/src/vendor/github.com/beego/beego/v2/core/admin/command.go
new file mode 100644
index 000000000..f65d27501
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/admin/command.go
@@ -0,0 +1,87 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package admin
+
+import (
+ "github.com/pkg/errors"
+)
+
+// Command is an experimental interface
+// We try to use this to decouple modules
+// All other modules depends on this, and they register the command they support
+// We may change the API in the future, so be careful about this.
+type Command interface {
+ Execute(params ...interface{}) *Result
+}
+
+var CommandNotFound = errors.New("Command not found")
+
+type Result struct {
+ // Status is the same as http.Status
+ Status int
+ Error error
+ Content interface{}
+}
+
+func (r *Result) IsSuccess() bool {
+ return r.Status >= 200 && r.Status < 300
+}
+
+// CommandRegistry stores all commands
+// name => command
+type moduleCommands map[string]Command
+
+// Get returns command with the name
+func (m moduleCommands) Get(name string) Command {
+ c, ok := m[name]
+ if ok {
+ return c
+ }
+ return &doNothingCommand{}
+}
+
+// module name => moduleCommand
+type commandRegistry map[string]moduleCommands
+
+// Get returns module's commands
+func (c commandRegistry) Get(moduleName string) moduleCommands {
+ if mcs, ok := c[moduleName]; ok {
+ return mcs
+ }
+ res := make(moduleCommands)
+ c[moduleName] = res
+ return res
+}
+
+var cmdRegistry = make(commandRegistry)
+
+// RegisterCommand is not thread-safe
+// do not use it in concurrent case
+func RegisterCommand(module string, commandName string, command Command) {
+ cmdRegistry.Get(module)[commandName] = command
+}
+
+func GetCommand(module string, cmdName string) Command {
+ return cmdRegistry.Get(module).Get(cmdName)
+}
+
+type doNothingCommand struct{}
+
+func (d *doNothingCommand) Execute(params ...interface{}) *Result {
+ return &Result{
+ Status: 404,
+ Error: CommandNotFound,
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/toolbox/healthcheck.go b/src/vendor/github.com/beego/beego/v2/core/admin/healthcheck.go
similarity index 92%
rename from src/vendor/github.com/beego/beego/toolbox/healthcheck.go
rename to src/vendor/github.com/beego/beego/v2/core/admin/healthcheck.go
index e3544b3ad..73a6cb089 100644
--- a/src/vendor/github.com/beego/beego/toolbox/healthcheck.go
+++ b/src/vendor/github.com/beego/beego/v2/core/admin/healthcheck.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Package toolbox healthcheck
+// Package admin healthcheck
//
// type DatabaseCheck struct {
// }
@@ -27,8 +27,8 @@
//
// AddHealthCheck("database",&DatabaseCheck{})
//
-// more docs: http://beego.me/docs/module/toolbox.md
-package toolbox
+// more docs: http://beego.vip/docs/module/toolbox.md
+package admin
// AdminCheckList holds health checker map
var AdminCheckList map[string]HealthChecker
diff --git a/src/vendor/github.com/beego/beego/toolbox/profile.go b/src/vendor/github.com/beego/beego/v2/core/admin/profile.go
similarity index 79%
rename from src/vendor/github.com/beego/beego/toolbox/profile.go
rename to src/vendor/github.com/beego/beego/v2/core/admin/profile.go
index 06e40ede7..f85afaa2c 100644
--- a/src/vendor/github.com/beego/beego/toolbox/profile.go
+++ b/src/vendor/github.com/beego/beego/v2/core/admin/profile.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package toolbox
+package admin
import (
"fmt"
@@ -25,10 +25,14 @@ import (
"runtime/pprof"
"strconv"
"time"
+
+ "github.com/beego/beego/v2/core/utils"
)
-var startTime = time.Now()
-var pid int
+var (
+ startTime = time.Now()
+ pid int
+)
func init() {
pid = os.Getpid()
@@ -103,27 +107,26 @@ func PrintGCSummary(w io.Writer) {
}
func printGC(memStats *runtime.MemStats, gcstats *debug.GCStats, w io.Writer) {
-
if gcstats.NumGC > 0 {
lastPause := gcstats.Pause[0]
- elapsed := time.Now().Sub(startTime)
+ elapsed := time.Since(startTime)
overhead := float64(gcstats.PauseTotal) / float64(elapsed) * 100
allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds()
fmt.Fprintf(w, "NumGC:%d Pause:%s Pause(Avg):%s Overhead:%3.2f%% Alloc:%s Sys:%s Alloc(Rate):%s/s Histogram:%s %s %s \n",
gcstats.NumGC,
- toS(lastPause),
- toS(avg(gcstats.Pause)),
+ utils.ToShortTimeFormat(lastPause),
+ utils.ToShortTimeFormat(avg(gcstats.Pause)),
overhead,
toH(memStats.Alloc),
toH(memStats.Sys),
toH(uint64(allocatedRate)),
- toS(gcstats.PauseQuantiles[94]),
- toS(gcstats.PauseQuantiles[98]),
- toS(gcstats.PauseQuantiles[99]))
+ utils.ToShortTimeFormat(gcstats.PauseQuantiles[94]),
+ utils.ToShortTimeFormat(gcstats.PauseQuantiles[98]),
+ utils.ToShortTimeFormat(gcstats.PauseQuantiles[99]))
} else {
// while GC has disabled
- elapsed := time.Now().Sub(startTime)
+ elapsed := time.Since(startTime)
allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds()
fmt.Fprintf(w, "Alloc:%s Sys:%s Alloc(Rate):%s/s\n",
@@ -141,7 +144,7 @@ func avg(items []time.Duration) time.Duration {
return time.Duration(int64(sum) / int64(len(items)))
}
-// format bytes number friendly
+// toH format bytes number friendly
func toH(bytes uint64) string {
switch {
case bytes < 1024:
@@ -154,31 +157,3 @@ func toH(bytes uint64) string {
return fmt.Sprintf("%.2fG", float64(bytes)/1024/1024/1024)
}
}
-
-// short string format
-func toS(d time.Duration) string {
-
- u := uint64(d)
- if u < uint64(time.Second) {
- switch {
- case u == 0:
- return "0"
- case u < uint64(time.Microsecond):
- return fmt.Sprintf("%.2fns", float64(u))
- case u < uint64(time.Millisecond):
- return fmt.Sprintf("%.2fus", float64(u)/1000)
- default:
- return fmt.Sprintf("%.2fms", float64(u)/1000/1000)
- }
- } else {
- switch {
- case u < uint64(time.Minute):
- return fmt.Sprintf("%.2fs", float64(u)/1000/1000/1000)
- case u < uint64(time.Hour):
- return fmt.Sprintf("%.2fm", float64(u)/1000/1000/1000/60)
- default:
- return fmt.Sprintf("%.2fh", float64(u)/1000/1000/1000/60/60)
- }
- }
-
-}
diff --git a/src/vendor/github.com/beego/beego/v2/core/berror/codes.go b/src/vendor/github.com/beego/beego/v2/core/berror/codes.go
new file mode 100644
index 000000000..b6712a847
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/berror/codes.go
@@ -0,0 +1,86 @@
+// Copyright 2020 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package berror
+
+import (
+ "fmt"
+ "sync"
+)
+
+// A Code is an unsigned 32-bit error code as defined in the beego spec.
+type Code interface {
+ Code() uint32
+ Module() string
+ Desc() string
+ Name() string
+}
+
+var defaultCodeRegistry = &codeRegistry{
+ codes: make(map[uint32]*codeDefinition, 127),
+}
+
+// DefineCode defining a new Code
+// Before defining a new code, please read Beego specification.
+// desc could be markdown doc
+func DefineCode(code uint32, module string, name string, desc string) Code {
+ res := &codeDefinition{
+ code: code,
+ module: module,
+ desc: desc,
+ }
+ defaultCodeRegistry.lock.Lock()
+ defer defaultCodeRegistry.lock.Unlock()
+
+ if _, ok := defaultCodeRegistry.codes[code]; ok {
+ panic(fmt.Sprintf("duplicate code, code %d has been registered", code))
+ }
+ defaultCodeRegistry.codes[code] = res
+ return res
+}
+
+type codeRegistry struct {
+ lock sync.RWMutex
+ codes map[uint32]*codeDefinition
+}
+
+func (cr *codeRegistry) Get(code uint32) (Code, bool) {
+ cr.lock.RLock()
+ defer cr.lock.RUnlock()
+ c, ok := cr.codes[code]
+ return c, ok
+}
+
+type codeDefinition struct {
+ code uint32
+ module string
+ desc string
+ name string
+}
+
+func (c *codeDefinition) Name() string {
+ return c.name
+}
+
+func (c *codeDefinition) Code() uint32 {
+ return c.code
+}
+
+func (c *codeDefinition) Module() string {
+ return c.module
+}
+
+func (c *codeDefinition) Desc() string {
+ return c.desc
+}
diff --git a/src/vendor/github.com/beego/beego/v2/core/berror/error.go b/src/vendor/github.com/beego/beego/v2/core/berror/error.go
new file mode 100644
index 000000000..c40009c68
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/berror/error.go
@@ -0,0 +1,69 @@
+// Copyright 2020 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package berror
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/pkg/errors"
+)
+
+// code, msg
+const errFmt = "ERROR-%d, %s"
+
+// Error returns an error representing c and msg. If c is OK, returns nil.
+func Error(c Code, msg string) error {
+ return fmt.Errorf(errFmt, c.Code(), msg)
+}
+
+// Errorf returns error
+func Errorf(c Code, format string, a ...interface{}) error {
+ return Error(c, fmt.Sprintf(format, a...))
+}
+
+func Wrap(err error, c Code, msg string) error {
+ if err == nil {
+ return nil
+ }
+ return errors.Wrap(err, fmt.Sprintf(errFmt, c.Code(), msg))
+}
+
+func Wrapf(err error, c Code, format string, a ...interface{}) error {
+ return Wrap(err, c, fmt.Sprintf(format, a...))
+}
+
+// FromError is very simple. It just parse error msg and check whether code has been register
+// if code not being register, return unknown
+// if err.Error() is not valid beego error code, return unknown
+func FromError(err error) (Code, bool) {
+ msg := err.Error()
+ codeSeg := strings.SplitN(msg, ",", 2)
+ if strings.HasPrefix(codeSeg[0], "ERROR-") {
+ codeStr := strings.SplitN(codeSeg[0], "-", 2)
+ if len(codeStr) < 2 {
+ return Unknown, false
+ }
+ codeInt, e := strconv.ParseUint(codeStr[1], 10, 32)
+ if e != nil {
+ return Unknown, false
+ }
+ if code, ok := defaultCodeRegistry.Get(uint32(codeInt)); ok {
+ return code, true
+ }
+ }
+ return Unknown, false
+}
diff --git a/src/vendor/github.com/beego/beego/v2/core/berror/pre_define_code.go b/src/vendor/github.com/beego/beego/v2/core/berror/pre_define_code.go
new file mode 100644
index 000000000..ff8eb46b6
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/berror/pre_define_code.go
@@ -0,0 +1,52 @@
+// Copyright 2021 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package berror
+
+import (
+ "fmt"
+)
+
+// pre define code
+
+// Unknown indicates got some error which is not defined
+var Unknown = DefineCode(5000001, "error", "Unknown", fmt.Sprintf(`
+Unknown error code. Usually you will see this code in three cases:
+1. You forget to define Code or function DefineCode not being executed;
+2. This is not Beego's error but you call FromError();
+3. Beego got unexpected error and don't know how to handle it, and then return Unknown error
+
+A common practice to DefineCode looks like:
+%s
+
+In this way, you may forget to import this package, and got Unknown error.
+
+Sometimes, you believe you got Beego error, but actually you don't, and then you call FromError(err)
+
+`, goCodeBlock(`
+import your_package
+
+func init() {
+ DefineCode(5100100, "your_module", "detail")
+ // ...
+}
+`)))
+
+func goCodeBlock(code string) string {
+ return codeBlock("go", code)
+}
+
+func codeBlock(lan string, code string) string {
+ return fmt.Sprintf("```%s\n%s\n```", lan, code)
+}
diff --git a/src/vendor/github.com/beego/beego/config/config.go b/src/vendor/github.com/beego/beego/v2/core/config/config.go
similarity index 63%
rename from src/vendor/github.com/beego/beego/config/config.go
rename to src/vendor/github.com/beego/beego/v2/core/config/config.go
index b115f0c95..9e84f059c 100644
--- a/src/vendor/github.com/beego/beego/config/config.go
+++ b/src/vendor/github.com/beego/beego/v2/core/config/config.go
@@ -14,8 +14,8 @@
// Package config is used to parse config.
// Usage:
-// import "github.com/beego/beego/config"
-//Examples.
+// import "github.com/beego/beego/v2/core/config"
+// Examples.
//
// cnf, err := config.NewConfig("ini", "config.conf")
//
@@ -37,36 +37,164 @@
// cnf.DIY(key string) (interface{}, error)
// cnf.GetSection(section string) (map[string]string, error)
// cnf.SaveConfigFile(filename string) error
-//More docs http://beego.me/docs/module/config.md
+// More docs http://beego.vip/docs/module/config.md
package config
import (
+ "context"
+ "errors"
"fmt"
"os"
"reflect"
+ "strconv"
+ "strings"
"time"
)
// Configer defines how to get and set value from configuration raw data.
type Configer interface {
- Set(key, val string) error //support section::key type in given key when using ini type.
- String(key string) string //support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
- Strings(key string) []string //get string slice
+ // Set support section::key type in given key when using ini type.
+ Set(key, val string) error
+
+ // String support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
+ String(key string) (string, error)
+ // Strings get string slice
+ Strings(key string) ([]string, error)
Int(key string) (int, error)
Int64(key string) (int64, error)
Bool(key string) (bool, error)
Float(key string) (float64, error)
- DefaultString(key string, defaultVal string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
- DefaultStrings(key string, defaultVal []string) []string //get string slice
+ // DefaultString support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
+ DefaultString(key string, defaultVal string) string
+ // DefaultStrings get string slice
+ DefaultStrings(key string, defaultVal []string) []string
DefaultInt(key string, defaultVal int) int
DefaultInt64(key string, defaultVal int64) int64
DefaultBool(key string, defaultVal bool) bool
DefaultFloat(key string, defaultVal float64) float64
+
+ // DIY return the original value
DIY(key string) (interface{}, error)
+
GetSection(section string) (map[string]string, error)
+
+ Unmarshaler(prefix string, obj interface{}, opt ...DecodeOption) error
+ Sub(key string) (Configer, error)
+ OnChange(key string, fn func(value string))
SaveConfigFile(filename string) error
}
+type BaseConfiger struct {
+ // The reader should support key like "a.b.c"
+ reader func(ctx context.Context, key string) (string, error)
+}
+
+func NewBaseConfiger(reader func(ctx context.Context, key string) (string, error)) BaseConfiger {
+ return BaseConfiger{
+ reader: reader,
+ }
+}
+
+func (c *BaseConfiger) Int(key string) (int, error) {
+ res, err := c.reader(context.TODO(), key)
+ if err != nil {
+ return 0, err
+ }
+ return strconv.Atoi(res)
+}
+
+func (c *BaseConfiger) Int64(key string) (int64, error) {
+ res, err := c.reader(context.TODO(), key)
+ if err != nil {
+ return 0, err
+ }
+ return strconv.ParseInt(res, 10, 64)
+}
+
+func (c *BaseConfiger) Bool(key string) (bool, error) {
+ res, err := c.reader(context.TODO(), key)
+ if err != nil {
+ return false, err
+ }
+ return ParseBool(res)
+}
+
+func (c *BaseConfiger) Float(key string) (float64, error) {
+ res, err := c.reader(context.TODO(), key)
+ if err != nil {
+ return 0, err
+ }
+ return strconv.ParseFloat(res, 64)
+}
+
+// DefaultString returns the string value for a given key.
+// if err != nil or value is empty return defaultval
+func (c *BaseConfiger) DefaultString(key string, defaultVal string) string {
+ if res, err := c.String(key); res != "" && err == nil {
+ return res
+ }
+ return defaultVal
+}
+
+// DefaultStrings returns the []string value for a given key.
+// if err != nil return defaultval
+func (c *BaseConfiger) DefaultStrings(key string, defaultVal []string) []string {
+ if res, err := c.Strings(key); len(res) > 0 && err == nil {
+ return res
+ }
+ return defaultVal
+}
+
+func (c *BaseConfiger) DefaultInt(key string, defaultVal int) int {
+ if res, err := c.Int(key); err == nil {
+ return res
+ }
+ return defaultVal
+}
+
+func (c *BaseConfiger) DefaultInt64(key string, defaultVal int64) int64 {
+ if res, err := c.Int64(key); err == nil {
+ return res
+ }
+ return defaultVal
+}
+
+func (c *BaseConfiger) DefaultBool(key string, defaultVal bool) bool {
+ if res, err := c.Bool(key); err == nil {
+ return res
+ }
+ return defaultVal
+}
+
+func (c *BaseConfiger) DefaultFloat(key string, defaultVal float64) float64 {
+ if res, err := c.Float(key); err == nil {
+ return res
+ }
+ return defaultVal
+}
+
+func (c *BaseConfiger) String(key string) (string, error) {
+ return c.reader(context.TODO(), key)
+}
+
+// Strings returns the []string value for a given key.
+// Return nil if config value does not exist or is empty.
+func (c *BaseConfiger) Strings(key string) ([]string, error) {
+ res, err := c.String(key)
+ if err != nil || res == "" {
+ return nil, err
+ }
+ return strings.Split(res, ";"), nil
+}
+
+func (*BaseConfiger) Sub(string) (Configer, error) {
+ return nil, errors.New("unsupported operation")
+}
+
+func (*BaseConfiger) OnChange(_ string, _ func(value string)) {
+ // do nothing
+}
+
// Config is the adapter interface for parsing config file to get raw data to Configer.
type Config interface {
Parse(key string) (Configer, error)
@@ -121,6 +249,12 @@ func ExpandValueEnvForMap(m map[string]interface{}) map[string]interface{} {
value[k2] = ExpandValueEnv(v2)
}
m[k] = value
+ case map[interface{}]interface{}:
+ tmp := make(map[string]interface{}, len(value))
+ for k2, v2 := range value {
+ tmp[k2.(string)] = v2
+ }
+ m[k] = ExpandValueEnvForMap(tmp)
}
}
return m
@@ -240,3 +374,7 @@ func ToString(x interface{}) string {
// Fallback to fmt package for anything else like numeric types
return fmt.Sprint(x)
}
+
+type DecodeOption func(options decodeOptions)
+
+type decodeOptions struct{}
diff --git a/src/vendor/github.com/beego/beego/v2/core/config/error.go b/src/vendor/github.com/beego/beego/v2/core/config/error.go
new file mode 100644
index 000000000..e4636c452
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/config/error.go
@@ -0,0 +1,25 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "github.com/pkg/errors"
+)
+
+// now not all implementation return those error codes
+var (
+ KeyNotFoundError = errors.New("the key is not found")
+ InvalidValueTypeError = errors.New("the value is not expected type")
+)
diff --git a/src/vendor/github.com/beego/beego/config/fake.go b/src/vendor/github.com/beego/beego/v2/core/config/fake.go
similarity index 71%
rename from src/vendor/github.com/beego/beego/config/fake.go
rename to src/vendor/github.com/beego/beego/v2/core/config/fake.go
index d21ab820d..3f6f46827 100644
--- a/src/vendor/github.com/beego/beego/config/fake.go
+++ b/src/vendor/github.com/beego/beego/v2/core/config/fake.go
@@ -15,12 +15,14 @@
package config
import (
+ "context"
"errors"
"strconv"
"strings"
)
type fakeConfigContainer struct {
+ BaseConfiger
data map[string]string
}
@@ -33,42 +35,14 @@ func (c *fakeConfigContainer) Set(key, val string) error {
return nil
}
-func (c *fakeConfigContainer) String(key string) string {
- return c.getData(key)
-}
-
-func (c *fakeConfigContainer) DefaultString(key string, defaultval string) string {
- v := c.String(key)
- if v == "" {
- return defaultval
- }
- return v
-}
-
-func (c *fakeConfigContainer) Strings(key string) []string {
- v := c.String(key)
- if v == "" {
- return nil
- }
- return strings.Split(v, ";")
-}
-
-func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string {
- v := c.Strings(key)
- if v == nil {
- return defaultval
- }
- return v
-}
-
func (c *fakeConfigContainer) Int(key string) (int, error) {
return strconv.Atoi(c.getData(key))
}
-func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int {
+func (c *fakeConfigContainer) DefaultInt(key string, defaultVal int) int {
v, err := c.Int(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
@@ -77,10 +51,10 @@ func (c *fakeConfigContainer) Int64(key string) (int64, error) {
return strconv.ParseInt(c.getData(key), 10, 64)
}
-func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
+func (c *fakeConfigContainer) DefaultInt64(key string, defaultVal int64) int64 {
v, err := c.Int64(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
@@ -89,10 +63,10 @@ func (c *fakeConfigContainer) Bool(key string) (bool, error) {
return ParseBool(c.getData(key))
}
-func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool {
+func (c *fakeConfigContainer) DefaultBool(key string, defaultVal bool) bool {
v, err := c.Bool(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
@@ -101,10 +75,10 @@ func (c *fakeConfigContainer) Float(key string) (float64, error) {
return strconv.ParseFloat(c.getData(key), 64)
}
-func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
+func (c *fakeConfigContainer) DefaultFloat(key string, defaultVal float64) float64 {
v, err := c.Float(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
@@ -124,11 +98,19 @@ func (c *fakeConfigContainer) SaveConfigFile(filename string) error {
return errors.New("not implement in the fakeConfigContainer")
}
+func (c *fakeConfigContainer) Unmarshaler(prefix string, obj interface{}, opt ...DecodeOption) error {
+ return errors.New("unsupported operation")
+}
+
var _ Configer = new(fakeConfigContainer)
// NewFakeConfig return a fake Configer
func NewFakeConfig() Configer {
- return &fakeConfigContainer{
+ res := &fakeConfigContainer{
data: make(map[string]string),
}
+ res.BaseConfiger = NewBaseConfiger(func(ctx context.Context, key string) (string, error) {
+ return res.getData(key), nil
+ })
+ return res
}
diff --git a/src/vendor/github.com/beego/beego/v2/core/config/global.go b/src/vendor/github.com/beego/beego/v2/core/config/global.go
new file mode 100644
index 000000000..6f692fce5
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/config/global.go
@@ -0,0 +1,111 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+// We use this to simply application's development
+// for most users, they only need to use those methods
+var globalInstance Configer
+
+// InitGlobalInstance will ini the global instance
+// If you want to use specific implementation, don't forget to import it.
+// e.g. _ import "github.com/beego/beego/v2/core/config/etcd"
+// err := InitGlobalInstance("etcd", "someconfig")
+func InitGlobalInstance(name string, cfg string) error {
+ var err error
+ globalInstance, err = NewConfig(name, cfg)
+ return err
+}
+
+// Set support section::key type in given key when using ini type.
+func Set(key, val string) error {
+ return globalInstance.Set(key, val)
+}
+
+// String support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
+func String(key string) (string, error) {
+ return globalInstance.String(key)
+}
+
+// Strings will get string slice
+func Strings(key string) ([]string, error) {
+ return globalInstance.Strings(key)
+}
+
+func Int(key string) (int, error) {
+ return globalInstance.Int(key)
+}
+
+func Int64(key string) (int64, error) {
+ return globalInstance.Int64(key)
+}
+
+func Bool(key string) (bool, error) {
+ return globalInstance.Bool(key)
+}
+
+func Float(key string) (float64, error) {
+ return globalInstance.Float(key)
+}
+
+// DefaultString support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
+func DefaultString(key string, defaultVal string) string {
+ return globalInstance.DefaultString(key, defaultVal)
+}
+
+// DefaultStrings will get string slice
+func DefaultStrings(key string, defaultVal []string) []string {
+ return globalInstance.DefaultStrings(key, defaultVal)
+}
+
+func DefaultInt(key string, defaultVal int) int {
+ return globalInstance.DefaultInt(key, defaultVal)
+}
+
+func DefaultInt64(key string, defaultVal int64) int64 {
+ return globalInstance.DefaultInt64(key, defaultVal)
+}
+
+func DefaultBool(key string, defaultVal bool) bool {
+ return globalInstance.DefaultBool(key, defaultVal)
+}
+
+func DefaultFloat(key string, defaultVal float64) float64 {
+ return globalInstance.DefaultFloat(key, defaultVal)
+}
+
+// DIY return the original value
+func DIY(key string) (interface{}, error) {
+ return globalInstance.DIY(key)
+}
+
+func GetSection(section string) (map[string]string, error) {
+ return globalInstance.GetSection(section)
+}
+
+func Unmarshaler(prefix string, obj interface{}, opt ...DecodeOption) error {
+ return globalInstance.Unmarshaler(prefix, obj, opt...)
+}
+
+func Sub(key string) (Configer, error) {
+ return globalInstance.Sub(key)
+}
+
+func OnChange(key string, fn func(value string)) {
+ globalInstance.OnChange(key, fn)
+}
+
+func SaveConfigFile(filename string) error {
+ return globalInstance.SaveConfigFile(filename)
+}
diff --git a/src/vendor/github.com/beego/beego/config/ini.go b/src/vendor/github.com/beego/beego/v2/core/config/ini.go
similarity index 84%
rename from src/vendor/github.com/beego/beego/config/ini.go
rename to src/vendor/github.com/beego/beego/v2/core/config/ini.go
index 002e5e056..d4dea2e39 100644
--- a/src/vendor/github.com/beego/beego/config/ini.go
+++ b/src/vendor/github.com/beego/beego/v2/core/config/ini.go
@@ -17,6 +17,7 @@ package config
import (
"bufio"
"bytes"
+ "context"
"errors"
"io"
"io/ioutil"
@@ -26,6 +27,10 @@ import (
"strconv"
"strings"
"sync"
+
+ "github.com/mitchellh/mapstructure"
+
+ "github.com/beego/beego/v2/core/logs"
)
var (
@@ -41,8 +46,7 @@ var (
)
// IniConfig implements Config to parse ini file.
-type IniConfig struct {
-}
+type IniConfig struct{}
// Parse creates a new Config and parses the file configuration from the named file.
func (ini *IniConfig) Parse(name string) (Configer, error) {
@@ -65,6 +69,10 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
keyComment: make(map[string]string),
RWMutex: sync.RWMutex{},
}
+
+ cfg.BaseConfiger = NewBaseConfiger(func(ctx context.Context, key string) (string, error) {
+ return cfg.getdata(key), nil
+ })
cfg.Lock()
defer cfg.Unlock()
@@ -90,7 +98,7 @@ func (ini *IniConfig) parseData(dir string, data []byte) (*IniConfigContainer, e
break
}
- //It might be a good idea to throw a error on all unknonw errors?
+ // It might be a good idea to throw an error on all unknonw errors?
if _, ok := err.(*os.PathError); ok {
return nil, err
}
@@ -222,9 +230,10 @@ func (ini *IniConfig) ParseData(data []byte) (Configer, error) {
return ini.parseData(dir, data)
}
-// IniConfigContainer A Config represents the ini configuration.
+// IniConfigContainer is a config which represents the ini configuration.
// When set and get value, support key as section:name type.
type IniConfigContainer struct {
+ BaseConfiger
data map[string]map[string]string // section=> key:val
sectionComment map[string]string // section : comment
keyComment map[string]string // id: []{comment, key...}; id 1 is for main comment.
@@ -237,11 +246,11 @@ func (c *IniConfigContainer) Bool(key string) (bool, error) {
}
// DefaultBool returns the boolean value for a given key.
-// if err != nil return defaultval
-func (c *IniConfigContainer) DefaultBool(key string, defaultval bool) bool {
+// if err != nil return defaultVal
+func (c *IniConfigContainer) DefaultBool(key string, defaultVal bool) bool {
v, err := c.Bool(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
@@ -252,11 +261,11 @@ func (c *IniConfigContainer) Int(key string) (int, error) {
}
// DefaultInt returns the integer value for a given key.
-// if err != nil return defaultval
-func (c *IniConfigContainer) DefaultInt(key string, defaultval int) int {
+// if err != nil return defaultVal
+func (c *IniConfigContainer) DefaultInt(key string, defaultVal int) int {
v, err := c.Int(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
@@ -267,11 +276,11 @@ func (c *IniConfigContainer) Int64(key string) (int64, error) {
}
// DefaultInt64 returns the int64 value for a given key.
-// if err != nil return defaultval
-func (c *IniConfigContainer) DefaultInt64(key string, defaultval int64) int64 {
+// if err != nil return defaultVal
+func (c *IniConfigContainer) DefaultInt64(key string, defaultVal int64) int64 {
v, err := c.Int64(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
@@ -282,46 +291,46 @@ func (c *IniConfigContainer) Float(key string) (float64, error) {
}
// DefaultFloat returns the float64 value for a given key.
-// if err != nil return defaultval
-func (c *IniConfigContainer) DefaultFloat(key string, defaultval float64) float64 {
+// if err != nil return defaultVal
+func (c *IniConfigContainer) DefaultFloat(key string, defaultVal float64) float64 {
v, err := c.Float(key)
if err != nil {
- return defaultval
+ return defaultVal
}
return v
}
// String returns the string value for a given key.
-func (c *IniConfigContainer) String(key string) string {
- return c.getdata(key)
+func (c *IniConfigContainer) String(key string) (string, error) {
+ return c.getdata(key), nil
}
// DefaultString returns the string value for a given key.
-// if err != nil return defaultval
-func (c *IniConfigContainer) DefaultString(key string, defaultval string) string {
- v := c.String(key)
- if v == "" {
- return defaultval
+// if err != nil return defaultVal
+func (c *IniConfigContainer) DefaultString(key string, defaultVal string) string {
+ v, err := c.String(key)
+ if v == "" || err != nil {
+ return defaultVal
}
return v
}
// Strings returns the []string value for a given key.
// Return nil if config value does not exist or is empty.
-func (c *IniConfigContainer) Strings(key string) []string {
- v := c.String(key)
- if v == "" {
- return nil
+func (c *IniConfigContainer) Strings(key string) ([]string, error) {
+ v, err := c.String(key)
+ if v == "" || err != nil {
+ return nil, err
}
- return strings.Split(v, ";")
+ return strings.Split(v, ";"), nil
}
// DefaultStrings returns the []string value for a given key.
-// if err != nil return defaultval
-func (c *IniConfigContainer) DefaultStrings(key string, defaultval []string) []string {
- v := c.Strings(key)
- if v == nil {
- return defaultval
+// if err != nil return defaultVal
+func (c *IniConfigContainer) DefaultStrings(key string, defaultVal []string) []string {
+ v, err := c.Strings(key)
+ if v == nil || err != nil {
+ return defaultVal
}
return v
}
@@ -437,7 +446,7 @@ func (c *IniConfigContainer) SaveConfigFile(filename string) (err error) {
// Set writes a new value for key.
// if write to one section, the key need be "section::key".
// if the section is not existed, it panics.
-func (c *IniConfigContainer) Set(key, value string) error {
+func (c *IniConfigContainer) Set(key, val string) error {
c.Lock()
defer c.Unlock()
if len(key) == 0 {
@@ -460,7 +469,7 @@ func (c *IniConfigContainer) Set(key, value string) error {
if _, ok := c.data[section]; !ok {
c.data[section] = make(map[string]string)
}
- c.data[section][k] = value
+ c.data[section][k] = val
return nil
}
@@ -469,7 +478,7 @@ func (c *IniConfigContainer) DIY(key string) (v interface{}, err error) {
if v, ok := c.data[strings.ToLower(key)]; ok {
return v, nil
}
- return v, errors.New("key not find")
+ return v, errors.New("key not found")
}
// section.key or key
@@ -499,6 +508,20 @@ func (c *IniConfigContainer) getdata(key string) string {
return ""
}
+func (c *IniConfigContainer) Unmarshaler(prefix string, obj interface{}, opt ...DecodeOption) error {
+ if len(prefix) > 0 {
+ return errors.New("unsupported prefix params")
+ }
+ return mapstructure.Decode(c.data, obj)
+}
+
func init() {
Register("ini", &IniConfig{})
+
+ err := InitGlobalInstance("ini", "conf/app.conf")
+ if err != nil {
+ logs.Debug("init global config instance failed. If you do not use this, just ignore it. ", err)
+ }
}
+
+// Ignore this error
diff --git a/src/vendor/github.com/beego/beego/logs/README.md b/src/vendor/github.com/beego/beego/v2/core/logs/README.md
similarity index 93%
rename from src/vendor/github.com/beego/beego/logs/README.md
rename to src/vendor/github.com/beego/beego/v2/core/logs/README.md
index 660b1fe19..b2c405ffb 100644
--- a/src/vendor/github.com/beego/beego/logs/README.md
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/README.md
@@ -1,24 +1,22 @@
## logs
-logs is a Go logs manager. It can use many logs adapters. The repo is inspired by `database/sql` .
+logs is a Go logs manager. It can use many logs adapters. The repo is inspired by `database/sql` .
## How to install?
- go get github.com/beego/beego/logs
-
+ go get github.com/beego/beego/v2/core/logs
## What adapters are supported?
As of now this logs support console, file,smtp and conn.
-
## How to use it?
First you must import it
```golang
import (
- "github.com/beego/beego/logs"
+ "github.com/beego/beego/v2/core/logs"
)
```
diff --git a/src/vendor/github.com/beego/beego/logs/accesslog.go b/src/vendor/github.com/beego/beego/v2/core/logs/access_log.go
similarity index 89%
rename from src/vendor/github.com/beego/beego/logs/accesslog.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/access_log.go
index 9011b6022..10455fe92 100644
--- a/src/vendor/github.com/beego/beego/logs/accesslog.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/access_log.go
@@ -28,7 +28,7 @@ const (
jsonFormat = "JSON_FORMAT"
)
-// AccessLogRecord struct for holding access log data.
+// AccessLogRecord is astruct for holding access log data.
type AccessLogRecord struct {
RemoteAddr string `json:"remote_addr"`
RequestTime time.Time `json:"request_time"`
@@ -63,7 +63,17 @@ func disableEscapeHTML(i interface{}) {
// AccessLog - Format and print access log.
func AccessLog(r *AccessLogRecord, format string) {
- var msg string
+ msg := r.format(format)
+ lm := &LogMsg{
+ Msg: strings.TrimSpace(msg),
+ When: time.Now(),
+ Level: levelLoggerImpl,
+ }
+ beeLogger.writeMsg(lm)
+}
+
+func (r *AccessLogRecord) format(format string) string {
+ msg := ""
switch format {
case apacheFormat:
timeFormatted := r.RequestTime.Format("02/Jan/2006 03:04:05")
@@ -79,5 +89,5 @@ func AccessLog(r *AccessLogRecord, format string) {
msg = string(jsonData)
}
}
- beeLogger.writeMsg(levelLoggerImpl, strings.TrimSpace(msg))
+ return msg
}
diff --git a/src/vendor/github.com/beego/beego/logs/conn.go b/src/vendor/github.com/beego/beego/v2/core/logs/conn.go
similarity index 66%
rename from src/vendor/github.com/beego/beego/logs/conn.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/conn.go
index 74c458ab8..cfeb3f916 100644
--- a/src/vendor/github.com/beego/beego/logs/conn.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/conn.go
@@ -16,16 +16,20 @@ package logs
import (
"encoding/json"
+ "fmt"
"io"
"net"
- "time"
+
+ "github.com/pkg/errors"
)
// connWriter implements LoggerInterface.
-// it writes messages in keep-live tcp connection.
+// Writes messages in keep-live tcp connection.
type connWriter struct {
lg *logWriter
innerWriter io.WriteCloser
+ formatter LogFormatter
+ Formatter string `json:"formatter"`
ReconnectOnMsg bool `json:"reconnectOnMsg"`
Reconnect bool `json:"reconnect"`
Net string `json:"net"`
@@ -33,23 +37,40 @@ type connWriter struct {
Level int `json:"level"`
}
-// NewConn create new ConnWrite returning as LoggerInterface.
+// NewConn creates new ConnWrite returning as LoggerInterface.
func NewConn() Logger {
conn := new(connWriter)
conn.Level = LevelTrace
+ conn.formatter = conn
return conn
}
-// Init init connection writer with json config.
-// json config only need key "level".
-func (c *connWriter) Init(jsonConfig string) error {
- return json.Unmarshal([]byte(jsonConfig), c)
+func (c *connWriter) Format(lm *LogMsg) string {
+ return lm.OldStyleFormat()
}
-// WriteMsg write message in connection.
-// if connection is down, try to re-connect.
-func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
- if level > c.Level {
+// Init initializes a connection writer with json config.
+// json config only needs they "level" key
+func (c *connWriter) Init(config string) error {
+ res := json.Unmarshal([]byte(config), c)
+ if res == nil && len(c.Formatter) > 0 {
+ fmtr, ok := GetFormatter(c.Formatter)
+ if !ok {
+ return errors.New(fmt.Sprintf("the formatter with name: %s not found", c.Formatter))
+ }
+ c.formatter = fmtr
+ }
+ return res
+}
+
+func (c *connWriter) SetFormatter(f LogFormatter) {
+ c.formatter = f
+}
+
+// WriteMsg writes message in connection.
+// If connection is down, try to re-connect.
+func (c *connWriter) WriteMsg(lm *LogMsg) error {
+ if lm.Level > c.Level {
return nil
}
if c.needToConnectOnMsg() {
@@ -63,7 +84,9 @@ func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
defer c.innerWriter.Close()
}
- _, err := c.lg.writeln(when, msg)
+ msg := c.formatter.Format(lm)
+
+ _, err := c.lg.writeln(msg)
if err != nil {
return err
}
@@ -72,7 +95,6 @@ func (c *connWriter) WriteMsg(when time.Time, msg string, level int) error {
// Flush implementing method. empty.
func (c *connWriter) Flush() {
-
}
// Destroy destroy connection writer and close tcp listener.
diff --git a/src/vendor/github.com/beego/beego/logs/console.go b/src/vendor/github.com/beego/beego/v2/core/logs/console.go
similarity index 58%
rename from src/vendor/github.com/beego/beego/logs/console.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/console.go
index 3dcaee1df..ff4fcf468 100644
--- a/src/vendor/github.com/beego/beego/logs/console.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/console.go
@@ -16,17 +16,18 @@ package logs
import (
"encoding/json"
+ "fmt"
"os"
"strings"
- "time"
+ "github.com/pkg/errors"
"github.com/shiena/ansicolor"
)
// brush is a color join function
type brush func(string) string
-// newBrush return a fix color Brush
+// newBrush returns a fix color Brush
func newBrush(color string) brush {
pre := "\033["
reset := "\033[0m"
@@ -48,50 +49,75 @@ var colors = []brush{
// consoleWriter implements LoggerInterface and writes messages to terminal.
type consoleWriter struct {
- lg *logWriter
- Level int `json:"level"`
- Colorful bool `json:"color"` //this filed is useful only when system's terminal supports color
+ lg *logWriter
+ formatter LogFormatter
+ Formatter string `json:"formatter"`
+ Level int `json:"level"`
+ Colorful bool `json:"color"` // this filed is useful only when system's terminal supports color
}
-// NewConsole create ConsoleWriter returning as LoggerInterface.
+func (c *consoleWriter) Format(lm *LogMsg) string {
+ msg := lm.OldStyleFormat()
+ if c.Colorful {
+ msg = strings.Replace(msg, levelPrefix[lm.Level], colors[lm.Level](levelPrefix[lm.Level]), 1)
+ }
+ h, _, _ := formatTimeHeader(lm.When)
+ return string(append(h, msg...))
+}
+
+func (c *consoleWriter) SetFormatter(f LogFormatter) {
+ c.formatter = f
+}
+
+// NewConsole creates ConsoleWriter returning as LoggerInterface.
func NewConsole() Logger {
+ return newConsole()
+}
+
+func newConsole() *consoleWriter {
cw := &consoleWriter{
lg: newLogWriter(ansicolor.NewAnsiColorWriter(os.Stdout)),
Level: LevelDebug,
Colorful: true,
}
+ cw.formatter = cw
return cw
}
-// Init init console logger.
-// jsonConfig like '{"level":LevelTrace}'.
-func (c *consoleWriter) Init(jsonConfig string) error {
- if len(jsonConfig) == 0 {
+// Init initianlizes the console logger.
+// jsonConfig must be in the format '{"level":LevelTrace}'
+func (c *consoleWriter) Init(config string) error {
+ if len(config) == 0 {
return nil
}
- return json.Unmarshal([]byte(jsonConfig), c)
+
+ res := json.Unmarshal([]byte(config), c)
+ if res == nil && len(c.Formatter) > 0 {
+ fmtr, ok := GetFormatter(c.Formatter)
+ if !ok {
+ return errors.New(fmt.Sprintf("the formatter with name: %s not found", c.Formatter))
+ }
+ c.formatter = fmtr
+ }
+ return res
}
-// WriteMsg write message in console.
-func (c *consoleWriter) WriteMsg(when time.Time, msg string, level int) error {
- if level > c.Level {
+// WriteMsg writes message in console.
+func (c *consoleWriter) WriteMsg(lm *LogMsg) error {
+ if lm.Level > c.Level {
return nil
}
- if c.Colorful {
- msg = strings.Replace(msg, levelPrefix[level], colors[level](levelPrefix[level]), 1)
- }
- c.lg.writeln(when, msg)
+ msg := c.formatter.Format(lm)
+ c.lg.writeln(msg)
return nil
}
// Destroy implementing method. empty.
func (c *consoleWriter) Destroy() {
-
}
// Flush implementing method. empty.
func (c *consoleWriter) Flush() {
-
}
func init() {
diff --git a/src/vendor/github.com/beego/beego/logs/file.go b/src/vendor/github.com/beego/beego/v2/core/logs/file.go
similarity index 82%
rename from src/vendor/github.com/beego/beego/logs/file.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/file.go
index 40a3572a0..3234a674c 100644
--- a/src/vendor/github.com/beego/beego/logs/file.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/file.go
@@ -30,9 +30,14 @@ import (
)
// fileLogWriter implements LoggerInterface.
-// It writes messages by lines limit, file size limit, or time frequency.
+// Writes messages by lines limit, file size limit, or time frequency.
type fileLogWriter struct {
sync.RWMutex // write log order by order and atomic incr maxLinesCurLines and maxSizeCurSize
+
+ Rotate bool `json:"rotate"`
+ Daily bool `json:"daily"`
+ Hourly bool `json:"hourly"`
+
// The opened file
Filename string `json:"filename"`
fileWriter *os.File
@@ -49,29 +54,30 @@ type fileLogWriter struct {
maxSizeCurSize int
// Rotate daily
- Daily bool `json:"daily"`
MaxDays int64 `json:"maxdays"`
dailyOpenDate int
dailyOpenTime time.Time
// Rotate hourly
- Hourly bool `json:"hourly"`
MaxHours int64 `json:"maxhours"`
hourlyOpenDate int
hourlyOpenTime time.Time
- Rotate bool `json:"rotate"`
-
Level int `json:"level"`
-
+ // Permissions for log file
Perm string `json:"perm"`
+ // Permissions for directory if it is specified in FileName
+ DirPerm string `json:"dirperm"`
RotatePerm string `json:"rotateperm"`
fileNameOnly, suffix string // like "project.log", project is fileNameOnly and .log is suffix
+
+ logFormatter LogFormatter
+ Formatter string `json:"formatter"`
}
-// newFileWriter create a FileLogWriter returning as LoggerInterface.
+// newFileWriter creates a FileLogWriter returning as LoggerInterface.
func newFileWriter() Logger {
w := &fileLogWriter{
Daily: true,
@@ -82,13 +88,26 @@ func newFileWriter() Logger {
RotatePerm: "0440",
Level: LevelTrace,
Perm: "0660",
+ DirPerm: "0770",
MaxLines: 10000000,
MaxFiles: 999,
MaxSize: 1 << 28,
}
+ w.logFormatter = w
return w
}
+func (*fileLogWriter) Format(lm *LogMsg) string {
+ msg := lm.OldStyleFormat()
+ hd, _, _ := formatTimeHeader(lm.When)
+ msg = fmt.Sprintf("%s %s\n", string(hd), msg)
+ return msg
+}
+
+func (w *fileLogWriter) SetFormatter(f LogFormatter) {
+ w.logFormatter = f
+}
+
// Init file logger with json config.
// jsonConfig like:
// {
@@ -100,12 +119,12 @@ func newFileWriter() Logger {
// "rotate":true,
// "perm":"0600"
// }
-func (w *fileLogWriter) Init(jsonConfig string) error {
- err := json.Unmarshal([]byte(jsonConfig), w)
+func (w *fileLogWriter) Init(config string) error {
+ err := json.Unmarshal([]byte(config), w)
if err != nil {
return err
}
- if len(w.Filename) == 0 {
+ if w.Filename == "" {
return errors.New("jsonconfig must have filename")
}
w.suffix = filepath.Ext(w.Filename)
@@ -113,6 +132,14 @@ func (w *fileLogWriter) Init(jsonConfig string) error {
if w.suffix == "" {
w.suffix = ".log"
}
+
+ if len(w.Formatter) > 0 {
+ fmtr, ok := GetFormatter(w.Formatter)
+ if !ok {
+ return fmt.Errorf("the formatter with name: %s not found", w.Formatter)
+ }
+ w.logFormatter = fmtr
+ }
err = w.startLogger()
return err
}
@@ -130,42 +157,43 @@ func (w *fileLogWriter) startLogger() error {
return w.initFd()
}
-func (w *fileLogWriter) needRotateDaily(size int, day int) bool {
+func (w *fileLogWriter) needRotateDaily(day int) bool {
return (w.MaxLines > 0 && w.maxLinesCurLines >= w.MaxLines) ||
(w.MaxSize > 0 && w.maxSizeCurSize >= w.MaxSize) ||
(w.Daily && day != w.dailyOpenDate)
}
-func (w *fileLogWriter) needRotateHourly(size int, hour int) bool {
+func (w *fileLogWriter) needRotateHourly(hour int) bool {
return (w.MaxLines > 0 && w.maxLinesCurLines >= w.MaxLines) ||
(w.MaxSize > 0 && w.maxSizeCurSize >= w.MaxSize) ||
(w.Hourly && hour != w.hourlyOpenDate)
-
}
-// WriteMsg write logger message into file.
-func (w *fileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
- if level > w.Level {
+// WriteMsg writes logger message into file.
+func (w *fileLogWriter) WriteMsg(lm *LogMsg) error {
+ if lm.Level > w.Level {
return nil
}
- hd, d, h := formatTimeHeader(when)
- msg = string(hd) + msg + "\n"
+
+ _, d, h := formatTimeHeader(lm.When)
+
+ msg := w.logFormatter.Format(lm)
if w.Rotate {
w.RLock()
- if w.needRotateHourly(len(msg), h) {
+ if w.needRotateHourly(h) {
w.RUnlock()
w.Lock()
- if w.needRotateHourly(len(msg), h) {
- if err := w.doRotate(when); err != nil {
+ if w.needRotateHourly(h) {
+ if err := w.doRotate(lm.When); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
}
w.Unlock()
- } else if w.needRotateDaily(len(msg), d) {
+ } else if w.needRotateDaily(d) {
w.RUnlock()
w.Lock()
- if w.needRotateDaily(len(msg), d) {
- if err := w.doRotate(when); err != nil {
+ if w.needRotateDaily(d) {
+ if err := w.doRotate(lm.When); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
}
@@ -192,8 +220,13 @@ func (w *fileLogWriter) createLogFile() (*os.File, error) {
return nil, err
}
+ dirperm, err := strconv.ParseInt(w.DirPerm, 8, 64)
+ if err != nil {
+ return nil, err
+ }
+
filepath := path.Dir(w.Filename)
- os.MkdirAll(filepath, os.FileMode(perm))
+ os.MkdirAll(filepath, os.FileMode(dirperm))
fd, err := os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(perm))
if err == nil {
@@ -236,7 +269,7 @@ func (w *fileLogWriter) dailyRotate(openTime time.Time) {
tm := time.NewTimer(time.Duration(nextDay.UnixNano() - openTime.UnixNano() + 100))
<-tm.C
w.Lock()
- if w.needRotateDaily(0, time.Now().Day()) {
+ if w.needRotateDaily(time.Now().Day()) {
if err := w.doRotate(time.Now()); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
@@ -251,7 +284,7 @@ func (w *fileLogWriter) hourlyRotate(openTime time.Time) {
tm := time.NewTimer(time.Duration(nextHour.UnixNano() - openTime.UnixNano() + 100))
<-tm.C
w.Lock()
- if w.needRotateHourly(0, time.Now().Hour()) {
+ if w.needRotateHourly(time.Now().Hour()) {
if err := w.doRotate(time.Now()); err != nil {
fmt.Fprintf(os.Stderr, "FileLogWriter(%q): %s\n", w.Filename, err)
}
@@ -286,7 +319,7 @@ func (w *fileLogWriter) lines() (int, error) {
return count, nil
}
-// DoRotate means it need to write file in new file.
+// DoRotate means it needs to write logs into a new file.
// new file name like xx.2013-01-01.log (daily) or xx.001.log (by line or size)
func (w *fileLogWriter) doRotate(logTime time.Time) error {
// file exists
@@ -302,7 +335,7 @@ func (w *fileLogWriter) doRotate(logTime time.Time) error {
_, err = os.Lstat(w.Filename)
if err != nil {
- //even if the file is not exist or other ,we should RESTART the logger
+ // even if the file is not exist or other ,we should RESTART the logger
goto RESTART_LOGGER
}
@@ -397,7 +430,7 @@ func (w *fileLogWriter) Destroy() {
w.fileWriter.Close()
}
-// Flush flush file logger.
+// Flush flushes file logger.
// there are no buffering messages in file logger in memory.
// flush file means sync file from disk.
func (w *fileLogWriter) Flush() {
diff --git a/src/vendor/github.com/beego/beego/v2/core/logs/formatter.go b/src/vendor/github.com/beego/beego/v2/core/logs/formatter.go
new file mode 100644
index 000000000..6fa4f70c5
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/formatter.go
@@ -0,0 +1,91 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package logs
+
+import (
+ "fmt"
+ "path"
+ "strconv"
+)
+
+var formatterMap = make(map[string]LogFormatter, 4)
+
+type LogFormatter interface {
+ Format(lm *LogMsg) string
+}
+
+// PatternLogFormatter provides a quick format method
+// for example:
+// tes := &PatternLogFormatter{Pattern: "%F:%n|%w %t>> %m", WhenFormat: "2006-01-02"}
+// RegisterFormatter("tes", tes)
+// SetGlobalFormatter("tes")
+type PatternLogFormatter struct {
+ Pattern string
+ WhenFormat string
+}
+
+func (p *PatternLogFormatter) getWhenFormatter() string {
+ s := p.WhenFormat
+ if s == "" {
+ s = "2006/01/02 15:04:05.123" // default style
+ }
+ return s
+}
+
+func (p *PatternLogFormatter) Format(lm *LogMsg) string {
+ return p.ToString(lm)
+}
+
+// RegisterFormatter register an formatter. Usually you should use this to extend your custom formatter
+// for example:
+// RegisterFormatter("my-fmt", &MyFormatter{})
+// logs.SetFormatter(Console, `{"formatter": "my-fmt"}`)
+func RegisterFormatter(name string, fmtr LogFormatter) {
+ formatterMap[name] = fmtr
+}
+
+func GetFormatter(name string) (LogFormatter, bool) {
+ res, ok := formatterMap[name]
+ return res, ok
+}
+
+// ToString 'w' when, 'm' msg,'f' filename,'F' full path,'n' line number
+// 'l' level number, 't' prefix of level type, 'T' full name of level type
+func (p *PatternLogFormatter) ToString(lm *LogMsg) string {
+ s := []rune(p.Pattern)
+ msg := fmt.Sprintf(lm.Msg, lm.Args...)
+ m := map[rune]string{
+ 'w': lm.When.Format(p.getWhenFormatter()),
+ 'm': msg,
+ 'n': strconv.Itoa(lm.LineNumber),
+ 'l': strconv.Itoa(lm.Level),
+ 't': levelPrefix[lm.Level],
+ 'T': levelNames[lm.Level],
+ 'F': lm.FilePath,
+ }
+ _, m['f'] = path.Split(lm.FilePath)
+ res := ""
+ for i := 0; i < len(s)-1; i++ {
+ if s[i] == '%' {
+ if k, ok := m[s[i+1]]; ok {
+ res += k
+ i++
+ continue
+ }
+ }
+ res += string(s[i])
+ }
+ return res
+}
diff --git a/src/vendor/github.com/beego/beego/logs/jianliao.go b/src/vendor/github.com/beego/beego/v2/core/logs/jianliao.go
similarity index 56%
rename from src/vendor/github.com/beego/beego/logs/jianliao.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/jianliao.go
index 88ba0f9af..95835c068 100644
--- a/src/vendor/github.com/beego/beego/logs/jianliao.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/jianliao.go
@@ -5,7 +5,8 @@ import (
"fmt"
"net/http"
"net/url"
- "time"
+
+ "github.com/pkg/errors"
)
// JLWriter implements beego LoggerInterface and is used to send jiaoliao webhook
@@ -16,26 +17,49 @@ type JLWriter struct {
RedirectURL string `json:"redirecturl,omitempty"`
ImageURL string `json:"imageurl,omitempty"`
Level int `json:"level"`
+
+ formatter LogFormatter
+ Formatter string `json:"formatter"`
}
-// newJLWriter create jiaoliao writer.
+// newJLWriter creates jiaoliao writer.
func newJLWriter() Logger {
- return &JLWriter{Level: LevelTrace}
+ res := &JLWriter{Level: LevelTrace}
+ res.formatter = res
+ return res
}
// Init JLWriter with json config string
-func (s *JLWriter) Init(jsonconfig string) error {
- return json.Unmarshal([]byte(jsonconfig), s)
+func (s *JLWriter) Init(config string) error {
+ res := json.Unmarshal([]byte(config), s)
+ if res == nil && len(s.Formatter) > 0 {
+ fmtr, ok := GetFormatter(s.Formatter)
+ if !ok {
+ return errors.New(fmt.Sprintf("the formatter with name: %s not found", s.Formatter))
+ }
+ s.formatter = fmtr
+ }
+ return res
}
-// WriteMsg write message in smtp writer.
-// it will send an email with subject and only this message.
-func (s *JLWriter) WriteMsg(when time.Time, msg string, level int) error {
- if level > s.Level {
+func (s *JLWriter) Format(lm *LogMsg) string {
+ msg := lm.OldStyleFormat()
+ msg = fmt.Sprintf("%s %s", lm.When.Format("2006-01-02 15:04:05"), msg)
+ return msg
+}
+
+func (s *JLWriter) SetFormatter(f LogFormatter) {
+ s.formatter = f
+}
+
+// WriteMsg writes message in smtp writer.
+// Sends an email with subject and only this message.
+func (s *JLWriter) WriteMsg(lm *LogMsg) error {
+ if lm.Level > s.Level {
return nil
}
- text := fmt.Sprintf("%s %s", when.Format("2006-01-02 15:04:05"), msg)
+ text := s.formatter.Format(lm)
form := url.Values{}
form.Add("authorName", s.AuthorName)
diff --git a/src/vendor/github.com/beego/beego/logs/log.go b/src/vendor/github.com/beego/beego/v2/core/logs/log.go
similarity index 73%
rename from src/vendor/github.com/beego/beego/logs/log.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/log.go
index 17bdc8d61..e5e736cae 100644
--- a/src/vendor/github.com/beego/beego/logs/log.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/log.go
@@ -15,7 +15,7 @@
// Package logs provide a general log interface
// Usage:
//
-// import "github.com/beego/beego/logs"
+// import "github.com/beego/beego/v2/core/logs"
//
// log := NewLogger(10000)
// log.SetLogger("console", "")
@@ -30,19 +30,19 @@
// log.Debug("debug")
// log.Critical("critical")
//
-// more docs http://beego.me/docs/module/logs.md
+// more docs http://beego.vip/docs/module/logs.md
package logs
import (
"fmt"
"log"
"os"
- "path"
"runtime"
- "strconv"
"strings"
"sync"
"time"
+
+ "github.com/pkg/errors"
)
// RFC5424 log message levels.
@@ -86,13 +86,16 @@ type newLoggerFunc func() Logger
// Logger defines the behavior of a log provider.
type Logger interface {
Init(config string) error
- WriteMsg(when time.Time, msg string, level int) error
+ WriteMsg(lm *LogMsg) error
Destroy()
Flush()
+ SetFormatter(f LogFormatter)
}
-var adapters = make(map[string]newLoggerFunc)
-var levelPrefix = [LevelDebug + 1]string{"[M]", "[A]", "[C]", "[E]", "[W]", "[N]", "[I]", "[D]"}
+var (
+ adapters = make(map[string]newLoggerFunc)
+ levelPrefix = [LevelDebug + 1]string{"[M]", "[A]", "[C]", "[E]", "[W]", "[N]", "[I]", "[D]"}
+)
// Register makes a log provide available by the provided name.
// If Register is called twice with the same name or if driver is nil,
@@ -108,20 +111,22 @@ func Register(name string, log newLoggerFunc) {
}
// BeeLogger is default logger in beego application.
-// it can contain several providers and log message into all providers.
+// Can contain several providers and log message into all providers.
type BeeLogger struct {
lock sync.Mutex
- level int
init bool
enableFuncCallDepth bool
- loggerFuncCallDepth int
+ enableFullFilePath bool
asynchronous bool
+ wg sync.WaitGroup
+ level int
+ loggerFuncCallDepth int
prefix string
msgChanLen int64
- msgChan chan *logMsg
+ msgChan chan *LogMsg
signalChan chan string
- wg sync.WaitGroup
outputs []*nameLogger
+ globalFormatter string
}
const defaultAsyncMsgLen = 1e3
@@ -131,21 +136,15 @@ type nameLogger struct {
name string
}
-type logMsg struct {
- level int
- msg string
- when time.Time
-}
-
var logMsgPool *sync.Pool
// NewLogger returns a new BeeLogger.
-// channelLen means the number of messages in chan(used where asynchronous is true).
+// channelLen: the number of messages in chan(used where asynchronous is true).
// if the buffering chan is full, logger adapters write to file or other way.
func NewLogger(channelLens ...int64) *BeeLogger {
bl := new(BeeLogger)
bl.level = LevelDebug
- bl.loggerFuncCallDepth = 2
+ bl.loggerFuncCallDepth = 3
bl.msgChanLen = append(channelLens, 0)[0]
if bl.msgChanLen <= 0 {
bl.msgChanLen = defaultAsyncMsgLen
@@ -155,7 +154,7 @@ func NewLogger(channelLens ...int64) *BeeLogger {
return bl
}
-// Async set the log to asynchronous and start the goroutine
+// Async sets the log to asynchronous and start the goroutine
func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
bl.lock.Lock()
defer bl.lock.Unlock()
@@ -166,10 +165,10 @@ func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
if len(msgLen) > 0 && msgLen[0] > 0 {
bl.msgChanLen = msgLen[0]
}
- bl.msgChan = make(chan *logMsg, bl.msgChanLen)
+ bl.msgChan = make(chan *LogMsg, bl.msgChanLen)
logMsgPool = &sync.Pool{
New: func() interface{} {
- return &logMsg{}
+ return &LogMsg{}
},
}
bl.wg.Add(1)
@@ -178,7 +177,7 @@ func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
}
// SetLogger provides a given logger adapter into BeeLogger with config string.
-// config need to be correct JSON as string: {"interval":360}.
+// config must in in JSON format like {"interval":360}}
func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
config := append(configs, "{}")[0]
for _, l := range bl.outputs {
@@ -193,6 +192,16 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
}
lg := logAdapter()
+
+ // Global formatter overrides the default set formatter
+ if len(bl.globalFormatter) > 0 {
+ fmtr, ok := GetFormatter(bl.globalFormatter)
+ if !ok {
+ return errors.New(fmt.Sprintf("the formatter with name: %s not found", bl.globalFormatter))
+ }
+ lg.SetFormatter(fmtr)
+ }
+
err := lg.Init(config)
if err != nil {
fmt.Fprintln(os.Stderr, "logs.BeeLogger.SetLogger: "+err.Error())
@@ -203,7 +212,7 @@ func (bl *BeeLogger) setLogger(adapterName string, configs ...string) error {
}
// SetLogger provides a given logger adapter into BeeLogger with config string.
-// config need to be correct JSON as string: {"interval":360}.
+// config must in in JSON format like {"interval":360}}
func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
bl.lock.Lock()
defer bl.lock.Unlock()
@@ -214,7 +223,7 @@ func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
return bl.setLogger(adapterName, configs...)
}
-// DelLogger remove a logger adapter in BeeLogger.
+// DelLogger removes a logger adapter in BeeLogger.
func (bl *BeeLogger) DelLogger(adapterName string) error {
bl.lock.Lock()
defer bl.lock.Unlock()
@@ -233,9 +242,9 @@ func (bl *BeeLogger) DelLogger(adapterName string) error {
return nil
}
-func (bl *BeeLogger) writeToLoggers(when time.Time, msg string, level int) {
+func (bl *BeeLogger) writeToLoggers(lm *LogMsg) {
for _, l := range bl.outputs {
- err := l.WriteMsg(when, msg, level)
+ err := l.WriteMsg(lm)
if err != nil {
fmt.Fprintf(os.Stderr, "unable to WriteMsg to adapter:%v,error:%v\n", l.name, err)
}
@@ -250,65 +259,74 @@ func (bl *BeeLogger) Write(p []byte) (n int, err error) {
if p[len(p)-1] == '\n' {
p = p[0 : len(p)-1]
}
+ lm := &LogMsg{
+ Msg: string(p),
+ Level: levelLoggerImpl,
+ When: time.Now(),
+ }
+
// set levelLoggerImpl to ensure all log message will be write out
- err = bl.writeMsg(levelLoggerImpl, string(p))
+ err = bl.writeMsg(lm)
if err == nil {
- return len(p), err
+ return len(p), nil
}
return 0, err
}
-func (bl *BeeLogger) writeMsg(logLevel int, msg string, v ...interface{}) error {
+func (bl *BeeLogger) writeMsg(lm *LogMsg) error {
if !bl.init {
bl.lock.Lock()
bl.setLogger(AdapterConsole)
bl.lock.Unlock()
}
- if len(v) > 0 {
- msg = fmt.Sprintf(msg, v...)
+ var (
+ file string
+ line int
+ ok bool
+ )
+
+ _, file, line, ok = runtime.Caller(bl.loggerFuncCallDepth)
+ if !ok {
+ file = "???"
+ line = 0
}
+ lm.FilePath = file
+ lm.LineNumber = line
+ lm.Prefix = bl.prefix
- msg = bl.prefix + " " + msg
+ lm.enableFullFilePath = bl.enableFullFilePath
+ lm.enableFuncCallDepth = bl.enableFuncCallDepth
- when := time.Now()
- if bl.enableFuncCallDepth {
- _, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth)
- if !ok {
- file = "???"
- line = 0
- }
- _, filename := path.Split(file)
- msg = "[" + filename + ":" + strconv.Itoa(line) + "] " + msg
- }
-
- //set level info in front of filename info
- if logLevel == levelLoggerImpl {
+ // set level info in front of filename info
+ if lm.Level == levelLoggerImpl {
// set to emergency to ensure all log will be print out correctly
- logLevel = LevelEmergency
- } else {
- msg = levelPrefix[logLevel] + " " + msg
+ lm.Level = LevelEmergency
}
if bl.asynchronous {
- lm := logMsgPool.Get().(*logMsg)
- lm.level = logLevel
- lm.msg = msg
- lm.when = when
+ logM := logMsgPool.Get().(*LogMsg)
+ logM.Level = lm.Level
+ logM.Msg = lm.Msg
+ logM.When = lm.When
+ logM.Args = lm.Args
+ logM.FilePath = lm.FilePath
+ logM.LineNumber = lm.LineNumber
+ logM.Prefix = lm.Prefix
if bl.outputs != nil {
bl.msgChan <- lm
} else {
logMsgPool.Put(lm)
}
} else {
- bl.writeToLoggers(when, msg, logLevel)
+ bl.writeToLoggers(lm)
}
return nil
}
-// SetLevel Set log message level.
+// SetLevel sets log message level.
// If message level (such as LevelDebug) is higher than logger level (such as LevelWarning),
-// log providers will not even be sent the message.
+// log providers will not be sent the message.
func (bl *BeeLogger) SetLevel(l int) {
bl.level = l
}
@@ -345,7 +363,7 @@ func (bl *BeeLogger) startLogger() {
for {
select {
case bm := <-bl.msgChan:
- bl.writeToLoggers(bm.when, bm.msg, bm.level)
+ bl.writeToLoggers(bm)
logMsgPool.Put(bm)
case sg := <-bl.signalChan:
// Now should only send "flush" or "close" to bl.signalChan
@@ -365,12 +383,33 @@ func (bl *BeeLogger) startLogger() {
}
}
+func (bl *BeeLogger) setGlobalFormatter(fmtter string) error {
+ bl.globalFormatter = fmtter
+ return nil
+}
+
+// SetGlobalFormatter sets the global formatter for all log adapters
+// don't forget to register the formatter by invoking RegisterFormatter
+func SetGlobalFormatter(fmtter string) error {
+ return beeLogger.setGlobalFormatter(fmtter)
+}
+
// Emergency Log EMERGENCY level message.
func (bl *BeeLogger) Emergency(format string, v ...interface{}) {
if LevelEmergency > bl.level {
return
}
- bl.writeMsg(LevelEmergency, format, v...)
+
+ lm := &LogMsg{
+ Level: LevelEmergency,
+ Msg: format,
+ When: time.Now(),
+ }
+ if len(v) > 0 {
+ lm.Msg = fmt.Sprintf(lm.Msg, v...)
+ }
+
+ bl.writeMsg(lm)
}
// Alert Log ALERT level message.
@@ -378,7 +417,14 @@ func (bl *BeeLogger) Alert(format string, v ...interface{}) {
if LevelAlert > bl.level {
return
}
- bl.writeMsg(LevelAlert, format, v...)
+
+ lm := &LogMsg{
+ Level: LevelAlert,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+ bl.writeMsg(lm)
}
// Critical Log CRITICAL level message.
@@ -386,7 +432,14 @@ func (bl *BeeLogger) Critical(format string, v ...interface{}) {
if LevelCritical > bl.level {
return
}
- bl.writeMsg(LevelCritical, format, v...)
+ lm := &LogMsg{
+ Level: LevelCritical,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Error Log ERROR level message.
@@ -394,7 +447,14 @@ func (bl *BeeLogger) Error(format string, v ...interface{}) {
if LevelError > bl.level {
return
}
- bl.writeMsg(LevelError, format, v...)
+ lm := &LogMsg{
+ Level: LevelError,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Warning Log WARNING level message.
@@ -402,7 +462,14 @@ func (bl *BeeLogger) Warning(format string, v ...interface{}) {
if LevelWarn > bl.level {
return
}
- bl.writeMsg(LevelWarn, format, v...)
+ lm := &LogMsg{
+ Level: LevelWarn,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Notice Log NOTICE level message.
@@ -410,7 +477,14 @@ func (bl *BeeLogger) Notice(format string, v ...interface{}) {
if LevelNotice > bl.level {
return
}
- bl.writeMsg(LevelNotice, format, v...)
+ lm := &LogMsg{
+ Level: LevelNotice,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Informational Log INFORMATIONAL level message.
@@ -418,7 +492,14 @@ func (bl *BeeLogger) Informational(format string, v ...interface{}) {
if LevelInfo > bl.level {
return
}
- bl.writeMsg(LevelInfo, format, v...)
+ lm := &LogMsg{
+ Level: LevelInfo,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Debug Log DEBUG level message.
@@ -426,7 +507,14 @@ func (bl *BeeLogger) Debug(format string, v ...interface{}) {
if LevelDebug > bl.level {
return
}
- bl.writeMsg(LevelDebug, format, v...)
+ lm := &LogMsg{
+ Level: LevelDebug,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Warn Log WARN level message.
@@ -435,7 +523,14 @@ func (bl *BeeLogger) Warn(format string, v ...interface{}) {
if LevelWarn > bl.level {
return
}
- bl.writeMsg(LevelWarn, format, v...)
+ lm := &LogMsg{
+ Level: LevelWarn,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Info Log INFO level message.
@@ -444,7 +539,14 @@ func (bl *BeeLogger) Info(format string, v ...interface{}) {
if LevelInfo > bl.level {
return
}
- bl.writeMsg(LevelInfo, format, v...)
+ lm := &LogMsg{
+ Level: LevelInfo,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Trace Log TRACE level message.
@@ -453,7 +555,14 @@ func (bl *BeeLogger) Trace(format string, v ...interface{}) {
if LevelDebug > bl.level {
return
}
- bl.writeMsg(LevelDebug, format, v...)
+ lm := &LogMsg{
+ Level: LevelDebug,
+ Msg: format,
+ When: time.Now(),
+ Args: v,
+ }
+
+ bl.writeMsg(lm)
}
// Flush flush all chan data.
@@ -497,7 +606,7 @@ func (bl *BeeLogger) flush() {
for {
if len(bl.msgChan) > 0 {
bm := <-bl.msgChan
- bl.writeToLoggers(bm.when, bm.msg, bm.level)
+ bl.writeToLoggers(bm)
logMsgPool.Put(bm)
continue
}
@@ -547,6 +656,12 @@ func GetLogger(prefixes ...string) *log.Logger {
return l
}
+// EnableFullFilePath enables full file path logging. Disabled by default
+// e.g "/home/Documents/GitHub/beego/mainapp/" instead of "mainapp"
+func EnableFullFilePath(b bool) {
+ beeLogger.enableFullFilePath = b
+}
+
// Reset will remove all the adapter
func Reset() {
beeLogger.Reset()
@@ -575,7 +690,7 @@ func EnableFuncCallDepth(b bool) {
// SetLogFuncCall set the CallDepth, default is 4
func SetLogFuncCall(b bool) {
beeLogger.EnableFuncCallDepth(b)
- beeLogger.SetLogFuncCallDepth(4)
+ beeLogger.SetLogFuncCallDepth(3)
}
// SetLogFuncCallDepth set log funcCallDepth
@@ -590,61 +705,61 @@ func SetLogger(adapter string, config ...string) error {
// Emergency logs a message at emergency level.
func Emergency(f interface{}, v ...interface{}) {
- beeLogger.Emergency(formatLog(f, v...))
+ beeLogger.Emergency(formatPattern(f, v...), v...)
}
// Alert logs a message at alert level.
func Alert(f interface{}, v ...interface{}) {
- beeLogger.Alert(formatLog(f, v...))
+ beeLogger.Alert(formatPattern(f, v...), v...)
}
// Critical logs a message at critical level.
func Critical(f interface{}, v ...interface{}) {
- beeLogger.Critical(formatLog(f, v...))
+ beeLogger.Critical(formatPattern(f, v...), v...)
}
// Error logs a message at error level.
func Error(f interface{}, v ...interface{}) {
- beeLogger.Error(formatLog(f, v...))
+ beeLogger.Error(formatPattern(f, v...), v...)
}
// Warning logs a message at warning level.
func Warning(f interface{}, v ...interface{}) {
- beeLogger.Warn(formatLog(f, v...))
+ beeLogger.Warn(formatPattern(f, v...), v...)
}
// Warn compatibility alias for Warning()
func Warn(f interface{}, v ...interface{}) {
- beeLogger.Warn(formatLog(f, v...))
+ beeLogger.Warn(formatPattern(f, v...), v...)
}
// Notice logs a message at notice level.
func Notice(f interface{}, v ...interface{}) {
- beeLogger.Notice(formatLog(f, v...))
+ beeLogger.Notice(formatPattern(f, v...), v...)
}
// Informational logs a message at info level.
func Informational(f interface{}, v ...interface{}) {
- beeLogger.Info(formatLog(f, v...))
+ beeLogger.Info(formatPattern(f, v...), v...)
}
// Info compatibility alias for Warning()
func Info(f interface{}, v ...interface{}) {
- beeLogger.Info(formatLog(f, v...))
+ beeLogger.Info(formatPattern(f, v...), v...)
}
// Debug logs a message at debug level.
func Debug(f interface{}, v ...interface{}) {
- beeLogger.Debug(formatLog(f, v...))
+ beeLogger.Debug(formatPattern(f, v...), v...)
}
// Trace logs a message at trace level.
// compatibility alias for Warning()
func Trace(f interface{}, v ...interface{}) {
- beeLogger.Trace(formatLog(f, v...))
+ beeLogger.Trace(formatPattern(f, v...), v...)
}
-func formatLog(f interface{}, v ...interface{}) string {
+func formatPattern(f interface{}, v ...interface{}) string {
var msg string
switch f.(type) {
case string:
@@ -652,10 +767,8 @@ func formatLog(f interface{}, v ...interface{}) string {
if len(v) == 0 {
return msg
}
- if strings.Contains(msg, "%") && !strings.Contains(msg, "%%") {
- //format string
- } else {
- //do not contain format char
+ if !strings.Contains(msg, "%") {
+ // do not contain format char
msg += strings.Repeat(" %v", len(v))
}
default:
@@ -665,5 +778,5 @@ func formatLog(f interface{}, v ...interface{}) string {
}
msg += strings.Repeat(" %v", len(v))
}
- return fmt.Sprintf(msg, v...)
+ return msg
}
diff --git a/src/vendor/github.com/beego/beego/v2/core/logs/log_msg.go b/src/vendor/github.com/beego/beego/v2/core/logs/log_msg.go
new file mode 100644
index 000000000..f1a0b559c
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/log_msg.go
@@ -0,0 +1,55 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package logs
+
+import (
+ "fmt"
+ "path"
+ "time"
+)
+
+type LogMsg struct {
+ Level int
+ Msg string
+ When time.Time
+ FilePath string
+ LineNumber int
+ Args []interface{}
+ Prefix string
+ enableFullFilePath bool
+ enableFuncCallDepth bool
+}
+
+// OldStyleFormat you should never invoke this
+func (lm *LogMsg) OldStyleFormat() string {
+ msg := lm.Msg
+
+ if len(lm.Args) > 0 {
+ msg = fmt.Sprintf(lm.Msg, lm.Args...)
+ }
+
+ msg = lm.Prefix + " " + msg
+
+ if lm.enableFuncCallDepth {
+ filePath := lm.FilePath
+ if !lm.enableFullFilePath {
+ _, filePath = path.Split(filePath)
+ }
+ msg = fmt.Sprintf("[%s:%d] %s", filePath, lm.LineNumber, msg)
+ }
+
+ msg = levelPrefix[lm.Level] + " " + msg
+ return msg
+}
diff --git a/src/vendor/github.com/beego/beego/logs/logger.go b/src/vendor/github.com/beego/beego/v2/core/logs/logger.go
similarity index 93%
rename from src/vendor/github.com/beego/beego/logs/logger.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/logger.go
index a28bff6f8..29e33a826 100644
--- a/src/vendor/github.com/beego/beego/logs/logger.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/logger.go
@@ -30,10 +30,10 @@ func newLogWriter(wr io.Writer) *logWriter {
return &logWriter{writer: wr}
}
-func (lg *logWriter) writeln(when time.Time, msg string) (int, error) {
+func (lg *logWriter) writeln(msg string) (int, error) {
lg.Lock()
- h, _, _ := formatTimeHeader(when)
- n, err := lg.writer.Write(append(append(h, msg...), '\n'))
+ msg += "\n"
+ n, err := lg.writer.Write([]byte(msg))
lg.Unlock()
return n, err
}
@@ -60,7 +60,7 @@ func formatTimeHeader(when time.Time) ([]byte, int, int) {
y, mo, d := when.Date()
h, mi, s := when.Clock()
ns := when.Nanosecond() / 1000000
- //len("2006/01/02 15:04:05.123 ")==24
+ // len("2006/01/02 15:04:05.123 ")==24
var buf [24]byte
buf[0] = y1[y/1000%10]
@@ -112,8 +112,10 @@ var (
reset = string([]byte{27, 91, 48, 109})
)
-var once sync.Once
-var colorMap map[string]string
+var (
+ once sync.Once
+ colorMap map[string]string
+)
func initColor() {
if runtime.GOOS == "windows" {
@@ -126,12 +128,12 @@ func initColor() {
cyan = w32Cyan
}
colorMap = map[string]string{
- //by color
+ // by color
"green": green,
"white": white,
"yellow": yellow,
"red": red,
- //by method
+ // by method
"GET": blue,
"POST": cyan,
"PUT": yellow,
diff --git a/src/vendor/github.com/beego/beego/logs/multifile.go b/src/vendor/github.com/beego/beego/v2/core/logs/multifile.go
similarity index 83%
rename from src/vendor/github.com/beego/beego/logs/multifile.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/multifile.go
index 901682743..009bd32f7 100644
--- a/src/vendor/github.com/beego/beego/logs/multifile.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/multifile.go
@@ -16,7 +16,6 @@ package logs
import (
"encoding/json"
- "time"
)
// A filesLogWriter manages several fileLogWriter
@@ -54,11 +53,17 @@ func (f *multiFileLogWriter) Init(config string) error {
f.fullLogWriter = writer
f.writers[LevelDebug+1] = writer
- //unmarshal "separate" field to f.Separate
- json.Unmarshal([]byte(config), f)
+ // unmarshal "separate" field to f.Separate
+ err = json.Unmarshal([]byte(config), f)
+ if err != nil {
+ return err
+ }
jsonMap := map[string]interface{}{}
- json.Unmarshal([]byte(config), &jsonMap)
+ err = json.Unmarshal([]byte(config), &jsonMap)
+ if err != nil {
+ return err
+ }
for i := LevelEmergency; i < LevelDebug+1; i++ {
for _, v := range f.Separate {
@@ -75,10 +80,17 @@ func (f *multiFileLogWriter) Init(config string) error {
}
}
}
-
return nil
}
+func (*multiFileLogWriter) Format(lm *LogMsg) string {
+ return lm.OldStyleFormat()
+}
+
+func (f *multiFileLogWriter) SetFormatter(fmt LogFormatter) {
+ f.fullLogWriter.SetFormatter(fmt)
+}
+
func (f *multiFileLogWriter) Destroy() {
for i := 0; i < len(f.writers); i++ {
if f.writers[i] != nil {
@@ -87,14 +99,14 @@ func (f *multiFileLogWriter) Destroy() {
}
}
-func (f *multiFileLogWriter) WriteMsg(when time.Time, msg string, level int) error {
+func (f *multiFileLogWriter) WriteMsg(lm *LogMsg) error {
if f.fullLogWriter != nil {
- f.fullLogWriter.WriteMsg(when, msg, level)
+ f.fullLogWriter.WriteMsg(lm)
}
for i := 0; i < len(f.writers)-1; i++ {
if f.writers[i] != nil {
- if level == f.writers[i].Level {
- f.writers[i].WriteMsg(when, msg, level)
+ if lm.Level == f.writers[i].Level {
+ f.writers[i].WriteMsg(lm)
}
}
}
@@ -111,7 +123,8 @@ func (f *multiFileLogWriter) Flush() {
// newFilesWriter create a FileLogWriter returning as LoggerInterface.
func newFilesWriter() Logger {
- return &multiFileLogWriter{}
+ res := &multiFileLogWriter{}
+ return res
}
func init() {
diff --git a/src/vendor/github.com/beego/beego/v2/core/logs/slack.go b/src/vendor/github.com/beego/beego/v2/core/logs/slack.go
new file mode 100644
index 000000000..ce892a1bc
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/slack.go
@@ -0,0 +1,84 @@
+package logs
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "github.com/pkg/errors"
+)
+
+// SLACKWriter implements beego LoggerInterface and is used to send jiaoliao webhook
+type SLACKWriter struct {
+ WebhookURL string `json:"webhookurl"`
+ Level int `json:"level"`
+ formatter LogFormatter
+ Formatter string `json:"formatter"`
+}
+
+// newSLACKWriter creates jiaoliao writer.
+func newSLACKWriter() Logger {
+ res := &SLACKWriter{Level: LevelTrace}
+ res.formatter = res
+ return res
+}
+
+func (s *SLACKWriter) Format(lm *LogMsg) string {
+ // text := fmt.Sprintf("{\"text\": \"%s\"}", msg)
+ return lm.When.Format("2006-01-02 15:04:05") + " " + lm.OldStyleFormat()
+}
+
+func (s *SLACKWriter) SetFormatter(f LogFormatter) {
+ s.formatter = f
+}
+
+// Init SLACKWriter with json config string
+func (s *SLACKWriter) Init(config string) error {
+ res := json.Unmarshal([]byte(config), s)
+
+ if res == nil && len(s.Formatter) > 0 {
+ fmtr, ok := GetFormatter(s.Formatter)
+ if !ok {
+ return errors.New(fmt.Sprintf("the formatter with name: %s not found", s.Formatter))
+ }
+ s.formatter = fmtr
+ }
+
+ return res
+}
+
+// WriteMsg write message in smtp writer.
+// Sends an email with subject and only this message.
+func (s *SLACKWriter) WriteMsg(lm *LogMsg) error {
+ if lm.Level > s.Level {
+ return nil
+ }
+ msg := s.Format(lm)
+ m := make(map[string]string, 1)
+ m["text"] = msg
+
+ body, _ := json.Marshal(m)
+ // resp, err := http.PostForm(s.WebhookURL, form)
+ resp, err := http.Post(s.WebhookURL, "application/json", bytes.NewReader(body))
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Errorf("Post webhook failed %s %d", resp.Status, resp.StatusCode)
+ }
+ return nil
+}
+
+// Flush implementing method. empty.
+func (s *SLACKWriter) Flush() {
+}
+
+// Destroy implementing method. empty.
+func (s *SLACKWriter) Destroy() {
+}
+
+func init() {
+ Register(AdapterSlack, newSLACKWriter)
+}
diff --git a/src/vendor/github.com/beego/beego/logs/smtp.go b/src/vendor/github.com/beego/beego/v2/core/logs/smtp.go
similarity index 77%
rename from src/vendor/github.com/beego/beego/logs/smtp.go
rename to src/vendor/github.com/beego/beego/v2/core/logs/smtp.go
index 6208d7b85..40891a7c8 100644
--- a/src/vendor/github.com/beego/beego/logs/smtp.go
+++ b/src/vendor/github.com/beego/beego/v2/core/logs/smtp.go
@@ -21,7 +21,8 @@ import (
"net"
"net/smtp"
"strings"
- "time"
+
+ "github.com/pkg/errors"
)
// SMTPWriter implements LoggerInterface and is used to send emails via given SMTP-server.
@@ -33,11 +34,15 @@ type SMTPWriter struct {
FromAddress string `json:"fromAddress"`
RecipientAddresses []string `json:"sendTos"`
Level int `json:"level"`
+ formatter LogFormatter
+ Formatter string `json:"formatter"`
}
-// NewSMTPWriter create smtp writer.
+// NewSMTPWriter creates the smtp writer.
func newSMTPWriter() Logger {
- return &SMTPWriter{Level: LevelTrace}
+ res := &SMTPWriter{Level: LevelTrace}
+ res.formatter = res
+ return res
}
// Init smtp writer with json config.
@@ -51,8 +56,16 @@ func newSMTPWriter() Logger {
// "sendTos":["email1","email2"],
// "level":LevelError
// }
-func (s *SMTPWriter) Init(jsonconfig string) error {
- return json.Unmarshal([]byte(jsonconfig), s)
+func (s *SMTPWriter) Init(config string) error {
+ res := json.Unmarshal([]byte(config), s)
+ if res == nil && len(s.Formatter) > 0 {
+ fmtr, ok := GetFormatter(s.Formatter)
+ if !ok {
+ return errors.New(fmt.Sprintf("the formatter with name: %s not found", s.Formatter))
+ }
+ s.formatter = fmtr
+ }
+ return res
}
func (s *SMTPWriter) getSMTPAuth(host string) smtp.Auth {
@@ -67,6 +80,10 @@ func (s *SMTPWriter) getSMTPAuth(host string) smtp.Auth {
)
}
+func (s *SMTPWriter) SetFormatter(f LogFormatter) {
+ s.formatter = f
+}
+
func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAddress string, recipients []string, msgContent []byte) error {
client, err := smtp.Dial(hostAddressWithPort)
if err != nil {
@@ -115,10 +132,14 @@ func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAd
return client.Quit()
}
-// WriteMsg write message in smtp writer.
-// it will send an email with subject and only this message.
-func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
- if level > s.Level {
+func (s *SMTPWriter) Format(lm *LogMsg) string {
+ return lm.OldStyleFormat()
+}
+
+// WriteMsg writes message in smtp writer.
+// Sends an email with subject and only this message.
+func (s *SMTPWriter) WriteMsg(lm *LogMsg) error {
+ if lm.Level > s.Level {
return nil
}
@@ -127,11 +148,13 @@ func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
// Set up authentication information.
auth := s.getSMTPAuth(hp[0])
+ msg := s.Format(lm)
+
// Connect to the server, authenticate, set the sender and recipient,
// and send the email all in one step.
contentType := "Content-Type: text/plain" + "; charset=UTF-8"
mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.FromAddress + "<" + s.FromAddress +
- ">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", when.Format("2006-01-02 15:04:05")) + msg)
+ ">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", lm.When.Format("2006-01-02 15:04:05")) + msg)
return s.sendMail(s.Host, auth, s.FromAddress, s.RecipientAddresses, mailmsg)
}
diff --git a/src/vendor/github.com/beego/beego/utils/caller.go b/src/vendor/github.com/beego/beego/v2/core/utils/caller.go
similarity index 100%
rename from src/vendor/github.com/beego/beego/utils/caller.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/caller.go
diff --git a/src/vendor/github.com/beego/beego/utils/debug.go b/src/vendor/github.com/beego/beego/v2/core/utils/debug.go
similarity index 90%
rename from src/vendor/github.com/beego/beego/utils/debug.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/debug.go
index 93c27b70d..93279181d 100644
--- a/src/vendor/github.com/beego/beego/utils/debug.go
+++ b/src/vendor/github.com/beego/beego/v2/core/utils/debug.go
@@ -47,20 +47,20 @@ func GetDisplayString(data ...interface{}) string {
}
func display(displayed bool, data ...interface{}) string {
- var pc, file, line, ok = runtime.Caller(2)
+ pc, file, line, ok := runtime.Caller(2)
if !ok {
return ""
}
- var buf = new(bytes.Buffer)
+ buf := new(bytes.Buffer)
fmt.Fprintf(buf, "[Debug] at %s() [%s:%d]\n", function(pc), file, line)
fmt.Fprintf(buf, "\n[Variables]\n")
for i := 0; i < len(data); i += 2 {
- var output = fomateinfo(len(data[i].(string))+3, data[i+1])
+ output := fomateinfo(len(data[i].(string))+3, data[i+1])
fmt.Fprintf(buf, "%s = %s", data[i], output)
}
@@ -72,7 +72,7 @@ func display(displayed bool, data ...interface{}) string {
// return data dump and format bytes
func fomateinfo(headlen int, data ...interface{}) []byte {
- var buf = new(bytes.Buffer)
+ buf := new(bytes.Buffer)
if len(data) > 1 {
fmt.Fprint(buf, " ")
@@ -83,9 +83,9 @@ func fomateinfo(headlen int, data ...interface{}) []byte {
}
for k, v := range data {
- var buf2 = new(bytes.Buffer)
+ buf2 := new(bytes.Buffer)
var pointers *pointerInfo
- var interfaces = make([]reflect.Value, 0, 10)
+ interfaces := make([]reflect.Value, 0, 10)
printKeyValue(buf2, reflect.ValueOf(v), &pointers, &interfaces, nil, true, " ", 1)
@@ -140,13 +140,13 @@ func isSimpleType(val reflect.Value, kind reflect.Kind, pointers **pointerInfo,
return true
}
- var elem = val.Elem()
+ elem := val.Elem()
if isSimpleType(elem, elem.Kind(), pointers, interfaces) {
return true
}
- var addr = val.Elem().UnsafeAddr()
+ addr := val.Elem().UnsafeAddr()
for p := *pointers; p != nil; p = p.prev {
if addr == p.addr {
@@ -162,7 +162,7 @@ func isSimpleType(val reflect.Value, kind reflect.Kind, pointers **pointerInfo,
// dump value
func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo, interfaces *[]reflect.Value, structFilter func(string, string) bool, formatOutput bool, indent string, level int) {
- var t = val.Kind()
+ t := val.Kind()
switch t {
case reflect.Bool:
@@ -183,7 +183,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo,
return
}
- var addr = val.Elem().UnsafeAddr()
+ addr := val.Elem().UnsafeAddr()
for p := *pointers; p != nil; p = p.prev {
if addr == p.addr {
@@ -206,7 +206,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo,
case reflect.String:
fmt.Fprint(buf, "\"", val.String(), "\"")
case reflect.Interface:
- var value = val.Elem()
+ value := val.Elem()
if !value.IsValid() {
fmt.Fprint(buf, "nil")
@@ -223,7 +223,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo,
printKeyValue(buf, value, pointers, interfaces, structFilter, formatOutput, indent, level+1)
}
case reflect.Struct:
- var t = val.Type()
+ t := val.Type()
fmt.Fprint(buf, t)
fmt.Fprint(buf, "{")
@@ -235,7 +235,7 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo,
fmt.Fprint(buf, " ")
}
- var name = t.Field(i).Name
+ name := t.Field(i).Name
if formatOutput {
for ind := 0; ind < level; ind++ {
@@ -270,12 +270,12 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo,
fmt.Fprint(buf, val.Type())
fmt.Fprint(buf, "{")
- var allSimple = true
+ allSimple := true
for i := 0; i < val.Len(); i++ {
- var elem = val.Index(i)
+ elem := val.Index(i)
- var isSimple = isSimpleType(elem, elem.Kind(), pointers, interfaces)
+ isSimple := isSimpleType(elem, elem.Kind(), pointers, interfaces)
if !isSimple {
allSimple = false
@@ -312,18 +312,18 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo,
fmt.Fprint(buf, "}")
case reflect.Map:
- var t = val.Type()
- var keys = val.MapKeys()
+ t := val.Type()
+ keys := val.MapKeys()
fmt.Fprint(buf, t)
fmt.Fprint(buf, "{")
- var allSimple = true
+ allSimple := true
for i := 0; i < len(keys); i++ {
- var elem = val.MapIndex(keys[i])
+ elem := val.MapIndex(keys[i])
- var isSimple = isSimpleType(elem, elem.Kind(), pointers, interfaces)
+ isSimple := isSimpleType(elem, elem.Kind(), pointers, interfaces)
if !isSimple {
allSimple = false
@@ -372,8 +372,8 @@ func printKeyValue(buf *bytes.Buffer, val reflect.Value, pointers **pointerInfo,
// PrintPointerInfo dump pointer value
func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) {
- var anyused = false
- var pointerNum = 0
+ anyused := false
+ pointerNum := 0
for p := pointers; p != nil; p = p.prev {
if len(p.used) > 0 {
@@ -384,10 +384,10 @@ func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) {
}
if anyused {
- var pointerBufs = make([][]rune, pointerNum+1)
+ pointerBufs := make([][]rune, pointerNum+1)
for i := 0; i < len(pointerBufs); i++ {
- var pointerBuf = make([]rune, buf.Len()+headlen)
+ pointerBuf := make([]rune, buf.Len()+headlen)
for j := 0; j < len(pointerBuf); j++ {
pointerBuf[j] = ' '
@@ -402,7 +402,7 @@ func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) {
if pn == p.n {
pointerBufs[pn][p.pos+headlen] = '└'
- var maxpos = 0
+ maxpos := 0
for i, pos := range p.used {
if i < len(p.used)-1 {
@@ -440,10 +440,10 @@ func PrintPointerInfo(buf *bytes.Buffer, headlen int, pointers *pointerInfo) {
// Stack get stack bytes
func Stack(skip int, indent string) []byte {
- var buf = new(bytes.Buffer)
+ buf := new(bytes.Buffer)
for i := skip; ; i++ {
- var pc, file, line, ok = runtime.Caller(i)
+ pc, file, line, ok := runtime.Caller(i)
if !ok {
break
diff --git a/src/vendor/github.com/beego/beego/utils/file.go b/src/vendor/github.com/beego/beego/v2/core/utils/file.go
similarity index 100%
rename from src/vendor/github.com/beego/beego/utils/file.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/file.go
diff --git a/src/vendor/github.com/beego/beego/v2/core/utils/kv.go b/src/vendor/github.com/beego/beego/v2/core/utils/kv.go
new file mode 100644
index 000000000..7fc5cee93
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/utils/kv.go
@@ -0,0 +1,87 @@
+// Copyright 2020 beego-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package utils
+
+type KV interface {
+ GetKey() interface{}
+ GetValue() interface{}
+}
+
+// SimpleKV is common structure to store key-value pairs.
+// When you need something like Pair, you can use this
+type SimpleKV struct {
+ Key interface{}
+ Value interface{}
+}
+
+var _ KV = new(SimpleKV)
+
+func (s *SimpleKV) GetKey() interface{} {
+ return s.Key
+}
+
+func (s *SimpleKV) GetValue() interface{} {
+ return s.Value
+}
+
+// KVs interface
+type KVs interface {
+ GetValueOr(key interface{}, defValue interface{}) interface{}
+ Contains(key interface{}) bool
+ IfContains(key interface{}, action func(value interface{})) KVs
+}
+
+// SimpleKVs will store SimpleKV collection as map
+type SimpleKVs struct {
+ kvs map[interface{}]interface{}
+}
+
+var _ KVs = new(SimpleKVs)
+
+// GetValueOr returns the value for a given key, if non-existent
+// it returns defValue
+func (kvs *SimpleKVs) GetValueOr(key interface{}, defValue interface{}) interface{} {
+ v, ok := kvs.kvs[key]
+ if ok {
+ return v
+ }
+ return defValue
+}
+
+// Contains checks if a key exists
+func (kvs *SimpleKVs) Contains(key interface{}) bool {
+ _, ok := kvs.kvs[key]
+ return ok
+}
+
+// IfContains invokes the action on a key if it exists
+func (kvs *SimpleKVs) IfContains(key interface{}, action func(value interface{})) KVs {
+ v, ok := kvs.kvs[key]
+ if ok {
+ action(v)
+ }
+ return kvs
+}
+
+// NewKVs creates the *KVs instance
+func NewKVs(kvs ...KV) KVs {
+ res := &SimpleKVs{
+ kvs: make(map[interface{}]interface{}, len(kvs)),
+ }
+ for _, kv := range kvs {
+ res.kvs[kv.GetKey()] = kv.GetValue()
+ }
+ return res
+}
diff --git a/src/vendor/github.com/beego/beego/utils/mail.go b/src/vendor/github.com/beego/beego/v2/core/utils/mail.go
similarity index 99%
rename from src/vendor/github.com/beego/beego/utils/mail.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/mail.go
index 80a366cae..e685c4496 100644
--- a/src/vendor/github.com/beego/beego/utils/mail.go
+++ b/src/vendor/github.com/beego/beego/v2/core/utils/mail.go
@@ -188,10 +188,10 @@ func (e *Email) Attach(r io.Reader, filename string, args ...string) (a *Attachm
err = errors.New("Must specify the file type and number of parameters can not exceed at least two")
return
}
- c := args[0] //Content-Type
+ c := args[0] // Content-Type
id := ""
if len(args) > 1 {
- id = args[1] //Content-ID
+ id = args[1] // Content-ID
}
var buffer bytes.Buffer
if _, err = io.Copy(&buffer, r); err != nil {
diff --git a/src/vendor/github.com/beego/beego/utils/rand.go b/src/vendor/github.com/beego/beego/v2/core/utils/rand.go
similarity index 97%
rename from src/vendor/github.com/beego/beego/utils/rand.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/rand.go
index 344d1cd53..f80dad7df 100644
--- a/src/vendor/github.com/beego/beego/utils/rand.go
+++ b/src/vendor/github.com/beego/beego/v2/core/utils/rand.go
@@ -27,7 +27,7 @@ func RandomCreateBytes(n int, alphabets ...byte) []byte {
if len(alphabets) == 0 {
alphabets = alphaNum
}
- var bytes = make([]byte, n)
+ bytes := make([]byte, n)
var randBy bool
if num, err := rand.Read(bytes); num != n || err != nil {
r.Seed(time.Now().UnixNano())
diff --git a/src/vendor/github.com/beego/beego/utils/safemap.go b/src/vendor/github.com/beego/beego/v2/core/utils/safemap.go
similarity index 98%
rename from src/vendor/github.com/beego/beego/utils/safemap.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/safemap.go
index 1793030a5..8c48cb5b6 100644
--- a/src/vendor/github.com/beego/beego/utils/safemap.go
+++ b/src/vendor/github.com/beego/beego/v2/core/utils/safemap.go
@@ -18,7 +18,7 @@ import (
"sync"
)
-// BeeMap is a map with lock
+// Deprecated: using sync.Map
type BeeMap struct {
lock *sync.RWMutex
bm map[interface{}]interface{}
diff --git a/src/vendor/github.com/beego/beego/utils/slice.go b/src/vendor/github.com/beego/beego/v2/core/utils/slice.go
similarity index 99%
rename from src/vendor/github.com/beego/beego/utils/slice.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/slice.go
index 8f2cef980..0eda46703 100644
--- a/src/vendor/github.com/beego/beego/utils/slice.go
+++ b/src/vendor/github.com/beego/beego/v2/core/utils/slice.go
@@ -20,6 +20,7 @@ import (
)
type reducetype func(interface{}) interface{}
+
type filtertype func(interface{}) bool
// InSlice checks given string in string slice or not.
diff --git a/src/vendor/github.com/beego/beego/v2/core/utils/time.go b/src/vendor/github.com/beego/beego/v2/core/utils/time.go
new file mode 100644
index 000000000..2f813a057
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/core/utils/time.go
@@ -0,0 +1,46 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package utils
+
+import (
+ "fmt"
+ "time"
+)
+
+// ToShortTimeFormat short string format
+func ToShortTimeFormat(d time.Duration) string {
+ u := uint64(d)
+ if u < uint64(time.Second) {
+ switch {
+ case u == 0:
+ return "0"
+ case u < uint64(time.Microsecond):
+ return fmt.Sprintf("%.2fns", float64(u))
+ case u < uint64(time.Millisecond):
+ return fmt.Sprintf("%.2fus", float64(u)/1000)
+ default:
+ return fmt.Sprintf("%.2fms", float64(u)/1000/1000)
+ }
+ } else {
+ switch {
+ case u < uint64(time.Minute):
+ return fmt.Sprintf("%.2fs", float64(u)/1000/1000/1000)
+ case u < uint64(time.Hour):
+ return fmt.Sprintf("%.2fm", float64(u)/1000/1000/1000/60)
+ default:
+ return fmt.Sprintf("%.2fh", float64(u)/1000/1000/1000/60/60)
+ }
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/utils/utils.go b/src/vendor/github.com/beego/beego/v2/core/utils/utils.go
similarity index 100%
rename from src/vendor/github.com/beego/beego/utils/utils.go
rename to src/vendor/github.com/beego/beego/v2/core/utils/utils.go
diff --git a/src/vendor/github.com/beego/beego/validation/README.md b/src/vendor/github.com/beego/beego/v2/core/validation/README.md
similarity index 90%
rename from src/vendor/github.com/beego/beego/validation/README.md
rename to src/vendor/github.com/beego/beego/v2/core/validation/README.md
index 80085f2cc..dee5a7b1b 100644
--- a/src/vendor/github.com/beego/beego/validation/README.md
+++ b/src/vendor/github.com/beego/beego/v2/core/validation/README.md
@@ -7,18 +7,18 @@ validation is a form validation for a data validation and error collecting using
Install:
- go get github.com/beego/beego/validation
+ go get github.com/beego/beego/v2/core/validation
Test:
- go test github.com/beego/beego/validation
+ go test github.com/beego/beego/v2/core/validation
## Example
Direct Use:
import (
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
"log"
)
@@ -49,7 +49,7 @@ Direct Use:
Struct Tag Use:
import (
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
)
// validation function follow with "valid" tag
@@ -81,7 +81,7 @@ Struct Tag Use:
Use custom function:
import (
- "github.com/beego/beego/validation"
+ "github.com/beego/beego/v2/core/validation"
)
type user struct {
@@ -141,7 +141,6 @@ Struct Tag Functions:
Phone
ZipCode
-
## LICENSE
BSD License http://creativecommons.org/licenses/BSD/
diff --git a/src/vendor/github.com/beego/beego/validation/util.go b/src/vendor/github.com/beego/beego/v2/core/validation/util.go
similarity index 100%
rename from src/vendor/github.com/beego/beego/validation/util.go
rename to src/vendor/github.com/beego/beego/v2/core/validation/util.go
diff --git a/src/vendor/github.com/beego/beego/validation/validation.go b/src/vendor/github.com/beego/beego/v2/core/validation/validation.go
similarity index 95%
rename from src/vendor/github.com/beego/beego/validation/validation.go
rename to src/vendor/github.com/beego/beego/v2/core/validation/validation.go
index 18dbf62fb..7605d22f4 100644
--- a/src/vendor/github.com/beego/beego/validation/validation.go
+++ b/src/vendor/github.com/beego/beego/v2/core/validation/validation.go
@@ -15,7 +15,7 @@
// Package validation for validations
//
// import (
-// "github.com/beego/beego/validation"
+// "github.com/beego/beego/v2/core/validation"
// "log"
// )
//
@@ -43,7 +43,7 @@
// }
// }
//
-// more info: http://beego.me/docs/mvc/controller/validation.md
+// more info: http://beego.vip/docs/mvc/controller/validation.md
package validation
import (
@@ -107,7 +107,7 @@ func (r *Result) Message(message string, args ...interface{}) *Result {
// A Validation context manages data validation and error messages.
type Validation struct {
// if this field set true, in struct tag valid
- // if the struct field vale is empty
+ // if the struct field value is empty
// it will skip those valid functions, see CanSkipFuncs
RequiredFirst bool
@@ -121,7 +121,7 @@ func (v *Validation) Clear() {
v.ErrorsMap = nil
}
-// HasErrors Has ValidationError nor not.
+// HasErrors Has ValidationError or not.
func (v *Validation) HasErrors() bool {
return len(v.Errors) > 0
}
@@ -158,7 +158,7 @@ func (v *Validation) Max(obj interface{}, max int, key string) *Result {
return v.apply(Max{max, key}, obj)
}
-// Range Test that the obj is between mni and max if obj's type is int
+// Range Test that the obj is between min and max if obj's type is int
func (v *Validation) Range(obj interface{}, min, max int, key string) *Result {
return v.apply(Range{Min{Min: min}, Max{Max: max}, key}, obj)
}
@@ -235,8 +235,11 @@ func (v *Validation) Tel(obj interface{}, key string) *Result {
// Phone Test that the obj is chinese mobile or telephone number if type is string
func (v *Validation) Phone(obj interface{}, key string) *Result {
- return v.apply(Phone{Mobile{Match: Match{Regexp: mobilePattern}},
- Tel{Match: Match{Regexp: telPattern}}, key}, obj)
+ return v.apply(Phone{
+ Mobile{Match: Match{Regexp: mobilePattern}},
+ Tel{Match: Match{Regexp: telPattern}},
+ key,
+ }, obj)
}
// ZipCode Test that the obj is chinese zip code if type is string
@@ -269,6 +272,11 @@ func (v *Validation) apply(chk Validator, obj interface{}) *Result {
Field := ""
Label := ""
parts := strings.Split(key, ".")
+ if len(parts) == 2 {
+ Field = parts[0]
+ Name = parts[1]
+ Label = Field
+ }
if len(parts) == 3 {
Field = parts[0]
Name = parts[1]
@@ -418,7 +426,7 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) {
// Step2: If pass on step1, then reflect obj's fields
// Step3: Do the Recursively validation to all struct or struct pointer fields
func (v *Validation) RecursiveValid(objc interface{}) (bool, error) {
- //Step 1: validate obj itself firstly
+ // Step 1: validate obj itself firstly
// fails if objc is not struct
pass, err := v.Valid(objc)
if err != nil || !pass {
diff --git a/src/vendor/github.com/beego/beego/validation/validators.go b/src/vendor/github.com/beego/beego/v2/core/validation/validators.go
similarity index 99%
rename from src/vendor/github.com/beego/beego/validation/validators.go
rename to src/vendor/github.com/beego/beego/v2/core/validation/validators.go
index 3fbcc6b29..c4ea1f512 100644
--- a/src/vendor/github.com/beego/beego/validation/validators.go
+++ b/src/vendor/github.com/beego/beego/v2/core/validation/validators.go
@@ -23,7 +23,7 @@ import (
"time"
"unicode/utf8"
- "github.com/beego/beego/logs"
+ "github.com/beego/beego/v2/core/logs"
)
// CanSkipFuncs will skip valid if RequiredFirst is true and the struct field's value is empty
diff --git a/src/vendor/github.com/beego/beego/v2/doc.go b/src/vendor/github.com/beego/beego/v2/doc.go
new file mode 100644
index 000000000..6975885ab
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/doc.go
@@ -0,0 +1,15 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package beego
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/LICENSE b/src/vendor/github.com/beego/beego/v2/server/web/LICENSE
new file mode 100644
index 000000000..26050108e
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2014 astaxie
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/admin.go b/src/vendor/github.com/beego/beego/v2/server/web/admin.go
new file mode 100644
index 000000000..56d2906f2
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/admin.go
@@ -0,0 +1,122 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package web
+
+import (
+ "fmt"
+ "net"
+ "net/http"
+ "reflect"
+ "time"
+
+ "github.com/beego/beego/v2/core/logs"
+)
+
+// BeeAdminApp is the default adminApp used by admin module.
+var beeAdminApp *adminApp
+
+// FilterMonitorFunc is default monitor filter when admin module is enable.
+// if this func returns, admin module records qps for this request by condition of this function logic.
+// usage:
+// func MyFilterMonitor(method, requestPath string, t time.Duration, pattern string, statusCode int) bool {
+// if method == "POST" {
+// return false
+// }
+// if t.Nanoseconds() < 100 {
+// return false
+// }
+// if strings.HasPrefix(requestPath, "/astaxie") {
+// return false
+// }
+// return true
+// }
+// beego.FilterMonitorFunc = MyFilterMonitor.
+var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
+
+func init() {
+ FilterMonitorFunc = func(string, string, time.Duration, string, int) bool { return true }
+}
+
+func list(root string, p interface{}, m M) {
+ pt := reflect.TypeOf(p)
+ pv := reflect.ValueOf(p)
+ if pt.Kind() == reflect.Ptr {
+ pt = pt.Elem()
+ pv = pv.Elem()
+ }
+ for i := 0; i < pv.NumField(); i++ {
+ var key string
+ if root == "" {
+ key = pt.Field(i).Name
+ } else {
+ key = root + "." + pt.Field(i).Name
+ }
+ if pv.Field(i).Kind() == reflect.Struct {
+ list(key, pv.Field(i).Interface(), m)
+ } else {
+ m[key] = pv.Field(i).Interface()
+ }
+ }
+}
+
+func writeJSON(rw http.ResponseWriter, jsonData []byte) {
+ rw.Header().Set("Content-Type", "application/json")
+ rw.Write(jsonData)
+}
+
+// adminApp is an http.HandlerFunc map used as beeAdminApp.
+type adminApp struct {
+ *HttpServer
+}
+
+// Run start Beego admin
+func (admin *adminApp) Run() {
+ logs.Debug("now we don't start tasks here, if you use task module," +
+ " please invoke task.StartTask, or task will not be executed")
+ addr := BConfig.Listen.AdminAddr
+ if BConfig.Listen.AdminPort != 0 {
+ addr = net.JoinHostPort(BConfig.Listen.AdminAddr, fmt.Sprintf("%d", BConfig.Listen.AdminPort))
+ }
+ logs.Info("Admin server Running on %s", addr)
+ admin.HttpServer.Run(addr)
+}
+
+func registerAdmin() error {
+ if BConfig.Listen.EnableAdmin {
+
+ c := &adminController{
+ servers: make([]*HttpServer, 0, 2),
+ }
+
+ // copy config to avoid conflict
+ adminCfg := *BConfig
+ adminCfg.Listen.EnableHTTPS = false
+ adminCfg.Listen.EnableMutualHTTPS = false
+ beeAdminApp = &adminApp{
+ HttpServer: NewHttpServerWithCfg(&adminCfg),
+ }
+ // keep in mind that all data should be html escaped to avoid XSS attack
+ beeAdminApp.Router("/", c, "get:AdminIndex")
+ beeAdminApp.Router("/qps", c, "get:QpsIndex")
+ beeAdminApp.Router("/prof", c, "get:ProfIndex")
+ beeAdminApp.Router("/healthcheck", c, "get:Healthcheck")
+ beeAdminApp.Router("/task", c, "get:TaskStatus")
+ beeAdminApp.Router("/listconf", c, "get:ListConf")
+ beeAdminApp.Router("/metrics", c, "get:PrometheusMetrics")
+
+ go beeAdminApp.Run()
+ }
+ return nil
+}
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/admin_controller.go b/src/vendor/github.com/beego/beego/v2/server/web/admin_controller.go
new file mode 100644
index 000000000..ce77ecdb9
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/admin_controller.go
@@ -0,0 +1,293 @@
+// Copyright 2020
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package web
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strconv"
+ "text/template"
+
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+
+ "github.com/beego/beego/v2/core/admin"
+)
+
+type adminController struct {
+ Controller
+ servers []*HttpServer
+}
+
+func (a *adminController) registerHttpServer(svr *HttpServer) {
+ a.servers = append(a.servers, svr)
+}
+
+// ProfIndex is a http.Handler for showing profile command.
+// it's in url pattern "/prof" in admin module.
+func (a *adminController) ProfIndex() {
+ rw, r := a.Ctx.ResponseWriter, a.Ctx.Request
+ r.ParseForm()
+ command := r.Form.Get("command")
+ if command == "" {
+ return
+ }
+
+ var (
+ format = r.Form.Get("format")
+ data = make(map[interface{}]interface{})
+ result bytes.Buffer
+ )
+ admin.ProcessInput(command, &result)
+ data["Content"] = template.HTMLEscapeString(result.String())
+
+ if format == "json" && command == "gc summary" {
+ dataJSON, err := json.Marshal(data)
+ if err != nil {
+ http.Error(rw, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ writeJSON(rw, dataJSON)
+ return
+ }
+
+ data["Title"] = template.HTMLEscapeString(command)
+ defaultTpl := defaultScriptsTpl
+ if command == "gc summary" {
+ defaultTpl = gcAjaxTpl
+ }
+ writeTemplate(rw, data, profillingTpl, defaultTpl)
+}
+
+func (a *adminController) PrometheusMetrics() {
+ promhttp.Handler().ServeHTTP(a.Ctx.ResponseWriter, a.Ctx.Request)
+}
+
+// TaskStatus is a http.Handler with running task status (task name, status and the last execution).
+// it's in "/task" pattern in admin module.
+func (a *adminController) TaskStatus() {
+ rw, req := a.Ctx.ResponseWriter, a.Ctx.Request
+
+ data := make(map[interface{}]interface{})
+
+ // Run Task
+ req.ParseForm()
+ taskname := req.Form.Get("taskname")
+ if taskname != "" {
+ cmd := admin.GetCommand("task", "run")
+ res := cmd.Execute(taskname)
+ if res.IsSuccess() {
+ data["Message"] = []string{
+ "success",
+ template.HTMLEscapeString(fmt.Sprintf("%s run success,Now the Status is
%s",
+ taskname, res.Content.(string))),
+ }
+ } else {
+ data["Message"] = []string{"error", template.HTMLEscapeString(fmt.Sprintf("%s", res.Error))}
+ }
+ }
+
+ // List Tasks
+ content := make(M)
+ resultList := admin.GetCommand("task", "list").Execute().Content.([][]string)
+ fields := []string{
+ "Task Name",
+ "Task Spec",
+ "Task Status",
+ "Last Time",
+ "",
+ }
+
+ content["Fields"] = fields
+ content["Data"] = resultList
+ data["Content"] = content
+ data["Title"] = "Tasks"
+ writeTemplate(rw, data, tasksTpl, defaultScriptsTpl)
+}
+
+func (a *adminController) AdminIndex() {
+ // AdminIndex is the default http.Handler for admin module.
+ // it matches url pattern "/".
+ writeTemplate(a.Ctx.ResponseWriter, map[interface{}]interface{}{}, indexTpl, defaultScriptsTpl)
+}
+
+// Healthcheck is a http.Handler calling health checking and showing the result.
+// it's in "/healthcheck" pattern in admin module.
+func (a *adminController) Healthcheck() {
+ heathCheck(a.Ctx.ResponseWriter, a.Ctx.Request)
+}
+
+func heathCheck(rw http.ResponseWriter, r *http.Request) {
+ var (
+ result []string
+ data = make(map[interface{}]interface{})
+ resultList = new([][]string)
+ content = M{
+ "Fields": []string{"Name", "Message", "Status"},
+ }
+ )
+
+ for name, h := range admin.AdminCheckList {
+ if err := h.Check(); err != nil {
+ result = []string{
+ "error",
+ template.HTMLEscapeString(name),
+ template.HTMLEscapeString(err.Error()),
+ }
+ } else {
+ result = []string{
+ "success",
+ template.HTMLEscapeString(name),
+ "OK",
+ }
+ }
+ *resultList = append(*resultList, result)
+ }
+
+ queryParams := r.URL.Query()
+ jsonFlag := queryParams.Get("json")
+ shouldReturnJSON, _ := strconv.ParseBool(jsonFlag)
+
+ if shouldReturnJSON {
+ response := buildHealthCheckResponseList(resultList)
+ jsonResponse, err := json.Marshal(response)
+
+ if err != nil {
+ http.Error(rw, err.Error(), http.StatusInternalServerError)
+ } else {
+ writeJSON(rw, jsonResponse)
+ }
+ return
+ }
+
+ content["Data"] = resultList
+ data["Content"] = content
+ data["Title"] = "Health Check"
+
+ writeTemplate(rw, data, healthCheckTpl, defaultScriptsTpl)
+}
+
+// QpsIndex is the http.Handler for writing qps statistics map result info in http.ResponseWriter.
+// it's registered with url pattern "/qps" in admin module.
+func (a *adminController) QpsIndex() {
+ data := make(map[interface{}]interface{})
+ data["Content"] = StatisticsMap.GetMap()
+
+ // do html escape before display path, avoid xss
+ if content, ok := (data["Content"]).(M); ok {
+ if resultLists, ok := (content["Data"]).([][]string); ok {
+ for i := range resultLists {
+ if len(resultLists[i]) > 0 {
+ resultLists[i][0] = template.HTMLEscapeString(resultLists[i][0])
+ }
+ }
+ }
+ }
+ writeTemplate(a.Ctx.ResponseWriter, data, qpsTpl, defaultScriptsTpl)
+}
+
+// ListConf is the http.Handler of displaying all beego configuration values as key/value pair.
+// it's registered with url pattern "/listconf" in admin module.
+func (a *adminController) ListConf() {
+ rw := a.Ctx.ResponseWriter
+ r := a.Ctx.Request
+ r.ParseForm()
+ command := r.Form.Get("command")
+ if command == "" {
+ rw.Write([]byte("command not support"))
+ return
+ }
+
+ data := make(map[interface{}]interface{})
+ switch command {
+ case "conf":
+ m := make(M)
+ list("BConfig", BConfig, m)
+ m["appConfigPath"] = template.HTMLEscapeString(appConfigPath)
+ m["appConfigProvider"] = template.HTMLEscapeString(appConfigProvider)
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ tmpl = template.Must(tmpl.Parse(configTpl))
+ tmpl = template.Must(tmpl.Parse(defaultScriptsTpl))
+
+ data["Content"] = m
+
+ tmpl.Execute(rw, data)
+
+ case "router":
+ content := BeeApp.PrintTree()
+ content["Fields"] = []string{
+ "Router Pattern",
+ "Methods",
+ "Controller",
+ }
+ data["Content"] = content
+ data["Title"] = "Routers"
+ writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
+ case "filter":
+ content := M{
+ "Fields": []string{
+ "Router Pattern",
+ "Filter Function",
+ },
+ }
+
+ filterTypeData := BeeApp.reportFilter()
+
+ filterTypes := make([]string, 0, len(filterTypeData))
+ for k := range filterTypeData {
+ filterTypes = append(filterTypes, k)
+ }
+
+ content["Data"] = filterTypeData
+ content["Methods"] = filterTypes
+
+ data["Content"] = content
+ data["Title"] = "Filters"
+ writeTemplate(rw, data, routerAndFilterTpl, defaultScriptsTpl)
+ default:
+ rw.Write([]byte("command not support"))
+ }
+}
+
+func writeTemplate(rw http.ResponseWriter, data map[interface{}]interface{}, tpls ...string) {
+ tmpl := template.Must(template.New("dashboard").Parse(dashboardTpl))
+ for _, tpl := range tpls {
+ tmpl = template.Must(tmpl.Parse(tpl))
+ }
+ tmpl.Execute(rw, data)
+}
+
+func buildHealthCheckResponseList(healthCheckResults *[][]string) []map[string]interface{} {
+ response := make([]map[string]interface{}, len(*healthCheckResults))
+
+ for i, healthCheckResult := range *healthCheckResults {
+ currentResultMap := make(map[string]interface{})
+
+ currentResultMap["name"] = healthCheckResult[0]
+ currentResultMap["message"] = healthCheckResult[1]
+ currentResultMap["status"] = healthCheckResult[2]
+
+ response[i] = currentResultMap
+ }
+
+ return response
+}
+
+// PrintTree print all routers
+// Deprecated using BeeApp directly
+func PrintTree() M {
+ return BeeApp.PrintTree()
+}
diff --git a/src/vendor/github.com/beego/beego/adminui.go b/src/vendor/github.com/beego/beego/v2/server/web/adminui.go
similarity index 98%
rename from src/vendor/github.com/beego/beego/adminui.go
rename to src/vendor/github.com/beego/beego/v2/server/web/adminui.go
index cdcdef33f..75a8badc8 100644
--- a/src/vendor/github.com/beego/beego/adminui.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/adminui.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
var indexTpl = `
{{define "content"}}
@@ -21,10 +21,10 @@ var indexTpl = `
For detail usage please check our document:
-Toolbox
+Toolbox
-Live Monitor
+Live Monitor
{{.Content}}
{{end}}`
diff --git a/src/vendor/github.com/beego/beego/beego.go b/src/vendor/github.com/beego/beego/v2/server/web/beego.go
similarity index 65%
rename from src/vendor/github.com/beego/beego/beego.go
rename to src/vendor/github.com/beego/beego/v2/server/web/beego.go
index 44184c25c..cfe9a5ddc 100644
--- a/src/vendor/github.com/beego/beego/beego.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/beego.go
@@ -12,19 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"os"
"path/filepath"
- "strconv"
- "strings"
+ "sync"
)
const (
- // VERSION represent beego web framework version.
- VERSION = "1.12.3"
-
// DEV is for develop
DEV = "dev"
// PROD is for production
@@ -37,9 +33,7 @@ type M map[string]interface{}
// Hook function to run
type hookfunc func() error
-var (
- hooks = make([]hookfunc, 0) //hook function slice to store the hookfunc
-)
+var hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc
// AddAPPStartHook is used to register the hookfunc
// The hookfuncs will run in beego.Run()
@@ -54,56 +48,39 @@ func AddAPPStartHook(hf ...hookfunc) {
// beego.Run(":8089")
// beego.Run("127.0.0.1:8089")
func Run(params ...string) {
-
- initBeforeHTTPRun()
-
if len(params) > 0 && params[0] != "" {
- strs := strings.Split(params[0], ":")
- if len(strs) > 0 && strs[0] != "" {
- BConfig.Listen.HTTPAddr = strs[0]
- }
- if len(strs) > 1 && strs[1] != "" {
- BConfig.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
- }
-
- BConfig.Listen.Domains = params
+ BeeApp.Run(params[0])
}
-
- BeeApp.Run()
+ BeeApp.Run("")
}
// RunWithMiddleWares Run beego application with middlewares.
func RunWithMiddleWares(addr string, mws ...MiddleWare) {
- initBeforeHTTPRun()
-
- strs := strings.Split(addr, ":")
- if len(strs) > 0 && strs[0] != "" {
- BConfig.Listen.HTTPAddr = strs[0]
- BConfig.Listen.Domains = []string{strs[0]}
- }
- if len(strs) > 1 && strs[1] != "" {
- BConfig.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
- }
-
- BeeApp.Run(mws...)
+ BeeApp.Run(addr, mws...)
}
-func initBeforeHTTPRun() {
- //init hooks
- AddAPPStartHook(
- registerMime,
- registerDefaultErrorHandler,
- registerSession,
- registerTemplate,
- registerAdmin,
- registerGzip,
- )
+var initHttpOnce sync.Once
- for _, hk := range hooks {
- if err := hk(); err != nil {
- panic(err)
+// TODO move to module init function
+func initBeforeHTTPRun() {
+ initHttpOnce.Do(func() {
+ // init hooks
+ AddAPPStartHook(
+ registerMime,
+ registerDefaultErrorHandler,
+ registerSession,
+ registerTemplate,
+ registerAdmin,
+ registerGzip,
+ // registerCommentRouter,
+ )
+
+ for _, hk := range hooks {
+ if err := hk(); err != nil {
+ panic(err)
+ }
}
- }
+ })
}
// TestBeegoInit is for test package init
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/config.go b/src/vendor/github.com/beego/beego/v2/server/web/config.go
new file mode 100644
index 000000000..006201a63
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/config.go
@@ -0,0 +1,872 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package web
+
+import (
+ "crypto/tls"
+ "fmt"
+ "net/http"
+ "os"
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "strings"
+
+ "github.com/beego/beego/v2"
+ "github.com/beego/beego/v2/core/config"
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/core/utils"
+ "github.com/beego/beego/v2/server/web/context"
+ "github.com/beego/beego/v2/server/web/session"
+)
+
+// Config is the main struct for BConfig
+// TODO after supporting multiple servers, remove common config to somewhere else
+type Config struct {
+ // AppName
+ // @Description Application's name. You'd better set it because we use it to do some logging and tracing
+ // @Default beego
+ AppName string // Application name
+ // RunMode
+ // @Description it's the same as environment. In general, we have different run modes.
+ // For example, the most common case is using dev, test, prod three environments
+ // when you are developing the application, you should set it as dev
+ // when you completed coding and want QA to test your code, you should deploy your application to test environment
+ // and the RunMode should be set as test
+ // when you completed all tests, you want to deploy it to prod, you should set it to prod
+ // You should never set RunMode="dev" when you deploy the application to prod
+ // because Beego will do more things which need Go SDK and other tools when it found out the RunMode="dev"
+ // @Default dev
+ RunMode string // Running Mode: dev | prod
+
+ // RouterCaseSensitive
+ // @Description If it was true, it means that the router is case sensitive.
+ // For example, when you register a router with pattern "/hello",
+ // 1. If this is true, and the request URL is "/Hello", it won't match this pattern
+ // 2. If this is false and the request URL is "/Hello", it will match this pattern
+ // @Default true
+ RouterCaseSensitive bool
+ // RecoverPanic
+ // @Description if it was true, Beego will try to recover from panic when it serves your http request
+ // So you should notice that it doesn't mean that Beego will recover all panic cases.
+ // @Default true
+ RecoverPanic bool
+ // CopyRequestBody
+ // @Description if it's true, Beego will copy the request body. But if the request body's size > MaxMemory,
+ // Beego will return 413 as http status
+ // If you are building RESTful API, please set it to true.
+ // And if you want to read data from request Body multiple times, please set it to true
+ // In general, if you don't meet any performance issue, you could set it to true
+ // @Default false
+ CopyRequestBody bool
+ // EnableGzip
+ // @Description If it was true, Beego will try to compress data by using zip algorithm.
+ // But there are two points:
+ // 1. Only static resources will be compressed
+ // 2. Only those static resource which has the extension specified by StaticExtensionsToGzip will be compressed
+ // @Default false
+ EnableGzip bool
+ // EnableErrorsShow
+ // @Description If it's true, Beego will show error message to page
+ // it will work with ErrorMaps which allows you register some error handler
+ // You may want to set it to false when application was deploy to prod environment
+ // because you may not want to expose your internal error msg to your users
+ // it's a little bit unsafe
+ // @Default true
+ EnableErrorsShow bool
+ // EnableErrorsRender
+ // @Description If it's true, it will output the error msg as a page. It's similar to EnableErrorsShow
+ // And this configure item only work in dev run mode (see RunMode)
+ // @Default true
+ EnableErrorsRender bool
+ // ServerName
+ // @Description server name. For example, in large scale system,
+ // you may want to deploy your application to several machines, so that each of them has a server name
+ // we suggest you'd better set value because Beego use this to output some DEBUG msg,
+ // or integrated with other tools such as tracing, metrics
+ // @Default
+ ServerName string
+
+ // RecoverFunc
+ // @Description when Beego want to recover from panic, it will use this func as callback
+ // see RecoverPanic
+ // @Default defaultRecoverPanic
+ RecoverFunc func(*context.Context, *Config)
+ // @Description MaxMemory and MaxUploadSize are used to limit the request body
+ // if the request is not uploading file, MaxMemory is the max size of request body
+ // if the request is uploading file, MaxUploadSize is the max size of request body
+ // if CopyRequestBody is true, this value will be used as the threshold of request body
+ // see CopyRequestBody
+ // the default value is 1 << 26 (64MB)
+ // @Default 67108864
+ MaxMemory int64
+ // MaxUploadSize
+ // @Description MaxMemory and MaxUploadSize are used to limit the request body
+ // if the request is not uploading file, MaxMemory is the max size of request body
+ // if the request is uploading file, MaxUploadSize is the max size of request body
+ // the default value is 1 << 30 (1GB)
+ // @Default 1073741824
+ MaxUploadSize int64
+ // Listen
+ // @Description the configuration about socket or http protocol
+ Listen Listen
+ // WebConfig
+ // @Description the configuration about Web
+ WebConfig WebConfig
+ // LogConfig
+ // @Description log configuration
+ Log LogConfig
+}
+
+// Listen holds for http and https related config
+type Listen struct {
+ // Graceful
+ // @Description means use graceful module to start the server
+ // @Default false
+ Graceful bool
+ // ListenTCP4
+ // @Description if it's true, means that Beego only work for TCP4
+ // please check net.Listen function
+ // In general, you should not set it to true
+ // @Default false
+ ListenTCP4 bool
+ // EnableHTTP
+ // @Description if it's true, Beego will accept HTTP request.
+ // But if you want to use HTTPS only, please set it to false
+ // see EnableHTTPS
+ // @Default true
+ EnableHTTP bool
+ // AutoTLS
+ // @Description If it's true, Beego will use default value to initialize the TLS configure
+ // But those values could be override if you have custom value.
+ // see Domains, TLSCacheDir
+ // @Default false
+ AutoTLS bool
+ // EnableHTTPS
+ // @Description If it's true, Beego will accept HTTPS request.
+ // Now, you'd better use HTTPS protocol on prod environment to get better security
+ // In prod, the best option is EnableHTTPS=true and EnableHTTP=false
+ // see EnableHTTP
+ // @Default false
+ EnableHTTPS bool
+ // EnableMutualHTTPS
+ // @Description if it's true, Beego will handle requests on incoming mutual TLS connections
+ // see Server.ListenAndServeMutualTLS
+ // @Default false
+ EnableMutualHTTPS bool
+ // EnableAdmin
+ // @Description if it's true, Beego will provide admin service.
+ // You can visit the admin service via browser.
+ // The default port is 8088
+ // see AdminPort
+ // @Default false
+ EnableAdmin bool
+ // EnableFcgi
+ // @Description
+ // @Default false
+ EnableFcgi bool
+ // EnableStdIo
+ // @Description EnableStdIo works with EnableFcgi Use FCGI via standard I/O
+ // @Default false
+ EnableStdIo bool
+ // ServerTimeOut
+ // @Description Beego use this as ReadTimeout and WriteTimeout
+ // The unit is second.
+ // see http.Server.ReadTimeout, WriteTimeout
+ // @Default 0
+ ServerTimeOut int64
+ // HTTPAddr
+ // @Description Beego listen to this address when the application start up.
+ // @Default ""
+ HTTPAddr string
+ // HTTPPort
+ // @Description Beego listen to this port
+ // you'd better change this value when you deploy to prod environment
+ // @Default 8080
+ HTTPPort int
+ // Domains
+ // @Description Beego use this to configure TLS. Those domains are "white list" domain
+ // @Default []
+ Domains []string
+ // TLSCacheDir
+ // @Description Beego use this as cache dir to store TLS cert data
+ // @Default ""
+ TLSCacheDir string
+ // HTTPSAddr
+ // @Description Beego will listen to this address to accept HTTPS request
+ // see EnableHTTPS
+ // @Default ""
+ HTTPSAddr string
+ // HTTPSPort
+ // @Description Beego will listen to this port to accept HTTPS request
+ // @Default 10443
+ HTTPSPort int
+ // HTTPSCertFile
+ // @Description Beego read this file as cert file
+ // When you are using HTTPS protocol, please configure it
+ // see HTTPSKeyFile
+ // @Default ""
+ HTTPSCertFile string
+ // HTTPSKeyFile
+ // @Description Beego read this file as key file
+ // When you are using HTTPS protocol, please configure it
+ // see HTTPSCertFile
+ // @Default ""
+ HTTPSKeyFile string
+ // TrustCaFile
+ // @Description Beego read this file as CA file
+ // @Default ""
+ TrustCaFile string
+ // AdminAddr
+ // @Description Beego will listen to this address to provide admin service
+ // In general, it should be the same with your application address, HTTPAddr or HTTPSAddr
+ // @Default ""
+ AdminAddr string
+ // AdminPort
+ // @Description Beego will listen to this port to provide admin service
+ // @Default 8088
+ AdminPort int
+ // @Description Beego use this tls.ClientAuthType to initialize TLS connection
+ // The default value is tls.RequireAndVerifyClientCert
+ // @Default 4
+ ClientAuth int
+}
+
+// WebConfig holds web related config
+type WebConfig struct {
+ // AutoRender
+ // @Description If it's true, Beego will render the page based on your template and data
+ // In general, keep it as true.
+ // But if you are building RESTFul API and you don't have any page,
+ // you can set it to false
+ // @Default true
+ AutoRender bool
+ // Deprecated: Beego didn't use it anymore
+ EnableDocs bool
+ // EnableXSRF
+ // @Description If it's true, Beego will help to provide XSRF support
+ // But you should notice that, now Beego only work for HTTPS protocol with XSRF
+ // because it's not safe if using HTTP protocol
+ // And, the cookie storing XSRF token has two more flags HttpOnly and Secure
+ // It means that you must use HTTPS protocol and you can not read the token from JS script
+ // This is completed different from Beego 1.x because we got many security reports
+ // And if you are in dev environment, you could set it to false
+ // @Default false
+ EnableXSRF bool
+ // DirectoryIndex
+ // @Description When Beego serves static resources request, it will look up the file.
+ // If the file is directory, Beego will try to find the index.html as the response
+ // But if the index.html is not exist or it's a directory,
+ // Beego will return 403 response if DirectoryIndex is **false**
+ // @Default false
+ DirectoryIndex bool
+ // FlashName
+ // @Description the cookie's name when Beego try to store the flash data into cookie
+ // @Default BEEGO_FLASH
+ FlashName string
+ // FlashSeparator
+ // @Description When Beego read flash data from request, it uses this as the separator
+ // @Default BEEGOFLASH
+ FlashSeparator string
+ // StaticDir
+ // @Description Beego uses this as static resources' root directory.
+ // It means that Beego will try to search static resource from this start point
+ // It's a map, the key is the path and the value is the directory
+ // For example, the default value is /static => static,
+ // which means that when Beego got a request with path /static/xxx
+ // Beego will try to find the resource from static directory
+ // @Default /static => static
+ StaticDir map[string]string
+ // StaticExtensionsToGzip
+ // @Description The static resources with those extension will be compressed if EnableGzip is true
+ // @Default [".css", ".js" ]
+ StaticExtensionsToGzip []string
+ // StaticCacheFileSize
+ // @Description If the size of static resource < StaticCacheFileSize, Beego will try to handle it by itself,
+ // it means that Beego will compressed the file data (if enable) and cache this file.
+ // But if the file size > StaticCacheFileSize, Beego just simply delegate the request to http.ServeFile
+ // the default value is 100KB.
+ // the max memory size of caching static files is StaticCacheFileSize * StaticCacheFileNum
+ // see StaticCacheFileNum
+ // @Default 102400
+ StaticCacheFileSize int
+ // StaticCacheFileNum
+ // @Description Beego use it to control the memory usage of caching static resource file
+ // If the caching files > StaticCacheFileNum, Beego use LRU algorithm to remove caching file
+ // the max memory size of caching static files is StaticCacheFileSize * StaticCacheFileNum
+ // see StaticCacheFileSize
+ // @Default 1000
+ StaticCacheFileNum int
+ // TemplateLeft
+ // @Description Beego use this to render page
+ // see TemplateRight
+ // @Default {{
+ TemplateLeft string
+ // TemplateRight
+ // @Description Beego use this to render page
+ // see TemplateLeft
+ // @Default }}
+ TemplateRight string
+ // ViewsPath
+ // @Description The directory of Beego application storing template
+ // @Default views
+ ViewsPath string
+ // CommentRouterPath
+ // @Description Beego scans this directory and its sub directory to generate router
+ // Beego only scans this directory when it's in dev environment
+ // @Default controllers
+ CommentRouterPath string
+ // XSRFKey
+ // @Description the name of cookie storing XSRF token
+ // see EnableXSRF
+ // @Default beegoxsrf
+ XSRFKey string
+ // XSRFExpire
+ // @Description the expiration time of XSRF token cookie
+ // second
+ // @Default 0
+ XSRFExpire int
+ // @Description session related config
+ Session SessionConfig
+}
+
+// SessionConfig holds session related config
+type SessionConfig struct {
+ // SessionOn
+ // @Description if it's true, Beego will auto manage session
+ // @Default false
+ SessionOn bool
+ // SessionAutoSetCookie
+ // @Description if it's true, Beego will put the session token into cookie too
+ // @Default true
+ SessionAutoSetCookie bool
+ // SessionDisableHTTPOnly
+ // @Description used to allow for cross domain cookies/javascript cookies
+ // In general, you should not set it to true unless you understand the risk
+ // @Default false
+ SessionDisableHTTPOnly bool
+ // SessionEnableSidInHTTPHeader
+ // @Description enable store/get the sessionId into/from http headers
+ // @Default false
+ SessionEnableSidInHTTPHeader bool
+ // SessionEnableSidInURLQuery
+ // @Description enable get the sessionId from Url Query params
+ // @Default false
+ SessionEnableSidInURLQuery bool
+ // SessionProvider
+ // @Description session provider's name.
+ // You should confirm that this provider has been register via session.Register method
+ // the default value is memory. This is not suitable for distributed system
+ // @Default memory
+ SessionProvider string
+ // SessionName
+ // @Description If SessionAutoSetCookie is true, we use this value as the cookie's name
+ // @Default beegosessionID
+ SessionName string
+ // SessionGCMaxLifetime
+ // @Description Beego will GC session to clean useless session.
+ // unit: second
+ // @Default 3600
+ SessionGCMaxLifetime int64
+ // SessionProviderConfig
+ // @Description the config of session provider
+ // see SessionProvider
+ // you should read the document of session provider to learn how to set this value
+ // @Default ""
+ SessionProviderConfig string
+ // SessionCookieLifeTime
+ // @Description If SessionAutoSetCookie is true,
+ // we use this value as the expiration time and max age of the cookie
+ // unit second
+ // @Default 0
+ SessionCookieLifeTime int
+ // SessionDomain
+ // @Description If SessionAutoSetCookie is true, we use this value as the cookie's domain
+ // @Default ""
+ SessionDomain string
+ // SessionNameInHTTPHeader
+ // @Description if SessionEnableSidInHTTPHeader is true, this value will be used as the http header
+ // @Default Beegosessionid
+ SessionNameInHTTPHeader string
+ // SessionCookieSameSite
+ // @Description If SessionAutoSetCookie is true, we use this value as the cookie's same site policy
+ // the default value is http.SameSiteDefaultMode
+ // @Default 1
+ SessionCookieSameSite http.SameSite
+
+ // SessionIDPrefix
+ // @Description session id's prefix
+ // @Default ""
+ SessionIDPrefix string
+}
+
+// LogConfig holds Log related config
+type LogConfig struct {
+ // AccessLogs
+ // @Description If it's true, Beego will log the HTTP request info
+ // @Default false
+ AccessLogs bool
+ // EnableStaticLogs
+ // @Description log static files requests
+ // @Default false
+ EnableStaticLogs bool
+ // FileLineNum
+ // @Description if it's true, it will log the line number
+ // @Default true
+ FileLineNum bool
+ // AccessLogsFormat
+ // @Description access log format: JSON_FORMAT, APACHE_FORMAT or empty string
+ // @Default APACHE_FORMAT
+ AccessLogsFormat string
+ // Outputs
+ // @Description the destination of access log
+ // the key is log adapter and the value is adapter's configure
+ // @Default "console" => ""
+ Outputs map[string]string // Store Adaptor : config
+}
+
+var (
+ // BConfig is the default config for Application
+ BConfig *Config
+ // AppConfig is the instance of Config, store the config information from file
+ AppConfig *beegoAppConfig
+ // AppPath is the absolute path to the app
+ AppPath string
+ // GlobalSessions is the instance for the session manager
+ GlobalSessions *session.Manager
+
+ // appConfigPath is the path to the config files
+ appConfigPath string
+ // appConfigProvider is the provider for the config, default is ini
+ appConfigProvider = "ini"
+ // WorkPath is the absolute path to project root directory
+ WorkPath string
+)
+
+func init() {
+ BConfig = newBConfig()
+ var err error
+ if AppPath, err = filepath.Abs(filepath.Dir(os.Args[0])); err != nil {
+ panic(err)
+ }
+ WorkPath, err = os.Getwd()
+ if err != nil {
+ panic(err)
+ }
+ filename := "app.conf"
+ if os.Getenv("BEEGO_RUNMODE") != "" {
+ filename = os.Getenv("BEEGO_RUNMODE") + ".app.conf"
+ }
+ appConfigPath = filepath.Join(WorkPath, "conf", filename)
+ if !utils.FileExists(appConfigPath) {
+ appConfigPath = filepath.Join(AppPath, "conf", filename)
+ if !utils.FileExists(appConfigPath) {
+ AppConfig = &beegoAppConfig{innerConfig: config.NewFakeConfig()}
+ return
+ }
+ }
+ if err = parseConfig(appConfigPath); err != nil {
+ panic(err)
+ }
+}
+
+func defaultRecoverPanic(ctx *context.Context, cfg *Config) {
+ if err := recover(); err != nil {
+ if err == ErrAbort {
+ return
+ }
+ if !cfg.RecoverPanic {
+ panic(err)
+ }
+ if cfg.EnableErrorsShow {
+ if _, ok := ErrorMaps[fmt.Sprint(err)]; ok {
+ exception(fmt.Sprint(err), ctx)
+ return
+ }
+ }
+ var stack string
+ logs.Critical("the request url is ", ctx.Input.URL())
+ logs.Critical("Handler crashed with error", err)
+ for i := 1; ; i++ {
+ _, file, line, ok := runtime.Caller(i)
+ if !ok {
+ break
+ }
+ logs.Critical(fmt.Sprintf("%s:%d", file, line))
+ stack = stack + fmt.Sprintln(fmt.Sprintf("%s:%d", file, line))
+ }
+
+ if ctx.Output.Status != 0 {
+ ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
+ } else {
+ ctx.ResponseWriter.WriteHeader(500)
+ }
+
+ if cfg.RunMode == DEV && cfg.EnableErrorsRender {
+ showErr(err, ctx, stack)
+ }
+ }
+}
+
+func newBConfig() *Config {
+ res := &Config{
+ AppName: "beego",
+ RunMode: PROD,
+ RouterCaseSensitive: true,
+ ServerName: "beegoServer:" + beego.VERSION,
+ RecoverPanic: true,
+
+ CopyRequestBody: false,
+ EnableGzip: false,
+ MaxMemory: 1 << 26, // 64MB
+ MaxUploadSize: 1 << 30, // 1GB
+ EnableErrorsShow: true,
+ EnableErrorsRender: true,
+ Listen: Listen{
+ Graceful: false,
+ ServerTimeOut: 0,
+ ListenTCP4: false,
+ EnableHTTP: true,
+ AutoTLS: false,
+ Domains: []string{},
+ TLSCacheDir: ".",
+ HTTPAddr: "",
+ HTTPPort: 8080,
+ EnableHTTPS: false,
+ HTTPSAddr: "",
+ HTTPSPort: 10443,
+ HTTPSCertFile: "",
+ HTTPSKeyFile: "",
+ EnableAdmin: false,
+ AdminAddr: "",
+ AdminPort: 8088,
+ EnableFcgi: false,
+ EnableStdIo: false,
+ ClientAuth: int(tls.RequireAndVerifyClientCert),
+ },
+ WebConfig: WebConfig{
+ AutoRender: true,
+ EnableDocs: false,
+ FlashName: "BEEGO_FLASH",
+ FlashSeparator: "BEEGOFLASH",
+ DirectoryIndex: false,
+ StaticDir: map[string]string{"/static": "static"},
+ StaticExtensionsToGzip: []string{".css", ".js"},
+ StaticCacheFileSize: 1024 * 100,
+ StaticCacheFileNum: 1000,
+ TemplateLeft: "{{",
+ TemplateRight: "}}",
+ ViewsPath: "views",
+ CommentRouterPath: "controllers",
+ EnableXSRF: false,
+ XSRFKey: "beegoxsrf",
+ XSRFExpire: 0,
+ Session: SessionConfig{
+ SessionOn: false,
+ SessionProvider: "memory",
+ SessionName: "beegosessionID",
+ SessionGCMaxLifetime: 3600,
+ SessionProviderConfig: "",
+ SessionDisableHTTPOnly: false,
+ SessionCookieLifeTime: 0, // set cookie default is the browser life
+ SessionAutoSetCookie: true,
+ SessionDomain: "",
+ SessionEnableSidInHTTPHeader: false, // enable store/get the sessionId into/from http headers
+ SessionNameInHTTPHeader: "Beegosessionid",
+ SessionEnableSidInURLQuery: false, // enable get the sessionId from Url Query params
+ SessionCookieSameSite: http.SameSiteDefaultMode,
+ },
+ },
+ Log: LogConfig{
+ AccessLogs: false,
+ EnableStaticLogs: false,
+ AccessLogsFormat: "APACHE_FORMAT",
+ FileLineNum: true,
+ Outputs: map[string]string{"console": ""},
+ },
+ }
+
+ res.RecoverFunc = defaultRecoverPanic
+ return res
+}
+
+// now only support ini, next will support json.
+func parseConfig(appConfigPath string) (err error) {
+ AppConfig, err = newAppConfig(appConfigProvider, appConfigPath)
+ if err != nil {
+ return err
+ }
+ return assignConfig(AppConfig)
+}
+
+// assignConfig is tricky.
+// For 1.x, it use assignSingleConfig to parse the file
+// but for 2.x, we use Unmarshaler method
+func assignConfig(ac config.Configer) error {
+ parseConfigForV1(ac)
+
+ err := ac.Unmarshaler("", BConfig)
+ if err != nil {
+ _, _ = fmt.Fprintln(os.Stderr, fmt.Sprintf("Unmarshaler config file to BConfig failed. "+
+ "And if you are working on v1.x config file, please ignore this, err: %s", err))
+ return err
+ }
+
+ // init log
+ logs.Reset()
+ for adaptor, cfg := range BConfig.Log.Outputs {
+ err := logs.SetLogger(adaptor, cfg)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, fmt.Sprintf("%s with the config %q got err:%s", adaptor, cfg, err.Error()))
+ return err
+ }
+ }
+ logs.SetLogFuncCall(BConfig.Log.FileLineNum)
+ return nil
+}
+
+func parseConfigForV1(ac config.Configer) {
+ for _, i := range []interface{}{BConfig, &BConfig.Listen, &BConfig.WebConfig, &BConfig.Log, &BConfig.WebConfig.Session} {
+ assignSingleConfig(i, ac)
+ }
+
+ // set the run mode first
+ if envRunMode := os.Getenv("BEEGO_RUNMODE"); envRunMode != "" {
+ BConfig.RunMode = envRunMode
+ } else if runMode, err := ac.String("RunMode"); runMode != "" && err == nil {
+ BConfig.RunMode = runMode
+ }
+
+ if sd, err := ac.String("StaticDir"); sd != "" && err == nil {
+ BConfig.WebConfig.StaticDir = map[string]string{}
+ sds := strings.Fields(sd)
+ for _, v := range sds {
+ if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 {
+ BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[1]
+ } else {
+ BConfig.WebConfig.StaticDir["/"+strings.Trim(url2fsmap[0], "/")] = url2fsmap[0]
+ }
+ }
+ }
+
+ if sgz, err := ac.String("StaticExtensionsToGzip"); sgz != "" && err == nil {
+ extensions := strings.Split(sgz, ",")
+ fileExts := []string{}
+ for _, ext := range extensions {
+ ext = strings.TrimSpace(ext)
+ if ext == "" {
+ continue
+ }
+ if !strings.HasPrefix(ext, ".") {
+ ext = "." + ext
+ }
+ fileExts = append(fileExts, ext)
+ }
+ if len(fileExts) > 0 {
+ BConfig.WebConfig.StaticExtensionsToGzip = fileExts
+ }
+ }
+
+ if sfs, err := ac.Int("StaticCacheFileSize"); err == nil {
+ BConfig.WebConfig.StaticCacheFileSize = sfs
+ }
+
+ if sfn, err := ac.Int("StaticCacheFileNum"); err == nil {
+ BConfig.WebConfig.StaticCacheFileNum = sfn
+ }
+
+ if lo, err := ac.String("LogOutputs"); lo != "" && err == nil {
+ // if lo is not nil or empty
+ // means user has set his own LogOutputs
+ // clear the default setting to BConfig.Log.Outputs
+ BConfig.Log.Outputs = make(map[string]string)
+ los := strings.Split(lo, ";")
+ for _, v := range los {
+ if logType2Config := strings.SplitN(v, ",", 2); len(logType2Config) == 2 {
+ BConfig.Log.Outputs[logType2Config[0]] = logType2Config[1]
+ } else {
+ continue
+ }
+ }
+ }
+}
+
+func assignSingleConfig(p interface{}, ac config.Configer) {
+ pt := reflect.TypeOf(p)
+ if pt.Kind() != reflect.Ptr {
+ return
+ }
+ pt = pt.Elem()
+ if pt.Kind() != reflect.Struct {
+ return
+ }
+ pv := reflect.ValueOf(p).Elem()
+
+ for i := 0; i < pt.NumField(); i++ {
+ pf := pv.Field(i)
+ if !pf.CanSet() {
+ continue
+ }
+ name := pt.Field(i).Name
+ switch pf.Kind() {
+ case reflect.String:
+ pf.SetString(ac.DefaultString(name, pf.String()))
+ case reflect.Int, reflect.Int64:
+ pf.SetInt(ac.DefaultInt64(name, pf.Int()))
+ case reflect.Bool:
+ pf.SetBool(ac.DefaultBool(name, pf.Bool()))
+ case reflect.Struct:
+ default:
+ // do nothing here
+ }
+ }
+}
+
+// LoadAppConfig allow developer to apply a config file
+func LoadAppConfig(adapterName, configPath string) error {
+ absConfigPath, err := filepath.Abs(configPath)
+ if err != nil {
+ return err
+ }
+
+ if !utils.FileExists(absConfigPath) {
+ return fmt.Errorf("the target config file: %s don't exist", configPath)
+ }
+
+ appConfigPath = absConfigPath
+ appConfigProvider = adapterName
+
+ return parseConfig(appConfigPath)
+}
+
+type beegoAppConfig struct {
+ config.BaseConfiger
+ innerConfig config.Configer
+}
+
+func newAppConfig(appConfigProvider, appConfigPath string) (*beegoAppConfig, error) {
+ ac, err := config.NewConfig(appConfigProvider, appConfigPath)
+ if err != nil {
+ return nil, err
+ }
+ return &beegoAppConfig{innerConfig: ac}, nil
+}
+
+func (b *beegoAppConfig) Unmarshaler(prefix string, obj interface{}, opt ...config.DecodeOption) error {
+ return b.innerConfig.Unmarshaler(prefix, obj, opt...)
+}
+
+func (b *beegoAppConfig) Set(key, val string) error {
+ if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
+ return b.innerConfig.Set(key, val)
+ }
+ return nil
+}
+
+func (b *beegoAppConfig) String(key string) (string, error) {
+ if v, err := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" && err == nil {
+ return v, nil
+ }
+ return b.innerConfig.String(key)
+}
+
+func (b *beegoAppConfig) Strings(key string) ([]string, error) {
+ if v, err := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 && err == nil {
+ return v, nil
+ }
+ return b.innerConfig.Strings(key)
+}
+
+func (b *beegoAppConfig) Int(key string) (int, error) {
+ if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
+ return v, nil
+ }
+ return b.innerConfig.Int(key)
+}
+
+func (b *beegoAppConfig) Int64(key string) (int64, error) {
+ if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
+ return v, nil
+ }
+ return b.innerConfig.Int64(key)
+}
+
+func (b *beegoAppConfig) Bool(key string) (bool, error) {
+ if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
+ return v, nil
+ }
+ return b.innerConfig.Bool(key)
+}
+
+func (b *beegoAppConfig) Float(key string) (float64, error) {
+ if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
+ return v, nil
+ }
+ return b.innerConfig.Float(key)
+}
+
+func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
+ if v, err := b.String(key); v != "" && err == nil {
+ return v
+ }
+ return defaultVal
+}
+
+func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
+ if v, err := b.Strings(key); len(v) != 0 && err == nil {
+ return v
+ }
+ return defaultVal
+}
+
+func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
+ if v, err := b.Int(key); err == nil {
+ return v
+ }
+ return defaultVal
+}
+
+func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
+ if v, err := b.Int64(key); err == nil {
+ return v
+ }
+ return defaultVal
+}
+
+func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
+ if v, err := b.Bool(key); err == nil {
+ return v
+ }
+ return defaultVal
+}
+
+func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
+ if v, err := b.Float(key); err == nil {
+ return v
+ }
+ return defaultVal
+}
+
+func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
+ return b.innerConfig.DIY(key)
+}
+
+func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
+ return b.innerConfig.GetSection(section)
+}
+
+func (b *beegoAppConfig) SaveConfigFile(filename string) error {
+ return b.innerConfig.SaveConfigFile(filename)
+}
diff --git a/src/vendor/github.com/beego/beego/context/acceptencoder.go b/src/vendor/github.com/beego/beego/v2/server/web/context/acceptencoder.go
similarity index 81%
rename from src/vendor/github.com/beego/beego/context/acceptencoder.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/acceptencoder.go
index b4e2492c0..4181bfee9 100644
--- a/src/vendor/github.com/beego/beego/context/acceptencoder.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/acceptencoder.go
@@ -28,18 +28,18 @@ import (
)
var (
- //Default size==20B same as nginx
+ // Default size==20B same as nginx
defaultGzipMinLength = 20
- //Content will only be compressed if content length is either unknown or greater than gzipMinLength.
+ // Content will only be compressed if content length is either unknown or greater than gzipMinLength.
gzipMinLength = defaultGzipMinLength
- //The compression level used for deflate compression. (0-9).
+ // Compression level used for deflate compression. (0-9).
gzipCompressLevel int
- //List of HTTP methods to compress. If not set, only GET requests are compressed.
+ // List of HTTP methods to compress. If not set, only GET requests are compressed.
includedMethods map[string]bool
getMethodOnly bool
)
-// InitGzip init the gzipcompress
+// InitGzip initializes the gzipcompress
func InitGzip(minLength, compressLevel int, methods []string) {
if minLength >= 0 {
gzipMinLength = minLength
@@ -65,7 +65,7 @@ type nopResetWriter struct {
}
func (n nopResetWriter) Reset(w io.Writer) {
- //do nothing
+ // do nothing
}
type acceptEncoder struct {
@@ -98,9 +98,9 @@ func (ac acceptEncoder) put(wr resetWriter, level int) {
}
wr.Reset(nil)
- //notice
- //compressionLevel==BestCompression DOES NOT MATTER
- //sync.Pool will not memory leak
+ // notice
+ // compressionLevel==BestCompression DOES NOT MATTER
+ // sync.Pool will not memory leak
switch level {
case gzipCompressLevel:
@@ -119,10 +119,10 @@ var (
bestCompressionPool: &sync.Pool{New: func() interface{} { wr, _ := gzip.NewWriterLevel(nil, flate.BestCompression); return wr }},
}
- //according to the sec :http://tools.ietf.org/html/rfc2616#section-3.5 ,the deflate compress in http is zlib indeed
- //deflate
- //The "zlib" format defined in RFC 1950 [31] in combination with
- //the "deflate" compression mechanism described in RFC 1951 [29].
+ // According to: http://tools.ietf.org/html/rfc2616#section-3.5 the deflate compress in http is zlib indeed
+ // deflate
+ // The "zlib" format defined in RFC 1950 [31] in combination with
+ // the "deflate" compression mechanism described in RFC 1951 [29].
deflateCompressEncoder = acceptEncoder{
name: "deflate",
levelEncode: func(level int) resetWriter { wr, _ := zlib.NewWriterLevel(nil, level); return wr },
@@ -131,21 +131,19 @@ var (
}
)
-var (
- encoderMap = map[string]acceptEncoder{ // all the other compress methods will ignore
- "gzip": gzipCompressEncoder,
- "deflate": deflateCompressEncoder,
- "*": gzipCompressEncoder, // * means any compress will accept,we prefer gzip
- "identity": noneCompressEncoder, // identity means none-compress
- }
-)
+var encoderMap = map[string]acceptEncoder{ // all the other compress methods will ignore
+ "gzip": gzipCompressEncoder,
+ "deflate": deflateCompressEncoder,
+ "*": gzipCompressEncoder, // * means any compress will accept,we prefer gzip
+ "identity": noneCompressEncoder, // identity means none-compress
+}
// WriteFile reads from file and writes to writer by the specific encoding(gzip/deflate)
func WriteFile(encoding string, writer io.Writer, file *os.File) (bool, string, error) {
return writeLevel(encoding, writer, file, flate.BestCompression)
}
-// WriteBody reads writes content to writer by the specific encoding(gzip/deflate)
+// WriteBody reads writes content to writer by the specific encoding(gzip/deflate)
func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string, error) {
if encoding == "" || len(content) < gzipMinLength {
_, err := writer.Write(content)
@@ -154,12 +152,12 @@ func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string,
return writeLevel(encoding, writer, bytes.NewReader(content), gzipCompressLevel)
}
-// writeLevel reads from reader,writes to writer by specific encoding and compress level
-// the compress level is defined by deflate package
+// writeLevel reads from reader and writes to writer by specific encoding and compress level.
+// The compress level is defined by deflate package
func writeLevel(encoding string, writer io.Writer, reader io.Reader, level int) (bool, string, error) {
var outputWriter resetWriter
var err error
- var ce = noneCompressEncoder
+ ce := noneCompressEncoder
if cf, ok := encoderMap[encoding]; ok {
ce = cf
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/context/context.go b/src/vendor/github.com/beego/beego/v2/server/web/context/context.go
new file mode 100644
index 000000000..c85dc45b5
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/context.go
@@ -0,0 +1,399 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package context provide the context utils
+// Usage:
+//
+// import "github.com/beego/beego/v2/server/web/context"
+//
+// ctx := context.Context{Request:req,ResponseWriter:rw}
+//
+// more docs http://beego.vip/docs/module/context.md
+package context
+
+import (
+ "bufio"
+ "crypto/hmac"
+ "crypto/sha256"
+ "encoding/base64"
+ "encoding/json"
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "net"
+ "net/http"
+ "net/url"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+
+ "google.golang.org/protobuf/proto"
+ "gopkg.in/yaml.v3"
+
+ "github.com/beego/beego/v2/core/utils"
+ "github.com/beego/beego/v2/server/web/session"
+)
+
+// Commonly used mime-types
+const (
+ ApplicationJSON = "application/json"
+ ApplicationXML = "application/xml"
+ ApplicationForm = "application/x-www-form-urlencoded"
+ ApplicationProto = "application/x-protobuf"
+ ApplicationYAML = "application/x-yaml"
+ TextXML = "text/xml"
+
+ formatTime = "15:04:05"
+ formatDate = "2006-01-02"
+ formatDateTime = "2006-01-02 15:04:05"
+ formatDateTimeT = "2006-01-02T15:04:05"
+)
+
+// NewContext return the Context with Input and Output
+func NewContext() *Context {
+ return &Context{
+ Input: NewInput(),
+ Output: NewOutput(),
+ }
+}
+
+// Context Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter.
+// BeegoInput and BeegoOutput provides an api to operate request and response more easily.
+type Context struct {
+ Input *BeegoInput
+ Output *BeegoOutput
+ Request *http.Request
+ ResponseWriter *Response
+ _xsrfToken string
+}
+
+func (ctx *Context) Bind(obj interface{}) error {
+ ct, exist := ctx.Request.Header["Content-Type"]
+ if !exist || len(ct) == 0 {
+ return ctx.BindJSON(obj)
+ }
+ i, l := 0, len(ct[0])
+ for i < l && ct[0][i] != ';' {
+ i++
+ }
+ switch ct[0][0:i] {
+ case ApplicationJSON:
+ return ctx.BindJSON(obj)
+ case ApplicationXML, TextXML:
+ return ctx.BindXML(obj)
+ case ApplicationForm:
+ return ctx.BindForm(obj)
+ case ApplicationProto:
+ return ctx.BindProtobuf(obj.(proto.Message))
+ case ApplicationYAML:
+ return ctx.BindYAML(obj)
+ default:
+ return errors.New("Unsupported Content-Type:" + ct[0])
+ }
+}
+
+// Resp sends response based on the Accept Header
+// By default response will be in JSON
+func (ctx *Context) Resp(data interface{}) error {
+ accept := ctx.Input.Header("Accept")
+ switch accept {
+ case ApplicationYAML:
+ return ctx.YamlResp(data)
+ case ApplicationXML, TextXML:
+ return ctx.XMLResp(data)
+ case ApplicationProto:
+ return ctx.ProtoResp(data.(proto.Message))
+ default:
+ return ctx.JSONResp(data)
+ }
+}
+
+func (ctx *Context) JSONResp(data interface{}) error {
+ return ctx.Output.JSON(data, false, false)
+}
+
+func (ctx *Context) XMLResp(data interface{}) error {
+ return ctx.Output.XML(data, false)
+}
+
+func (ctx *Context) YamlResp(data interface{}) error {
+ return ctx.Output.YAML(data)
+}
+
+func (ctx *Context) ProtoResp(data proto.Message) error {
+ return ctx.Output.Proto(data)
+}
+
+// BindYAML only read data from http request body
+func (ctx *Context) BindYAML(obj interface{}) error {
+ return yaml.Unmarshal(ctx.Input.RequestBody, obj)
+}
+
+// BindForm will parse form values to struct via tag.
+func (ctx *Context) BindForm(obj interface{}) error {
+ err := ctx.Request.ParseForm()
+ if err != nil {
+ return err
+ }
+ return ParseForm(ctx.Request.Form, obj)
+}
+
+// BindJSON only read data from http request body
+func (ctx *Context) BindJSON(obj interface{}) error {
+ return json.Unmarshal(ctx.Input.RequestBody, obj)
+}
+
+// BindProtobuf only read data from http request body
+func (ctx *Context) BindProtobuf(obj proto.Message) error {
+ return proto.Unmarshal(ctx.Input.RequestBody, obj)
+}
+
+// BindXML only read data from http request body
+func (ctx *Context) BindXML(obj interface{}) error {
+ return xml.Unmarshal(ctx.Input.RequestBody, obj)
+}
+
+// ParseForm will parse form values to struct via tag.
+func ParseForm(form url.Values, obj interface{}) error {
+ objT := reflect.TypeOf(obj)
+ objV := reflect.ValueOf(obj)
+ if !isStructPtr(objT) {
+ return fmt.Errorf("%v must be a struct pointer", obj)
+ }
+ objT = objT.Elem()
+ objV = objV.Elem()
+ return parseFormToStruct(form, objT, objV)
+}
+
+func isStructPtr(t reflect.Type) bool {
+ return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
+}
+
+// Reset initializes Context, BeegoInput and BeegoOutput
+func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
+ ctx.Request = r
+ if ctx.ResponseWriter == nil {
+ ctx.ResponseWriter = &Response{}
+ }
+ ctx.ResponseWriter.reset(rw)
+ ctx.Input.Reset(ctx)
+ ctx.Output.Reset(ctx)
+ ctx._xsrfToken = ""
+}
+
+// Redirect redirects to localurl with http header status code.
+func (ctx *Context) Redirect(status int, localurl string) {
+ http.Redirect(ctx.ResponseWriter, ctx.Request, localurl, status)
+}
+
+// Abort stops the request.
+// If beego.ErrorMaps exists, panic body.
+func (ctx *Context) Abort(status int, body string) {
+ ctx.Output.SetStatus(status)
+ panic(body)
+}
+
+// WriteString writes a string to response body.
+func (ctx *Context) WriteString(content string) {
+ _, _ = ctx.ResponseWriter.Write([]byte(content))
+}
+
+// GetCookie gets a cookie from a request for a given key.
+// (Alias of BeegoInput.Cookie)
+func (ctx *Context) GetCookie(key string) string {
+ return ctx.Input.Cookie(key)
+}
+
+// SetCookie sets a cookie for a response.
+// (Alias of BeegoOutput.Cookie)
+func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
+ ctx.Output.Cookie(name, value, others...)
+}
+
+// GetSecureCookie gets a secure cookie from a request for a given key.
+func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
+ val := ctx.Input.Cookie(key)
+ if val == "" {
+ return "", false
+ }
+
+ parts := strings.SplitN(val, "|", 3)
+
+ if len(parts) != 3 {
+ return "", false
+ }
+
+ vs := parts[0]
+ timestamp := parts[1]
+ sig := parts[2]
+
+ h := hmac.New(sha256.New, []byte(Secret))
+ _, err := fmt.Fprintf(h, "%s%s", vs, timestamp)
+ if err != nil {
+ return "", false
+ }
+
+ if fmt.Sprintf("%02x", h.Sum(nil)) != sig {
+ return "", false
+ }
+ res, _ := base64.URLEncoding.DecodeString(vs)
+ return string(res), true
+}
+
+// SetSecureCookie sets a secure cookie for a response.
+func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
+ vs := base64.URLEncoding.EncodeToString([]byte(value))
+ timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+ h := hmac.New(sha256.New, []byte(Secret))
+ _, _ = fmt.Fprintf(h, "%s%s", vs, timestamp)
+ sig := fmt.Sprintf("%02x", h.Sum(nil))
+ cookie := strings.Join([]string{vs, timestamp, sig}, "|")
+ ctx.Output.Cookie(name, cookie, others...)
+}
+
+// XSRFToken creates and returns an xsrf token string
+func (ctx *Context) XSRFToken(key string, expire int64) string {
+ if ctx._xsrfToken == "" {
+ token, ok := ctx.GetSecureCookie(key, "_xsrf")
+ if !ok {
+ token = string(utils.RandomCreateBytes(32))
+ // TODO make it configurable
+ ctx.SetSecureCookie(key, "_xsrf", token, expire, "/", "", true, true)
+ }
+ ctx._xsrfToken = token
+ }
+ return ctx._xsrfToken
+}
+
+// CheckXSRFCookie checks if the XSRF token in this request is valid or not.
+// The token can be provided in the request header in the form "X-Xsrftoken" or "X-CsrfToken"
+// or in form field value named as "_xsrf".
+func (ctx *Context) CheckXSRFCookie() bool {
+ token := ctx.Input.Query("_xsrf")
+ if token == "" {
+ token = ctx.Request.Header.Get("X-Xsrftoken")
+ }
+ if token == "" {
+ token = ctx.Request.Header.Get("X-Csrftoken")
+ }
+ if token == "" {
+ ctx.Abort(422, "422")
+ return false
+ }
+ if ctx._xsrfToken != token {
+ ctx.Abort(417, "417")
+ return false
+ }
+ return true
+}
+
+// RenderMethodResult renders the return value of a controller method to the output
+func (ctx *Context) RenderMethodResult(result interface{}) {
+ if result != nil {
+ renderer, ok := result.(Renderer)
+ if !ok {
+ err, ok := result.(error)
+ if ok {
+ renderer = errorRenderer(err)
+ } else {
+ renderer = jsonRenderer(result)
+ }
+ }
+ renderer.Render(ctx)
+ }
+}
+
+// Session return session store of this context of request
+func (ctx *Context) Session() (store session.Store, err error) {
+ if ctx.Input != nil {
+ if ctx.Input.CruSession != nil {
+ store = ctx.Input.CruSession
+ return
+ } else {
+ err = errors.New(`no valid session store(please initialize session)`)
+ return
+ }
+ } else {
+ err = errors.New(`no valid input`)
+ return
+ }
+}
+
+// Response is a wrapper for the http.ResponseWriter
+// Started: if true, response was already written to so the other handler will not be executed
+type Response struct {
+ http.ResponseWriter
+ Started bool
+ Status int
+ Elapsed time.Duration
+}
+
+func (r *Response) reset(rw http.ResponseWriter) {
+ r.ResponseWriter = rw
+ r.Status = 0
+ r.Started = false
+}
+
+// Write writes the data to the connection as part of a HTTP reply,
+// and sets `Started` to true.
+// Started: if true, the response was already sent
+func (r *Response) Write(p []byte) (int, error) {
+ r.Started = true
+ return r.ResponseWriter.Write(p)
+}
+
+// WriteHeader sends a HTTP response header with status code,
+// and sets `Started` to true.
+func (r *Response) WriteHeader(code int) {
+ if r.Status > 0 {
+ // prevent multiple response.WriteHeader calls
+ return
+ }
+ r.Status = code
+ r.Started = true
+ r.ResponseWriter.WriteHeader(code)
+}
+
+// Hijack hijacker for http
+func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
+ hj, ok := r.ResponseWriter.(http.Hijacker)
+ if !ok {
+ return nil, nil, errors.New("webserver doesn't support hijacking")
+ }
+ return hj.Hijack()
+}
+
+// Flush http.Flusher
+func (r *Response) Flush() {
+ if f, ok := r.ResponseWriter.(http.Flusher); ok {
+ f.Flush()
+ }
+}
+
+// CloseNotify http.CloseNotifier
+func (r *Response) CloseNotify() <-chan bool {
+ if cn, ok := r.ResponseWriter.(http.CloseNotifier); ok {
+ return cn.CloseNotify()
+ }
+ return nil
+}
+
+// Pusher http.Pusher
+func (r *Response) Pusher() (pusher http.Pusher) {
+ if pusher, ok := r.ResponseWriter.(http.Pusher); ok {
+ return pusher
+ }
+ return nil
+}
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/context/form.go b/src/vendor/github.com/beego/beego/v2/server/web/context/form.go
new file mode 100644
index 000000000..07a1b0b22
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/form.go
@@ -0,0 +1,189 @@
+// Copyright 2020 beego
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package context
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+)
+
+var (
+ sliceOfInts = reflect.TypeOf([]int(nil))
+ sliceOfStrings = reflect.TypeOf([]string(nil))
+)
+
+// ParseForm will parse form values to struct via tag.
+// Support for anonymous struct.
+func parseFormToStruct(form url.Values, objT reflect.Type, objV reflect.Value) error {
+ for i := 0; i < objT.NumField(); i++ {
+ fieldV := objV.Field(i)
+ if !fieldV.CanSet() {
+ continue
+ }
+
+ fieldT := objT.Field(i)
+ if fieldT.Anonymous && fieldT.Type.Kind() == reflect.Struct {
+ err := parseFormToStruct(form, fieldT.Type, fieldV)
+ if err != nil {
+ return err
+ }
+ continue
+ }
+
+ tag, ok := formTagName(fieldT)
+ if !ok {
+ continue
+ }
+
+ value, ok := formValue(tag, form, fieldT)
+ if !ok {
+ continue
+ }
+
+ switch fieldT.Type.Kind() {
+ case reflect.Bool:
+ b, err := parseFormBoolValue(value)
+ if err != nil {
+ return err
+ }
+ fieldV.SetBool(b)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ x, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ return err
+ }
+ fieldV.SetInt(x)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ x, err := strconv.ParseUint(value, 10, 64)
+ if err != nil {
+ return err
+ }
+ fieldV.SetUint(x)
+ case reflect.Float32, reflect.Float64:
+ x, err := strconv.ParseFloat(value, 64)
+ if err != nil {
+ return err
+ }
+ fieldV.SetFloat(x)
+ case reflect.Interface:
+ fieldV.Set(reflect.ValueOf(value))
+ case reflect.String:
+ fieldV.SetString(value)
+ case reflect.Struct:
+ if fieldT.Type.String() == "time.Time" {
+ t, err := parseFormTime(value)
+ if err != nil {
+ return err
+ }
+ fieldV.Set(reflect.ValueOf(t))
+ }
+ case reflect.Slice:
+ if fieldT.Type == sliceOfInts {
+ formVals := form[tag]
+ fieldV.Set(reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(int(1))), len(formVals), len(formVals)))
+ for i := 0; i < len(formVals); i++ {
+ val, err := strconv.Atoi(formVals[i])
+ if err != nil {
+ return err
+ }
+ fieldV.Index(i).SetInt(int64(val))
+ }
+ } else if fieldT.Type == sliceOfStrings {
+ formVals := form[tag]
+ fieldV.Set(reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf("")), len(formVals), len(formVals)))
+ for i := 0; i < len(formVals); i++ {
+ fieldV.Index(i).SetString(formVals[i])
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// nolint
+func parseFormTime(value string) (time.Time, error) {
+ var pattern string
+ if len(value) >= 25 {
+ value = value[:25]
+ pattern = time.RFC3339
+ } else if strings.HasSuffix(strings.ToUpper(value), "Z") {
+ pattern = time.RFC3339
+ } else if len(value) >= 19 {
+ if strings.Contains(value, "T") {
+ pattern = formatDateTimeT
+ } else {
+ pattern = formatDateTime
+ }
+ value = value[:19]
+ } else if len(value) >= 10 {
+ if len(value) > 10 {
+ value = value[:10]
+ }
+ pattern = formatDate
+ } else if len(value) >= 8 {
+ if len(value) > 8 {
+ value = value[:8]
+ }
+ pattern = formatTime
+ }
+ return time.ParseInLocation(pattern, value, time.Local)
+}
+
+func parseFormBoolValue(value string) (bool, error) {
+ if strings.ToLower(value) == "on" || strings.ToLower(value) == "1" || strings.ToLower(value) == "yes" {
+ return true, nil
+ }
+ if strings.ToLower(value) == "off" || strings.ToLower(value) == "0" || strings.ToLower(value) == "no" {
+ return false, nil
+ }
+ return strconv.ParseBool(value)
+}
+
+// nolint
+func formTagName(fieldT reflect.StructField) (string, bool) {
+ tags := strings.Split(fieldT.Tag.Get("form"), ",")
+ var tag string
+ if len(tags) == 0 || tags[0] == "" {
+ tag = fieldT.Name
+ } else if tags[0] == "-" {
+ return "", false
+ } else {
+ tag = tags[0]
+ }
+ return tag, true
+}
+
+func formValue(tag string, form url.Values, fieldT reflect.StructField) (string, bool) {
+ formValues := form[tag]
+ var value string
+ if len(formValues) == 0 {
+ defaultValue := fieldT.Tag.Get("default")
+ if defaultValue != "" {
+ value = defaultValue
+ } else {
+ return "", false
+ }
+ }
+ if len(formValues) == 1 {
+ value = formValues[0]
+ if value == "" {
+ return "", false
+ }
+ }
+ return value, true
+}
diff --git a/src/vendor/github.com/beego/beego/context/input.go b/src/vendor/github.com/beego/beego/v2/server/web/context/input.go
similarity index 92%
rename from src/vendor/github.com/beego/beego/context/input.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/input.go
index 385cc85ef..dfb14dfb9 100644
--- a/src/vendor/github.com/beego/beego/context/input.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/input.go
@@ -29,7 +29,7 @@ import (
"strings"
"sync"
- "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/server/web/session"
)
// Regexes for checking the accept headers
@@ -43,7 +43,7 @@ var (
)
// BeegoInput operates the http request header, data, cookie and body.
-// it also contains router params and current session.
+// Contains router params and current session.
type BeegoInput struct {
Context *Context
CruSession session.Store
@@ -56,7 +56,7 @@ type BeegoInput struct {
RunController reflect.Type
}
-// NewInput return BeegoInput generated by Context.
+// NewInput returns the BeegoInput generated by context.
func NewInput() *BeegoInput {
return &BeegoInput{
pnames: make([]string, 0, maxParam),
@@ -65,7 +65,7 @@ func NewInput() *BeegoInput {
}
}
-// Reset init the BeegoInput
+// Reset initializes the BeegoInput
func (input *BeegoInput) Reset(ctx *Context) {
input.Context = ctx
input.CruSession = nil
@@ -77,27 +77,27 @@ func (input *BeegoInput) Reset(ctx *Context) {
input.RequestBody = []byte{}
}
-// Protocol returns request protocol name, such as HTTP/1.1 .
+// Protocol returns the request protocol name, such as HTTP/1.1 .
func (input *BeegoInput) Protocol() string {
return input.Context.Request.Proto
}
-// URI returns full request url with query string, fragment.
+// URI returns the full request url with query, string and fragment.
func (input *BeegoInput) URI() string {
return input.Context.Request.RequestURI
}
-// URL returns request url path (without query string, fragment).
+// URL returns the request url path (without query, string and fragment).
func (input *BeegoInput) URL() string {
- return input.Context.Request.URL.EscapedPath()
+ return input.Context.Request.URL.Path
}
-// Site returns base site url as scheme://domain type.
+// Site returns the base site url as scheme://domain type.
func (input *BeegoInput) Site() string {
return input.Scheme() + "://" + input.Domain()
}
-// Scheme returns request scheme as "http" or "https".
+// Scheme returns the request scheme as "http" or "https".
func (input *BeegoInput) Scheme() string {
if scheme := input.Header("X-Forwarded-Proto"); scheme != "" {
return scheme
@@ -111,14 +111,13 @@ func (input *BeegoInput) Scheme() string {
return "https"
}
-// Domain returns host name.
-// Alias of Host method.
+// Domain returns the host name (alias of host method)
func (input *BeegoInput) Domain() string {
return input.Host()
}
-// Host returns host name.
-// if no host info in request, return localhost.
+// Host returns the host name.
+// If no host info in request, return localhost.
func (input *BeegoInput) Host() string {
if input.Context.Request.Host != "" {
if hostPart, _, err := net.SplitHostPort(input.Context.Request.Host); err == nil {
@@ -134,7 +133,7 @@ func (input *BeegoInput) Method() string {
return input.Context.Request.Method
}
-// Is returns boolean of this request is on given method, such as Is("POST").
+// Is returns the boolean value of this request is on given method, such as Is("POST").
func (input *BeegoInput) Is(method string) bool {
return input.Method() == method
}
@@ -154,7 +153,7 @@ func (input *BeegoInput) IsHead() bool {
return input.Is("HEAD")
}
-// IsOptions Is this a OPTIONS method request?
+// IsOptions Is this an OPTIONS method request?
func (input *BeegoInput) IsOptions() bool {
return input.Is("OPTIONS")
}
@@ -174,7 +173,7 @@ func (input *BeegoInput) IsPatch() bool {
return input.Is("PATCH")
}
-// IsAjax returns boolean of this request is generated by ajax.
+// IsAjax returns boolean of is this request generated by ajax.
func (input *BeegoInput) IsAjax() bool {
return input.Header("X-Requested-With") == "XMLHttpRequest"
}
@@ -251,7 +250,7 @@ func (input *BeegoInput) Refer() string {
}
// SubDomains returns sub domain string.
-// if aa.bb.domain.com, returns aa.bb .
+// if aa.bb.domain.com, returns aa.bb
func (input *BeegoInput) SubDomains() string {
parts := strings.Split(input.Host(), ".")
if len(parts) >= 3 {
@@ -306,7 +305,7 @@ func (input *BeegoInput) Params() map[string]string {
return m
}
-// SetParam will set the param with key and value
+// SetParam sets the param with key and value
func (input *BeegoInput) SetParam(key, val string) {
// check if already exists
for i, v := range input.pnames {
@@ -319,9 +318,8 @@ func (input *BeegoInput) SetParam(key, val string) {
input.pnames = append(input.pnames, key)
}
-// ResetParams clears any of the input's Params
-// This function is used to clear parameters so they may be reset between filter
-// passes.
+// ResetParams clears any of the input's params
+// Used to clear parameters so they may be reset between filter passes.
func (input *BeegoInput) ResetParams() {
input.pnames = input.pnames[:0]
input.pvalues = input.pvalues[:0]
@@ -363,7 +361,7 @@ func (input *BeegoInput) Cookie(key string) string {
// Session returns current session item value by a given key.
// if non-existed, return nil.
func (input *BeegoInput) Session(key interface{}) interface{} {
- return input.CruSession.Get(key)
+ return input.CruSession.Get(nil, key)
}
// CopyBody returns the raw request body data as bytes.
@@ -391,7 +389,7 @@ func (input *BeegoInput) CopyBody(MaxMemory int64) []byte {
return requestbody
}
-// Data return the implicit data in the input
+// Data returns the implicit data in the input
func (input *BeegoInput) Data() map[interface{}]interface{} {
input.dataLock.Lock()
defer input.dataLock.Unlock()
@@ -412,7 +410,7 @@ func (input *BeegoInput) GetData(key interface{}) interface{} {
}
// SetData stores data with given key in this context.
-// This data are only available in this context.
+// This data is only available in this context.
func (input *BeegoInput) SetData(key, val interface{}) {
input.dataLock.Lock()
defer input.dataLock.Unlock()
@@ -422,10 +420,10 @@ func (input *BeegoInput) SetData(key, val interface{}) {
input.data[key] = val
}
-// ParseFormOrMulitForm parseForm or parseMultiForm based on Content-type
-func (input *BeegoInput) ParseFormOrMulitForm(maxMemory int64) error {
+// ParseFormOrMultiForm parseForm or parseMultiForm based on Content-type
+func (input *BeegoInput) ParseFormOrMultiForm(maxMemory int64) error {
// Parse the body depending on the content type.
- if strings.Contains(input.Header("Content-Type"), "multipart/form-data") {
+ if input.IsUpload() {
if err := input.Context.Request.ParseMultipartForm(maxMemory); err != nil {
return errors.New("Error parsing request body:" + err.Error())
}
diff --git a/src/vendor/github.com/beego/beego/context/output.go b/src/vendor/github.com/beego/beego/v2/server/web/context/output.go
similarity index 81%
rename from src/vendor/github.com/beego/beego/context/output.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/output.go
index 41b95d968..f52eac9d8 100644
--- a/src/vendor/github.com/beego/beego/context/output.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/output.go
@@ -31,7 +31,8 @@ import (
"strings"
"time"
- yaml "gopkg.in/yaml.v2"
+ "google.golang.org/protobuf/proto"
+ "gopkg.in/yaml.v2"
)
// BeegoOutput does work for sending response header.
@@ -42,12 +43,12 @@ type BeegoOutput struct {
}
// NewOutput returns new BeegoOutput.
-// it contains nothing now.
+// Empty when initialized
func NewOutput() *BeegoOutput {
return &BeegoOutput{}
}
-// Reset init BeegoOutput
+// Reset initializes BeegoOutput
func (output *BeegoOutput) Reset(ctx *Context) {
output.Context = ctx
output.Status = 0
@@ -58,12 +59,12 @@ func (output *BeegoOutput) Header(key, val string) {
output.Context.ResponseWriter.Header().Set(key, val)
}
-// Body sets response body content.
-// if EnableGzip, compress content string.
-// it sends out response body directly.
+// Body sets the response body content.
+// if EnableGzip, content is compressed.
+// Sends out response body directly.
func (output *BeegoOutput) Body(content []byte) error {
var encoding string
- var buf = &bytes.Buffer{}
+ buf := &bytes.Buffer{}
if output.EnableGzip {
encoding = ParseEncoding(output.Context.Request)
}
@@ -85,13 +86,13 @@ func (output *BeegoOutput) Body(content []byte) error {
return nil
}
-// Cookie sets cookie value via given key.
-// others are ordered as cookie's max age time, path,domain, secure and httponly.
+// Cookie sets a cookie value via given key.
+// others: used to set a cookie's max age time, path,domain, secure and httponly.
func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) {
var b bytes.Buffer
fmt.Fprintf(&b, "%s=%s", sanitizeName(name), sanitizeValue(value))
- //fix cookie not work in IE
+ // fix cookie not work in IE
if len(others) > 0 {
var maxAge int64
@@ -154,6 +155,14 @@ func (output *BeegoOutput) Cookie(name string, value string, others ...interface
fmt.Fprintf(&b, "; HttpOnly")
}
}
+
+ // default empty
+ if len(others) > 5 {
+ if v, ok := others[5].(string); ok && len(v) > 0 {
+ fmt.Fprintf(&b, "; SameSite=%s", sanitizeValue(v))
+ }
+ }
+
output.Context.ResponseWriter.Header().Add("Set-Cookie", b.String())
}
@@ -182,7 +191,7 @@ func errorRenderer(err error) Renderer {
})
}
-// JSON writes json to response body.
+// JSON writes json to the response body.
// if encoding is true, it converts utf-8 to \u0000 type.
func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error {
output.Header("Content-Type", "application/json; charset=utf-8")
@@ -203,7 +212,7 @@ func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool)
return output.Body(content)
}
-// YAML writes yaml to response body.
+// YAML writes yaml to the response body.
func (output *BeegoOutput) YAML(data interface{}) error {
output.Header("Content-Type", "application/x-yaml; charset=utf-8")
var content []byte
@@ -216,7 +225,20 @@ func (output *BeegoOutput) YAML(data interface{}) error {
return output.Body(content)
}
-// JSONP writes jsonp to response body.
+// Proto writes protobuf to the response body.
+func (output *BeegoOutput) Proto(data proto.Message) error {
+ output.Header("Content-Type", "application/x-protobuf; charset=utf-8")
+ var content []byte
+ var err error
+ content, err = proto.Marshal(data)
+ if err != nil {
+ http.Error(output.Context.ResponseWriter, err.Error(), http.StatusInternalServerError)
+ return err
+ }
+ return output.Body(content)
+}
+
+// JSONP writes jsonp to the response body.
func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
output.Header("Content-Type", "application/javascript; charset=utf-8")
var content []byte
@@ -242,7 +264,7 @@ func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
return output.Body(callbackContent.Bytes())
}
-// XML writes xml string to response body.
+// XML writes xml string to the response body.
func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
output.Header("Content-Type", "application/xml; charset=utf-8")
var content []byte
@@ -259,21 +281,21 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
return output.Body(content)
}
-// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
-func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
+// ServeFormatted serves YAML, XML or JSON, depending on the value of the Accept header
+func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) error {
accept := output.Context.Input.Header("Accept")
switch accept {
case ApplicationYAML:
- output.YAML(data)
+ return output.YAML(data)
case ApplicationXML, TextXML:
- output.XML(data, hasIndent)
+ return output.XML(data, hasIndent)
default:
- output.JSON(data, hasIndent, len(hasEncode) > 0 && hasEncode[0])
+ return output.JSON(data, hasIndent, len(hasEncode) > 0 && hasEncode[0])
}
}
// Download forces response for download file.
-// it prepares the download response header automatically.
+// Prepares the download response header automatically.
func (output *BeegoOutput) Download(file string, filename ...string) {
// check get file error, file not found or other error.
if _, err := os.Stat(file); err != nil {
@@ -287,7 +309,7 @@ func (output *BeegoOutput) Download(file string, filename ...string) {
} else {
fName = filepath.Base(file)
}
- //https://tools.ietf.org/html/rfc6266#section-4.3
+ // https://tools.ietf.org/html/rfc6266#section-4.3
fn := url.PathEscape(fName)
if fName == fn {
fn = "filename=" + fn
@@ -322,61 +344,61 @@ func (output *BeegoOutput) ContentType(ext string) {
}
}
-// SetStatus sets response status code.
-// It writes response header directly.
+// SetStatus sets the response status code.
+// Writes response header directly.
func (output *BeegoOutput) SetStatus(status int) {
output.Status = status
}
-// IsCachable returns boolean of this request is cached.
+// IsCachable returns boolean of if this request is cached.
// HTTP 304 means cached.
func (output *BeegoOutput) IsCachable() bool {
return output.Status >= 200 && output.Status < 300 || output.Status == 304
}
-// IsEmpty returns boolean of this request is empty.
+// IsEmpty returns boolean of if this request is empty.
// HTTP 201,204 and 304 means empty.
func (output *BeegoOutput) IsEmpty() bool {
return output.Status == 201 || output.Status == 204 || output.Status == 304
}
-// IsOk returns boolean of this request runs well.
+// IsOk returns boolean of if this request was ok.
// HTTP 200 means ok.
func (output *BeegoOutput) IsOk() bool {
return output.Status == 200
}
-// IsSuccessful returns boolean of this request runs successfully.
+// IsSuccessful returns boolean of this request was successful.
// HTTP 2xx means ok.
func (output *BeegoOutput) IsSuccessful() bool {
return output.Status >= 200 && output.Status < 300
}
-// IsRedirect returns boolean of this request is redirection header.
+// IsRedirect returns boolean of if this request is redirected.
// HTTP 301,302,307 means redirection.
func (output *BeegoOutput) IsRedirect() bool {
return output.Status == 301 || output.Status == 302 || output.Status == 303 || output.Status == 307
}
-// IsForbidden returns boolean of this request is forbidden.
+// IsForbidden returns boolean of if this request is forbidden.
// HTTP 403 means forbidden.
func (output *BeegoOutput) IsForbidden() bool {
return output.Status == 403
}
-// IsNotFound returns boolean of this request is not found.
+// IsNotFound returns boolean of if this request is not found.
// HTTP 404 means not found.
func (output *BeegoOutput) IsNotFound() bool {
return output.Status == 404
}
-// IsClientError returns boolean of this request client sends error data.
+// IsClientError returns boolean of if this request client sends error data.
// HTTP 4xx means client error.
func (output *BeegoOutput) IsClientError() bool {
return output.Status >= 400 && output.Status < 500
}
-// IsServerError returns boolean of this server handler errors.
+// IsServerError returns boolean of if this server handler errors.
// HTTP 5xx means server internal error.
func (output *BeegoOutput) IsServerError() bool {
return output.Status >= 500 && output.Status < 600
@@ -403,5 +425,5 @@ func stringsToJSON(str string) string {
// Session sets session item value with given key.
func (output *BeegoOutput) Session(name interface{}, value interface{}) {
- output.Context.Input.CruSession.Set(name, value)
+ output.Context.Input.CruSession.Set(nil, name, value)
}
diff --git a/src/vendor/github.com/beego/beego/context/param/conv.go b/src/vendor/github.com/beego/beego/v2/server/web/context/param/conv.go
similarity index 95%
rename from src/vendor/github.com/beego/beego/context/param/conv.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/param/conv.go
index c12420425..eecb6acbd 100644
--- a/src/vendor/github.com/beego/beego/context/param/conv.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/param/conv.go
@@ -4,8 +4,8 @@ import (
"fmt"
"reflect"
- beecontext "github.com/beego/beego/context"
- "github.com/beego/beego/logs"
+ "github.com/beego/beego/v2/core/logs"
+ beecontext "github.com/beego/beego/v2/server/web/context"
)
// ConvertParams converts http method params to values that will be passed to the method controller as arguments
diff --git a/src/vendor/github.com/beego/beego/context/param/methodparams.go b/src/vendor/github.com/beego/beego/v2/server/web/context/param/methodparams.go
similarity index 85%
rename from src/vendor/github.com/beego/beego/context/param/methodparams.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/param/methodparams.go
index cd6708a27..22ff0e436 100644
--- a/src/vendor/github.com/beego/beego/context/param/methodparams.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/param/methodparams.go
@@ -5,7 +5,7 @@ import (
"strings"
)
-//MethodParam keeps param information to be auto passed to controller methods
+// MethodParam keeps param information to be auto passed to controller methods
type MethodParam struct {
name string
in paramType
@@ -22,7 +22,7 @@ const (
header
)
-//New creates a new MethodParam with name and specific options
+// New creates a new MethodParam with name and specific options
func New(name string, opts ...MethodParamOption) *MethodParam {
return newParam(name, nil, opts)
}
@@ -35,7 +35,7 @@ func newParam(name string, parser paramParser, opts []MethodParamOption) (param
return
}
-//Make creates an array of MethodParmas or an empty array
+// Make creates an array of MethodParmas or an empty array
func Make(list ...*MethodParam) []*MethodParam {
if len(list) > 0 {
return list
diff --git a/src/vendor/github.com/beego/beego/context/param/options.go b/src/vendor/github.com/beego/beego/v2/server/web/context/param/options.go
similarity index 100%
rename from src/vendor/github.com/beego/beego/context/param/options.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/param/options.go
diff --git a/src/vendor/github.com/beego/beego/context/param/parsers.go b/src/vendor/github.com/beego/beego/v2/server/web/context/param/parsers.go
similarity index 93%
rename from src/vendor/github.com/beego/beego/context/param/parsers.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/param/parsers.go
index 421aecf08..99ad9275e 100644
--- a/src/vendor/github.com/beego/beego/context/param/parsers.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/param/parsers.go
@@ -18,7 +18,7 @@ func getParser(param *MethodParam, t reflect.Type) paramParser {
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return intParser{}
case reflect.Slice:
- if t.Elem().Kind() == reflect.Uint8 { //treat []byte as string
+ if t.Elem().Kind() == reflect.Uint8 { // treat []byte as string
return stringParser{}
}
if param.in == body {
@@ -55,29 +55,25 @@ func (f parserFunc) parse(value string, toType reflect.Type) (interface{}, error
return f(value, toType)
}
-type boolParser struct {
-}
+type boolParser struct{}
func (p boolParser) parse(value string, toType reflect.Type) (interface{}, error) {
return strconv.ParseBool(value)
}
-type stringParser struct {
-}
+type stringParser struct{}
func (p stringParser) parse(value string, toType reflect.Type) (interface{}, error) {
return value, nil
}
-type intParser struct {
-}
+type intParser struct{}
func (p intParser) parse(value string, toType reflect.Type) (interface{}, error) {
return strconv.Atoi(value)
}
-type floatParser struct {
-}
+type floatParser struct{}
func (p floatParser) parse(value string, toType reflect.Type) (interface{}, error) {
if toType.Kind() == reflect.Float32 {
@@ -90,8 +86,7 @@ func (p floatParser) parse(value string, toType reflect.Type) (interface{}, erro
return strconv.ParseFloat(value, 64)
}
-type timeParser struct {
-}
+type timeParser struct{}
func (p timeParser) parse(value string, toType reflect.Type) (result interface{}, err error) {
result, err = time.Parse(time.RFC3339, value)
@@ -101,8 +96,7 @@ func (p timeParser) parse(value string, toType reflect.Type) (result interface{}
return
}
-type jsonParser struct {
-}
+type jsonParser struct{}
func (p jsonParser) parse(value string, toType reflect.Type) (interface{}, error) {
pResult := reflect.New(toType)
diff --git a/src/vendor/github.com/beego/beego/context/renderer.go b/src/vendor/github.com/beego/beego/v2/server/web/context/renderer.go
similarity index 77%
rename from src/vendor/github.com/beego/beego/context/renderer.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/renderer.go
index 36a7cb53f..5a0783324 100644
--- a/src/vendor/github.com/beego/beego/context/renderer.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/renderer.go
@@ -1,6 +1,6 @@
package context
-// Renderer defines an http response renderer
+// Renderer defines a http response renderer
type Renderer interface {
Render(ctx *Context)
}
diff --git a/src/vendor/github.com/beego/beego/context/response.go b/src/vendor/github.com/beego/beego/v2/server/web/context/response.go
similarity index 66%
rename from src/vendor/github.com/beego/beego/context/response.go
rename to src/vendor/github.com/beego/beego/v2/server/web/context/response.go
index 9c3c715a2..86b2c0b88 100644
--- a/src/vendor/github.com/beego/beego/context/response.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/context/response.go
@@ -1,27 +1,26 @@
package context
import (
- "strconv"
-
"net/http"
+ "strconv"
)
const (
- //BadRequest indicates http error 400
+ // BadRequest indicates HTTP error 400
BadRequest StatusCode = http.StatusBadRequest
- //NotFound indicates http error 404
+ // NotFound indicates HTTP error 404
NotFound StatusCode = http.StatusNotFound
)
-// StatusCode sets the http response status code
+// StatusCode sets the HTTP response status code
type StatusCode int
func (s StatusCode) Error() string {
return strconv.Itoa(int(s))
}
-// Render sets the http status code
+// Render sets the HTTP status code
func (s StatusCode) Render(ctx *Context) {
ctx.Output.SetStatus(int(s))
}
diff --git a/src/vendor/github.com/beego/beego/controller.go b/src/vendor/github.com/beego/beego/v2/server/web/controller.go
similarity index 83%
rename from src/vendor/github.com/beego/beego/controller.go
rename to src/vendor/github.com/beego/beego/v2/server/web/controller.go
index 27e6f133b..6bf061dda 100644
--- a/src/vendor/github.com/beego/beego/controller.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/controller.go
@@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"bytes"
+ context2 "context"
"errors"
"fmt"
"html/template"
@@ -27,10 +28,13 @@ import (
"reflect"
"strconv"
"strings"
+ "sync"
- "github.com/beego/beego/context"
- "github.com/beego/beego/context/param"
- "github.com/beego/beego/session"
+ "google.golang.org/protobuf/proto"
+
+ "github.com/beego/beego/v2/server/web/context"
+ "github.com/beego/beego/v2/server/web/context/param"
+ "github.com/beego/beego/v2/server/web/session"
)
var (
@@ -38,8 +42,21 @@ var (
ErrAbort = errors.New("user stop run")
// GlobalControllerRouter store comments with controller. pkgpath+controller:comments
GlobalControllerRouter = make(map[string][]ControllerComments)
+ copyBufferPool sync.Pool
)
+const (
+ bytePerKb = 1024
+ copyBufferKb = 32
+ filePerm = 0o666
+)
+
+func init() {
+ copyBufferPool.New = func() interface{} {
+ return make([]byte, bytePerKb*copyBufferKb)
+ }
+}
+
// ControllerFilter store the filter for controller
type ControllerFilter struct {
Pattern string
@@ -106,9 +123,9 @@ type Controller struct {
EnableRender bool
// xsrf data
+ EnableXSRF bool
_xsrfToken string
XSRFExpire int
- EnableXSRF bool
// session
CruSession session.Store
@@ -224,6 +241,37 @@ func (c *Controller) HandlerFunc(fnname string) bool {
// URLMapping register the internal Controller router.
func (c *Controller) URLMapping() {}
+// Bind if the content type is form, we read data from form
+// otherwise, read data from request body
+func (c *Controller) Bind(obj interface{}) error {
+ return c.Ctx.Bind(obj)
+}
+
+// BindYAML only read data from http request body
+func (c *Controller) BindYAML(obj interface{}) error {
+ return c.Ctx.BindYAML(obj)
+}
+
+// BindForm read data from form
+func (c *Controller) BindForm(obj interface{}) error {
+ return c.Ctx.BindForm(obj)
+}
+
+// BindJSON only read data from http request body
+func (c *Controller) BindJSON(obj interface{}) error {
+ return c.Ctx.BindJSON(obj)
+}
+
+// BindProtobuf only read data from http request body
+func (c *Controller) BindProtobuf(obj proto.Message) error {
+ return c.Ctx.BindProtobuf(obj)
+}
+
+// BindXML only read data from http request body
+func (c *Controller) BindXML(obj interface{}) error {
+ return c.Ctx.BindXML(obj)
+}
+
// Mapping the method to function
func (c *Controller) Mapping(method string, fn func()) {
c.methodMapping[method] = fn
@@ -249,6 +297,9 @@ func (c *Controller) Render() error {
// RenderString returns the rendered template string. Do not send out response.
func (c *Controller) RenderString() (string, error) {
b, e := c.RenderBytes()
+ if e != nil {
+ return "", e
+ }
return string(b), e
}
@@ -275,7 +326,7 @@ func (c *Controller) RenderBytes() ([]byte, error) {
}
buf.Reset()
- ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath(), c.Data)
+ err = ExecuteViewPathTemplate(&buf, c.Layout, c.viewPath(), c.Data)
}
return buf.Bytes(), err
}
@@ -343,9 +394,9 @@ func (c *Controller) Abort(code string) {
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
func (c *Controller) CustomAbort(status int, body string) {
+ c.Ctx.Output.Status = status
// first panic from ErrorMaps, it is user defined error functions.
if _, ok := ErrorMaps[body]; ok {
- c.Ctx.Output.Status = status
panic(body)
}
// last panic user string
@@ -371,51 +422,74 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
return URLFor(endpoint, values...)
}
+func (c *Controller) JSONResp(data interface{}) error {
+ return c.Ctx.JSONResp(data)
+}
+
+func (c *Controller) XMLResp(data interface{}) error {
+ return c.Ctx.XMLResp(data)
+}
+
+func (c *Controller) YamlResp(data interface{}) error {
+ return c.Ctx.YamlResp(data)
+}
+
+// Resp sends response based on the Accept Header
+// By default response will be in JSON
+// it's different from ServeXXX methods
+// because we don't store the data to Data field
+func (c *Controller) Resp(data interface{}) error {
+ return c.Ctx.Resp(data)
+}
+
// ServeJSON sends a json response with encoding charset.
-func (c *Controller) ServeJSON(encoding ...bool) {
+func (c *Controller) ServeJSON(encoding ...bool) error {
var (
hasIndent = BConfig.RunMode != PROD
hasEncoding = len(encoding) > 0 && encoding[0]
)
- c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
+ return c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
}
// ServeJSONP sends a jsonp response.
-func (c *Controller) ServeJSONP() {
+func (c *Controller) ServeJSONP() error {
hasIndent := BConfig.RunMode != PROD
- c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
+ return c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
}
// ServeXML sends xml response.
-func (c *Controller) ServeXML() {
+func (c *Controller) ServeXML() error {
hasIndent := BConfig.RunMode != PROD
- c.Ctx.Output.XML(c.Data["xml"], hasIndent)
+ return c.Ctx.Output.XML(c.Data["xml"], hasIndent)
}
// ServeYAML sends yaml response.
-func (c *Controller) ServeYAML() {
- c.Ctx.Output.YAML(c.Data["yaml"])
+func (c *Controller) ServeYAML() error {
+ return c.Ctx.Output.YAML(c.Data["yaml"])
}
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
-func (c *Controller) ServeFormatted(encoding ...bool) {
+func (c *Controller) ServeFormatted(encoding ...bool) error {
hasIndent := BConfig.RunMode != PROD
hasEncoding := len(encoding) > 0 && encoding[0]
- c.Ctx.Output.ServeFormatted(c.Data, hasIndent, hasEncoding)
+ return c.Ctx.Output.ServeFormatted(c.Data, hasIndent, hasEncoding)
}
// Input returns the input data map from POST or PUT request body and query string.
-func (c *Controller) Input() url.Values {
+func (c *Controller) Input() (url.Values, error) {
if c.Ctx.Request.Form == nil {
- c.Ctx.Request.ParseForm()
+ err := c.Ctx.Request.ParseForm()
+ if err != nil {
+ return nil, err
+ }
}
- return c.Ctx.Request.Form
+ return c.Ctx.Request.Form, nil
}
// ParseForm maps input data map to obj struct.
func (c *Controller) ParseForm(obj interface{}) error {
- return ParseForm(c.Input(), obj)
+ return c.Ctx.BindForm(obj)
}
// GetString returns the input value by key string or the default value while it's present and input is blank
@@ -437,7 +511,7 @@ func (c *Controller) GetStrings(key string, def ...[]string) []string {
defv = def[0]
}
- if f := c.Input(); f == nil {
+ if f, err := c.Input(); f == nil || err != nil {
return defv
} else if vs := f[key]; len(vs) > 0 {
return vs
@@ -593,19 +667,31 @@ func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
// SaveToFile saves uploaded file to new path.
// it only operates the first one of mutil-upload form file field.
-func (c *Controller) SaveToFile(fromfile, tofile string) error {
- file, _, err := c.Ctx.Request.FormFile(fromfile)
+func (c *Controller) SaveToFile(fromFile, toFile string) error {
+ buf := copyBufferPool.Get().([]byte)
+ defer copyBufferPool.Put(buf)
+ return c.SaveToFileWithBuffer(fromFile, toFile, buf)
+}
+
+type onlyWriter struct {
+ io.Writer
+}
+
+func (c *Controller) SaveToFileWithBuffer(fromFile string, toFile string, buf []byte) error {
+ src, _, err := c.Ctx.Request.FormFile(fromFile)
if err != nil {
return err
}
- defer file.Close()
- f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+ defer src.Close()
+
+ dst, err := os.OpenFile(toFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, filePerm)
if err != nil {
return err
}
- defer f.Close()
- io.Copy(f, file)
- return nil
+ defer dst.Close()
+
+ _, err = io.CopyBuffer(onlyWriter{dst}, src, buf)
+ return err
}
// StartSession starts session and load old session data info this controller.
@@ -617,11 +703,11 @@ func (c *Controller) StartSession() session.Store {
}
// SetSession puts value into session.
-func (c *Controller) SetSession(name interface{}, value interface{}) {
+func (c *Controller) SetSession(name interface{}, value interface{}) error {
if c.CruSession == nil {
c.StartSession()
}
- c.CruSession.Set(name, value)
+ return c.CruSession.Set(context2.Background(), name, value)
}
// GetSession gets value from session.
@@ -629,33 +715,38 @@ func (c *Controller) GetSession(name interface{}) interface{} {
if c.CruSession == nil {
c.StartSession()
}
- return c.CruSession.Get(name)
+ return c.CruSession.Get(context2.Background(), name)
}
// DelSession removes value from session.
-func (c *Controller) DelSession(name interface{}) {
+func (c *Controller) DelSession(name interface{}) error {
if c.CruSession == nil {
c.StartSession()
}
- c.CruSession.Delete(name)
+ return c.CruSession.Delete(context2.Background(), name)
}
// SessionRegenerateID regenerates session id for this session.
// the session data have no changes.
-func (c *Controller) SessionRegenerateID() (err error) {
+func (c *Controller) SessionRegenerateID() error {
if c.CruSession != nil {
- c.CruSession.SessionRelease(c.Ctx.ResponseWriter)
+ c.CruSession.SessionRelease(context2.Background(), c.Ctx.ResponseWriter)
}
+ var err error
c.CruSession, err = GlobalSessions.SessionRegenerateID(c.Ctx.ResponseWriter, c.Ctx.Request)
c.Ctx.Input.CruSession = c.CruSession
- return
+ return err
}
// DestroySession cleans session data and session cookie.
-func (c *Controller) DestroySession() {
- c.Ctx.Input.CruSession.Flush()
+func (c *Controller) DestroySession() error {
+ err := c.Ctx.Input.CruSession.Flush(nil)
+ if err != nil {
+ return err
+ }
c.Ctx.Input.CruSession = nil
GlobalSessions.SessionDestroy(c.Ctx.ResponseWriter, c.Ctx.Request)
+ return nil
}
// IsAjax returns this request is ajax or not.
diff --git a/src/vendor/github.com/beego/beego/doc.go b/src/vendor/github.com/beego/beego/v2/server/web/doc.go
similarity index 82%
rename from src/vendor/github.com/beego/beego/doc.go
rename to src/vendor/github.com/beego/beego/v2/server/web/doc.go
index cbbd2711c..0bde987e7 100644
--- a/src/vendor/github.com/beego/beego/doc.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/doc.go
@@ -6,12 +6,12 @@ It is used for rapid development of RESTful APIs, web apps and backend services
beego is inspired by Tornado, Sinatra and Flask with the added benefit of some Go-specific features such as interfaces and struct embedding.
package main
- import "github.com/beego/beego"
+ import "github.com/beego/beego/v2"
func main() {
beego.Run()
}
-more information: http://beego.me
+more information: http://beego.vip
*/
-package beego
+package web
diff --git a/src/vendor/github.com/beego/beego/error.go b/src/vendor/github.com/beego/beego/v2/server/web/error.go
similarity index 95%
rename from src/vendor/github.com/beego/beego/error.go
rename to src/vendor/github.com/beego/beego/v2/server/web/error.go
index 23e044d2e..118585dc4 100644
--- a/src/vendor/github.com/beego/beego/error.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/error.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"fmt"
@@ -23,8 +23,9 @@ import (
"strconv"
"strings"
- "github.com/beego/beego/context"
- "github.com/beego/beego/utils"
+ "github.com/beego/beego/v2"
+ "github.com/beego/beego/v2/core/utils"
+ "github.com/beego/beego/v2/server/web/context"
)
const (
@@ -90,7 +91,7 @@ func showErr(err interface{}, ctx *context.Context, stack string) {
"RequestURL": ctx.Input.URI(),
"RemoteAddr": ctx.Input.IP(),
"Stack": stack,
- "BeegoVersion": VERSION,
+ "BeegoVersion": beego.VERSION,
"GoVersion": runtime.Version(),
}
t.Execute(ctx.ResponseWriter, data)
@@ -377,7 +378,7 @@ func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errCont
t, _ := template.New("beegoerrortemp").Parse(errtpl)
data := M{
"Title": http.StatusText(errCode),
- "BeegoVersion": VERSION,
+ "BeegoVersion": beego.VERSION,
"Content": template.HTML(errContent),
}
t.Execute(rw, data)
@@ -387,7 +388,7 @@ func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errCont
// usage:
// beego.ErrorHandler("404",NotFound)
// beego.ErrorHandler("500",InternalServerError)
-func ErrorHandler(code string, h http.HandlerFunc) *App {
+func ErrorHandler(code string, h http.HandlerFunc) *HttpServer {
ErrorMaps[code] = &errorInfo{
errorType: errorTypeHandler,
handler: h,
@@ -399,7 +400,7 @@ func ErrorHandler(code string, h http.HandlerFunc) *App {
// ErrorController registers ControllerInterface to each http err code string.
// usage:
// beego.ErrorController(&controllers.ErrorController{})
-func ErrorController(c ControllerInterface) *App {
+func ErrorController(c ControllerInterface) *HttpServer {
reflectVal := reflect.ValueOf(c)
rt := reflectVal.Type()
ct := reflect.Indirect(reflectVal).Type()
@@ -442,13 +443,13 @@ func exception(errCode string, ctx *context.Context) {
return
}
}
- //if 50x error has been removed from errorMap
+ // if 50x error has been removed from errorMap
ctx.ResponseWriter.WriteHeader(atoi(errCode))
ctx.WriteString(errCode)
}
func executeError(err *errorInfo, ctx *context.Context, code int) {
- //make sure to log the error in the access log
+ // make sure to log the error in the access log
LogAccess(ctx, nil, code)
if err.errorType == errorTypeHandler {
@@ -458,16 +459,16 @@ func executeError(err *errorInfo, ctx *context.Context, code int) {
}
if err.errorType == errorTypeController {
ctx.Output.SetStatus(code)
- //Invoke the request handler
+ // Invoke the request handler
vc := reflect.New(err.controllerType)
execController, ok := vc.Interface().(ControllerInterface)
if !ok {
panic("controller is not ControllerInterface")
}
- //call the controller init function
+ // call the controller init function
execController.Init(ctx, err.controllerType.Name(), err.method, vc.Interface())
- //call prepare function
+ // call prepare function
execController.Prepare()
execController.URLMapping()
@@ -475,7 +476,7 @@ func executeError(err *errorInfo, ctx *context.Context, code int) {
method := vc.MethodByName(err.method)
method.Call([]reflect.Value{})
- //render template
+ // render template
if BConfig.WebConfig.AutoRender {
if err := execController.Render(); err != nil {
panic(err)
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/filter.go b/src/vendor/github.com/beego/beego/v2/server/web/filter.go
new file mode 100644
index 000000000..2237703d5
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/filter.go
@@ -0,0 +1,136 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package web
+
+import (
+ "strings"
+
+ "github.com/beego/beego/v2/server/web/context"
+)
+
+// FilterChain is different from pure FilterFunc
+// when you use this, you must invoke next(ctx) inside the FilterFunc which is returned
+// And all those FilterChain will be invoked before other FilterFunc
+type FilterChain func(next FilterFunc) FilterFunc
+
+// FilterFunc defines a filter function which is invoked before the controller handler is executed.
+// It's a alias of HandleFunc
+// In fact, the HandleFunc is the last Filter. This is the truth
+type FilterFunc = HandleFunc
+
+// FilterRouter defines a filter operation which is invoked before the controller handler is executed.
+// It can match the URL against a pattern, and execute a filter function
+// when a request with a matching URL arrives.
+type FilterRouter struct {
+ filterFunc FilterFunc
+ next *FilterRouter
+ tree *Tree
+ pattern string
+ returnOnOutput bool
+ resetParams bool
+}
+
+// params is for:
+// 1. setting the returnOnOutput value (false allows multiple filters to execute)
+// 2. determining whether or not params need to be reset.
+func newFilterRouter(pattern string, filter FilterFunc, opts ...FilterOpt) *FilterRouter {
+ mr := &FilterRouter{
+ tree: NewTree(),
+ pattern: pattern,
+ filterFunc: filter,
+ }
+
+ fos := &filterOpts{
+ returnOnOutput: true,
+ }
+
+ for _, o := range opts {
+ o(fos)
+ }
+
+ if !fos.routerCaseSensitive {
+ mr.pattern = strings.ToLower(pattern)
+ }
+
+ mr.returnOnOutput = fos.returnOnOutput
+ mr.resetParams = fos.resetParams
+ mr.tree.AddRouter(pattern, true)
+ return mr
+}
+
+// filter will check whether we need to execute the filter logic
+// return (started, done)
+func (f *FilterRouter) filter(ctx *context.Context, urlPath string, preFilterParams map[string]string) (bool, bool) {
+ if f.returnOnOutput && ctx.ResponseWriter.Started {
+ return true, true
+ }
+ if f.resetParams {
+ preFilterParams = ctx.Input.Params()
+ }
+ if ok := f.ValidRouter(urlPath, ctx); ok {
+ f.filterFunc(ctx)
+ if f.resetParams {
+ ctx.Input.ResetParams()
+ for k, v := range preFilterParams {
+ ctx.Input.SetParam(k, v)
+ }
+ }
+ } else if f.next != nil {
+ return f.next.filter(ctx, urlPath, preFilterParams)
+ }
+ if f.returnOnOutput && ctx.ResponseWriter.Started {
+ return true, true
+ }
+ return false, false
+}
+
+// ValidRouter checks if the current request is matched by this filter.
+// If the request is matched, the values of the URL parameters defined
+// by the filter pattern are also returned.
+func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
+ isOk := f.tree.Match(url, ctx)
+ if isOk != nil {
+ if b, ok := isOk.(bool); ok {
+ return b
+ }
+ }
+ return false
+}
+
+type filterOpts struct {
+ returnOnOutput bool
+ resetParams bool
+ routerCaseSensitive bool
+}
+
+type FilterOpt func(opts *filterOpts)
+
+func WithReturnOnOutput(ret bool) FilterOpt {
+ return func(opts *filterOpts) {
+ opts.returnOnOutput = ret
+ }
+}
+
+func WithResetParams(reset bool) FilterOpt {
+ return func(opts *filterOpts) {
+ opts.resetParams = reset
+ }
+}
+
+func WithCaseSensitive(sensitive bool) FilterOpt {
+ return func(opts *filterOpts) {
+ opts.routerCaseSensitive = sensitive
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/flash.go b/src/vendor/github.com/beego/beego/v2/server/web/flash.go
similarity index 98%
rename from src/vendor/github.com/beego/beego/flash.go
rename to src/vendor/github.com/beego/beego/v2/server/web/flash.go
index a6485a17e..4b6567ac0 100644
--- a/src/vendor/github.com/beego/beego/flash.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/flash.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"fmt"
@@ -102,7 +102,7 @@ func ReadFromRequest(c *Controller) *FlashData {
}
}
}
- //read one time then delete it
+ // read one time then delete it
c.Ctx.SetCookie(BConfig.WebConfig.FlashName, "", -1, "/")
}
c.Data["flash"] = flash.Data
diff --git a/src/vendor/github.com/beego/beego/fs.go b/src/vendor/github.com/beego/beego/v2/server/web/fs.go
similarity index 97%
rename from src/vendor/github.com/beego/beego/fs.go
rename to src/vendor/github.com/beego/beego/v2/server/web/fs.go
index 41cc6f6e0..4d65630a3 100644
--- a/src/vendor/github.com/beego/beego/fs.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/fs.go
@@ -1,4 +1,4 @@
-package beego
+package web
import (
"net/http"
@@ -6,8 +6,7 @@ import (
"path/filepath"
)
-type FileSystem struct {
-}
+type FileSystem struct{}
func (d FileSystem) Open(name string) (http.File, error) {
return os.Open(name)
@@ -17,7 +16,6 @@ func (d FileSystem) Open(name string) (http.File, error) {
// directory in the tree, including root. All errors that arise visiting files
// and directories are filtered by walkFn.
func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error {
-
f, err := fs.Open(root)
if err != nil {
return err
diff --git a/src/vendor/github.com/beego/beego/grace/grace.go b/src/vendor/github.com/beego/beego/v2/server/web/grace/grace.go
similarity index 89%
rename from src/vendor/github.com/beego/beego/grace/grace.go
rename to src/vendor/github.com/beego/beego/v2/server/web/grace/grace.go
index 3e396ea88..bad7e61db 100644
--- a/src/vendor/github.com/beego/beego/grace/grace.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/grace/grace.go
@@ -22,7 +22,7 @@
// "net/http"
// "os"
//
-// "github.com/beego/beego/grace"
+// "github.com/beego/beego/v2/server/web/grace"
// )
//
// func handler(w http.ResponseWriter, r *http.Request) {
@@ -105,8 +105,17 @@ func init() {
}
}
+// ServerOption configures how we set up the connection.
+type ServerOption func(*Server)
+
+func WithShutdownCallback(shutdownCallback func()) ServerOption {
+ return func(srv *Server) {
+ srv.shutdownCallbacks = append(srv.shutdownCallbacks, shutdownCallback)
+ }
+}
+
// NewServer returns a new graceServer.
-func NewServer(addr string, handler http.Handler) (srv *Server) {
+func NewServer(addr string, handler http.Handler, opts ...ServerOption) (srv *Server) {
regLock.Lock()
defer regLock.Unlock()
@@ -138,7 +147,7 @@ func NewServer(addr string, handler http.Handler) (srv *Server) {
},
state: StateInit,
Network: "tcp",
- terminalChan: make(chan error), //no cache channel
+ terminalChan: make(chan error), // no cache channel
}
srv.Server = &http.Server{
Addr: addr,
@@ -148,6 +157,10 @@ func NewServer(addr string, handler http.Handler) (srv *Server) {
Handler: handler,
}
+ for _, opt := range opts {
+ opt(srv)
+ }
+
runningServersOrder = append(runningServersOrder, addr)
runningServers[addr] = srv
return srv
diff --git a/src/vendor/github.com/beego/beego/grace/server.go b/src/vendor/github.com/beego/beego/v2/server/web/grace/server.go
similarity index 79%
rename from src/vendor/github.com/beego/beego/grace/server.go
rename to src/vendor/github.com/beego/beego/v2/server/web/grace/server.go
index 008a61716..982849f36 100644
--- a/src/vendor/github.com/beego/beego/grace/server.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/grace/server.go
@@ -20,31 +20,42 @@ import (
// Server embedded http.Server
type Server struct {
*http.Server
- ln net.Listener
- SignalHooks map[int]map[os.Signal][]func()
- sigChan chan os.Signal
- isChild bool
- state uint8
- Network string
- terminalChan chan error
+ ln net.Listener
+ SignalHooks map[int]map[os.Signal][]func()
+ sigChan chan os.Signal
+ isChild bool
+ state uint8
+ Network string
+ terminalChan chan error
+ shutdownCallbacks []func()
}
-// Serve accepts incoming connections on the Listener l,
-// creating a new service goroutine for each.
+// Serve accepts incoming connections on the Listener l
+// and creates a new service goroutine for each.
// The service goroutines read requests and then call srv.Handler to reply to them.
func (srv *Server) Serve() (err error) {
+ return srv.internalServe(srv.ln)
+}
+
+func (srv *Server) ServeWithListener(ln net.Listener) (err error) {
+ srv.ln = ln
+ go srv.handleSignals()
+ return srv.internalServe(ln)
+}
+
+func (srv *Server) internalServe(ln net.Listener) (err error) {
srv.state = StateRunning
defer func() { srv.state = StateTerminate }()
// When Shutdown is called, Serve, ListenAndServe, and ListenAndServeTLS
// immediately return ErrServerClosed. Make sure the program doesn't exit
// and waits instead for Shutdown to return.
- if err = srv.Server.Serve(srv.ln); err != nil && err != http.ErrServerClosed {
+ if err = srv.Server.Serve(ln); err != nil && err != http.ErrServerClosed {
log.Println(syscall.Getpid(), "Server.Serve() error:", err)
return err
}
- log.Println(syscall.Getpid(), srv.ln.Addr(), "Listener closed.")
+ log.Println(syscall.Getpid(), ln.Addr(), "Listener closed.")
// wait for Shutdown to return
if shutdownErr := <-srv.terminalChan; shutdownErr != nil {
return shutdownErr
@@ -95,6 +106,15 @@ func (srv *Server) ListenAndServe() (err error) {
//
// If srv.Addr is blank, ":https" is used.
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) {
+ ln, err := srv.ListenTLS(certFile, keyFile)
+ if err != nil {
+ return err
+ }
+
+ return srv.ServeTLS(ln)
+}
+
+func (srv *Server) ListenTLS(certFile string, keyFile string) (net.Listener, error) {
addr := srv.Addr
if addr == "" {
addr = ":https"
@@ -108,20 +128,35 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) {
}
srv.TLSConfig.Certificates = make([]tls.Certificate, 1)
- srv.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
+ cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
- return
+ return nil, err
}
+ srv.TLSConfig.Certificates[0] = cert
go srv.handleSignals()
ln, err := srv.getListener(addr)
if err != nil {
log.Println(err)
+ return nil, err
+ }
+ tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig)
+ return tlsListener, nil
+}
+
+// ListenAndServeMutualTLS listens on the TCP network address srv.Addr and then calls
+// Serve to handle requests on incoming mutual TLS connections.
+func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string) (err error) {
+ ln, err := srv.ListenMutualTLS(certFile, keyFile, trustFile)
+ if err != nil {
return err
}
- srv.ln = tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig)
+ return srv.ServeTLS(ln)
+}
+
+func (srv *Server) ServeTLS(ln net.Listener) error {
if srv.isChild {
process, err := os.FindProcess(os.Getppid())
if err != nil {
@@ -134,13 +169,11 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) (err error) {
}
}
- log.Println(os.Getpid(), srv.Addr)
- return srv.Serve()
+ go srv.handleSignals()
+ return srv.internalServe(ln)
}
-// ListenAndServeMutualTLS listens on the TCP network address srv.Addr and then calls
-// Serve to handle requests on incoming mutual TLS connections.
-func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string) (err error) {
+func (srv *Server) ListenMutualTLS(certFile string, keyFile string, trustFile string) (net.Listener, error) {
addr := srv.Addr
if addr == "" {
addr = ":https"
@@ -154,16 +187,17 @@ func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string)
}
srv.TLSConfig.Certificates = make([]tls.Certificate, 1)
- srv.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
+ cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
- return
+ return nil, err
}
+ srv.TLSConfig.Certificates[0] = cert
srv.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
pool := x509.NewCertPool()
data, err := ioutil.ReadFile(trustFile)
if err != nil {
log.Println(err)
- return err
+ return nil, err
}
pool.AppendCertsFromPEM(data)
srv.TLSConfig.ClientCAs = pool
@@ -173,24 +207,10 @@ func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string)
ln, err := srv.getListener(addr)
if err != nil {
log.Println(err)
- return err
+ return nil, err
}
- srv.ln = tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig)
-
- if srv.isChild {
- process, err := os.FindProcess(os.Getppid())
- if err != nil {
- log.Println(err)
- return err
- }
- err = process.Signal(syscall.SIGTERM)
- if err != nil {
- return err
- }
- }
-
- log.Println(os.Getpid(), srv.Addr)
- return srv.Serve()
+ tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig)
+ return tlsListener, nil
}
// getListener either opens a new socket to listen on, or takes the acceptor socket
@@ -292,6 +312,9 @@ func (srv *Server) shutdown() {
ctx, cancel = context.WithTimeout(context.Background(), DefaultTimeout)
defer cancel()
}
+ for _, shutdownCallback := range srv.shutdownCallbacks {
+ shutdownCallback()
+ }
srv.terminalChan <- srv.Server.Shutdown(ctx)
}
@@ -303,8 +326,8 @@ func (srv *Server) fork() (err error) {
}
runningServersForked = true
- var files = make([]*os.File, len(runningServers))
- var orderArgs = make([]string, len(runningServers))
+ files := make([]*os.File, len(runningServers))
+ orderArgs := make([]string, len(runningServers))
for _, srvPtr := range runningServers {
f, _ := srvPtr.ln.(*net.TCPListener).File()
files[socketPtrOffsetMap[srvPtr.Server.Addr]] = f
diff --git a/src/vendor/github.com/beego/beego/hooks.go b/src/vendor/github.com/beego/beego/v2/server/web/hooks.go
similarity index 88%
rename from src/vendor/github.com/beego/beego/hooks.go
rename to src/vendor/github.com/beego/beego/v2/server/web/hooks.go
index dd1cefa6e..68cc61a18 100644
--- a/src/vendor/github.com/beego/beego/hooks.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/hooks.go
@@ -1,4 +1,4 @@
-package beego
+package web
import (
"encoding/json"
@@ -6,9 +6,9 @@ import (
"net/http"
"path/filepath"
- "github.com/beego/beego/context"
- "github.com/beego/beego/logs"
- "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/server/web/context"
+ "github.com/beego/beego/v2/server/web/session"
)
// register MIME type with content type
@@ -47,9 +47,9 @@ func registerDefaultErrorHandler() error {
func registerSession() error {
if BConfig.WebConfig.Session.SessionOn {
var err error
- sessionConfig := AppConfig.String("sessionConfig")
+ sessionConfig, err := AppConfig.String("sessionConfig")
conf := new(session.ManagerConfig)
- if sessionConfig == "" {
+ if sessionConfig == "" || err != nil {
conf.CookieName = BConfig.WebConfig.Session.SessionName
conf.EnableSetCookie = BConfig.WebConfig.Session.SessionAutoSetCookie
conf.Gclifetime = BConfig.WebConfig.Session.SessionGCMaxLifetime
@@ -62,6 +62,7 @@ func registerSession() error {
conf.SessionNameInHTTPHeader = BConfig.WebConfig.Session.SessionNameInHTTPHeader
conf.EnableSidInURLQuery = BConfig.WebConfig.Session.SessionEnableSidInURLQuery
conf.CookieSameSite = BConfig.WebConfig.Session.SessionCookieSameSite
+ conf.SessionIDPrefix = BConfig.WebConfig.Session.SessionIDPrefix
} else {
if err = json.Unmarshal([]byte(sessionConfig), conf); err != nil {
return err
@@ -86,13 +87,6 @@ func registerTemplate() error {
return nil
}
-func registerAdmin() error {
- if BConfig.Listen.EnableAdmin {
- go beeAdminApp.Run()
- }
- return nil
-}
-
func registerGzip() error {
if BConfig.EnableGzip {
context.InitGzip(
diff --git a/src/vendor/github.com/beego/beego/mime.go b/src/vendor/github.com/beego/beego/v2/server/web/mime.go
similarity index 99%
rename from src/vendor/github.com/beego/beego/mime.go
rename to src/vendor/github.com/beego/beego/v2/server/web/mime.go
index ca2878ab2..9393e9c7b 100644
--- a/src/vendor/github.com/beego/beego/mime.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/mime.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
var mimemaps = map[string]string{
".3dm": "x-world/x-3dmf",
diff --git a/src/vendor/github.com/beego/beego/namespace.go b/src/vendor/github.com/beego/beego/v2/server/web/namespace.go
similarity index 63%
rename from src/vendor/github.com/beego/beego/namespace.go
rename to src/vendor/github.com/beego/beego/v2/server/web/namespace.go
index 8f21dbb99..8da8a797b 100644
--- a/src/vendor/github.com/beego/beego/namespace.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/namespace.go
@@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"net/http"
"strings"
- beecontext "github.com/beego/beego/context"
+ beecontext "github.com/beego/beego/v2/server/web/context"
)
type namespaceCond func(*beecontext.Context) bool
@@ -48,7 +48,7 @@ func NewNamespace(prefix string, params ...LinkNamespace) *Namespace {
// if cond return true can run this namespace, else can't
// usage:
// ns.Cond(func (ctx *context.Context) bool{
-// if ctx.Input.Domain() == "api.beego.me" {
+// if ctx.Input.Domain() == "api.beego.vip" {
// return true
// }
// return false
@@ -91,106 +91,154 @@ func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace {
a = FinishRouter
}
for _, f := range filter {
- n.handlers.InsertFilter("*", a, f)
+ n.handlers.InsertFilter("*", a, f, WithReturnOnOutput(true))
}
return n
}
// Router same as beego.Rourer
-// refer: https://godoc.org/github.com/beego/beego#Router
+// refer: https://godoc.org/github.com/beego/beego/v2#Router
func (n *Namespace) Router(rootpath string, c ControllerInterface, mappingMethods ...string) *Namespace {
- n.handlers.Add(rootpath, c, mappingMethods...)
+ n.handlers.Add(rootpath, c, WithRouterMethods(c, mappingMethods...))
return n
}
// AutoRouter same as beego.AutoRouter
-// refer: https://godoc.org/github.com/beego/beego#AutoRouter
+// refer: https://godoc.org/github.com/beego/beego/v2#AutoRouter
func (n *Namespace) AutoRouter(c ControllerInterface) *Namespace {
n.handlers.AddAuto(c)
return n
}
// AutoPrefix same as beego.AutoPrefix
-// refer: https://godoc.org/github.com/beego/beego#AutoPrefix
+// refer: https://godoc.org/github.com/beego/beego/v2#AutoPrefix
func (n *Namespace) AutoPrefix(prefix string, c ControllerInterface) *Namespace {
n.handlers.AddAutoPrefix(prefix, c)
return n
}
// Get same as beego.Get
-// refer: https://godoc.org/github.com/beego/beego#Get
-func (n *Namespace) Get(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Get
+func (n *Namespace) Get(rootpath string, f HandleFunc) *Namespace {
n.handlers.Get(rootpath, f)
return n
}
// Post same as beego.Post
-// refer: https://godoc.org/github.com/beego/beego#Post
-func (n *Namespace) Post(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Post
+func (n *Namespace) Post(rootpath string, f HandleFunc) *Namespace {
n.handlers.Post(rootpath, f)
return n
}
// Delete same as beego.Delete
-// refer: https://godoc.org/github.com/beego/beego#Delete
-func (n *Namespace) Delete(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Delete
+func (n *Namespace) Delete(rootpath string, f HandleFunc) *Namespace {
n.handlers.Delete(rootpath, f)
return n
}
// Put same as beego.Put
-// refer: https://godoc.org/github.com/beego/beego#Put
-func (n *Namespace) Put(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Put
+func (n *Namespace) Put(rootpath string, f HandleFunc) *Namespace {
n.handlers.Put(rootpath, f)
return n
}
// Head same as beego.Head
-// refer: https://godoc.org/github.com/beego/beego#Head
-func (n *Namespace) Head(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Head
+func (n *Namespace) Head(rootpath string, f HandleFunc) *Namespace {
n.handlers.Head(rootpath, f)
return n
}
// Options same as beego.Options
-// refer: https://godoc.org/github.com/beego/beego#Options
-func (n *Namespace) Options(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Options
+func (n *Namespace) Options(rootpath string, f HandleFunc) *Namespace {
n.handlers.Options(rootpath, f)
return n
}
// Patch same as beego.Patch
-// refer: https://godoc.org/github.com/beego/beego#Patch
-func (n *Namespace) Patch(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Patch
+func (n *Namespace) Patch(rootpath string, f HandleFunc) *Namespace {
n.handlers.Patch(rootpath, f)
return n
}
// Any same as beego.Any
-// refer: https://godoc.org/github.com/beego/beego#Any
-func (n *Namespace) Any(rootpath string, f FilterFunc) *Namespace {
+// refer: https://godoc.org/github.com/beego/beego/v2#Any
+func (n *Namespace) Any(rootpath string, f HandleFunc) *Namespace {
n.handlers.Any(rootpath, f)
return n
}
// Handler same as beego.Handler
-// refer: https://godoc.org/github.com/beego/beego#Handler
+// refer: https://godoc.org/github.com/beego/beego/v2#Handler
func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace {
n.handlers.Handler(rootpath, h)
return n
}
// Include add include class
-// refer: https://godoc.org/github.com/beego/beego#Include
+// refer: https://godoc.org/github.com/beego/beego/v2#Include
func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
n.handlers.Include(cList...)
return n
}
+// CtrlGet same as beego.CtrlGet
+func (n *Namespace) CtrlGet(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlGet(rootpath, f)
+ return n
+}
+
+// CtrlPost same as beego.CtrlPost
+func (n *Namespace) CtrlPost(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlPost(rootpath, f)
+ return n
+}
+
+// CtrlDelete same as beego.CtrlDelete
+func (n *Namespace) CtrlDelete(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlDelete(rootpath, f)
+ return n
+}
+
+// CtrlPut same as beego.CtrlPut
+func (n *Namespace) CtrlPut(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlPut(rootpath, f)
+ return n
+}
+
+// CtrlHead same as beego.CtrlHead
+func (n *Namespace) CtrlHead(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlHead(rootpath, f)
+ return n
+}
+
+// CtrlOptions same as beego.CtrlOptions
+func (n *Namespace) CtrlOptions(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlOptions(rootpath, f)
+ return n
+}
+
+// CtrlPatch same as beego.CtrlPatch
+func (n *Namespace) CtrlPatch(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlPatch(rootpath, f)
+ return n
+}
+
+// Any same as beego.CtrlAny
+func (n *Namespace) CtrlAny(rootpath string, f interface{}) *Namespace {
+ n.handlers.CtrlAny(rootpath, f)
+ return n
+}
+
// Namespace add nest Namespace
// usage:
-//ns := beego.NewNamespace(“/v1”).
-//Namespace(
+// ns := beego.NewNamespace(“/v1”).
+// Namespace(
// beego.NewNamespace("/shop").
// Get("/:id", func(ctx *context.Context) {
// ctx.Output.Body([]byte("shopinfo"))
@@ -203,7 +251,7 @@ func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
// Get("/:id", func(ctx *context.Context) {
// ctx.Output.Body([]byte("crminfo"))
// }),
-//)
+// )
func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
for _, ni := range ns {
for k, v := range ni.handlers.routers {
@@ -311,61 +359,117 @@ func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string)
}
// NSGet call Namespace Get
-func NSGet(rootpath string, f FilterFunc) LinkNamespace {
+func NSGet(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Get(rootpath, f)
}
}
// NSPost call Namespace Post
-func NSPost(rootpath string, f FilterFunc) LinkNamespace {
+func NSPost(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Post(rootpath, f)
}
}
// NSHead call Namespace Head
-func NSHead(rootpath string, f FilterFunc) LinkNamespace {
+func NSHead(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Head(rootpath, f)
}
}
// NSPut call Namespace Put
-func NSPut(rootpath string, f FilterFunc) LinkNamespace {
+func NSPut(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Put(rootpath, f)
}
}
// NSDelete call Namespace Delete
-func NSDelete(rootpath string, f FilterFunc) LinkNamespace {
+func NSDelete(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Delete(rootpath, f)
}
}
// NSAny call Namespace Any
-func NSAny(rootpath string, f FilterFunc) LinkNamespace {
+func NSAny(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Any(rootpath, f)
}
}
// NSOptions call Namespace Options
-func NSOptions(rootpath string, f FilterFunc) LinkNamespace {
+func NSOptions(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Options(rootpath, f)
}
}
// NSPatch call Namespace Patch
-func NSPatch(rootpath string, f FilterFunc) LinkNamespace {
+func NSPatch(rootpath string, f HandleFunc) LinkNamespace {
return func(ns *Namespace) {
ns.Patch(rootpath, f)
}
}
+// NSCtrlGet call Namespace CtrlGet
+func NSCtrlGet(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlGet(rootpath, f)
+ }
+}
+
+// NSCtrlPost call Namespace CtrlPost
+func NSCtrlPost(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlPost(rootpath, f)
+ }
+}
+
+// NSCtrlHead call Namespace CtrlHead
+func NSCtrlHead(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlHead(rootpath, f)
+ }
+}
+
+// NSCtrlPut call Namespace CtrlPut
+func NSCtrlPut(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlPut(rootpath, f)
+ }
+}
+
+// NSCtrlDelete call Namespace CtrlDelete
+func NSCtrlDelete(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlDelete(rootpath, f)
+ }
+}
+
+// NSCtrlAny call Namespace CtrlAny
+func NSCtrlAny(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlAny(rootpath, f)
+ }
+}
+
+// NSCtrlOptions call Namespace CtrlOptions
+func NSCtrlOptions(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlOptions(rootpath, f)
+ }
+}
+
+// NSCtrlPatch call Namespace CtrlPatch
+func NSCtrlPatch(rootpath string, f interface{}) LinkNamespace {
+ return func(ns *Namespace) {
+ ns.CtrlPatch(rootpath, f)
+ }
+}
+
// NSAutoRouter call Namespace AutoRouter
func NSAutoRouter(c ControllerInterface) LinkNamespace {
return func(ns *Namespace) {
diff --git a/src/vendor/github.com/beego/beego/policy.go b/src/vendor/github.com/beego/beego/v2/server/web/policy.go
similarity index 96%
rename from src/vendor/github.com/beego/beego/policy.go
rename to src/vendor/github.com/beego/beego/v2/server/web/policy.go
index 58222885a..41fb2669d 100644
--- a/src/vendor/github.com/beego/beego/policy.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/policy.go
@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"strings"
- "github.com/beego/beego/context"
+ "github.com/beego/beego/v2/server/web/context"
)
// PolicyFunc defines a policy function which is invoked before the controller handler is executed.
@@ -25,7 +25,7 @@ type PolicyFunc func(*context.Context)
// FindPolicy Find Router info for URL
func (p *ControllerRegister) FindPolicy(cont *context.Context) []PolicyFunc {
- var urlPath = cont.Input.URL()
+ urlPath := cont.Input.URL()
if !BConfig.RouterCaseSensitive {
urlPath = strings.ToLower(urlPath)
}
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/router.go b/src/vendor/github.com/beego/beego/v2/server/web/router.go
new file mode 100644
index 000000000..1536bae4a
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/router.go
@@ -0,0 +1,1391 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package web
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "path"
+ "reflect"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/core/utils"
+ beecontext "github.com/beego/beego/v2/server/web/context"
+ "github.com/beego/beego/v2/server/web/context/param"
+)
+
+// default filter execution points
+const (
+ BeforeStatic = iota
+ BeforeRouter
+ BeforeExec
+ AfterExec
+ FinishRouter
+)
+
+const (
+ routerTypeBeego = iota
+ routerTypeRESTFul
+ routerTypeHandler
+)
+
+var (
+ // HTTPMETHOD list the supported http methods.
+ HTTPMETHOD = map[string]bool{
+ "GET": true,
+ "POST": true,
+ "PUT": true,
+ "DELETE": true,
+ "PATCH": true,
+ "OPTIONS": true,
+ "HEAD": true,
+ "TRACE": true,
+ "CONNECT": true,
+ "MKCOL": true,
+ "COPY": true,
+ "MOVE": true,
+ "PROPFIND": true,
+ "PROPPATCH": true,
+ "LOCK": true,
+ "UNLOCK": true,
+ }
+ // these web.Controller's methods shouldn't reflect to AutoRouter
+ // see registerControllerExceptMethods
+ exceptMethod = initExceptMethod()
+
+ urlPlaceholder = "{{placeholder}}"
+ // DefaultAccessLogFilter will skip the accesslog if return true
+ DefaultAccessLogFilter FilterHandler = &logFilter{}
+)
+
+// FilterHandler is an interface for
+type FilterHandler interface {
+ Filter(*beecontext.Context) bool
+}
+
+// default log filter static file will not show
+type logFilter struct{}
+
+func (l *logFilter) Filter(ctx *beecontext.Context) bool {
+ requestPath := path.Clean(ctx.Request.URL.Path)
+ if requestPath == "/favicon.ico" || requestPath == "/robots.txt" {
+ return true
+ }
+ for prefix := range BConfig.WebConfig.StaticDir {
+ if strings.HasPrefix(requestPath, prefix) {
+ return true
+ }
+ }
+ return false
+}
+
+// ExceptMethodAppend to append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter
+func ExceptMethodAppend(action string) {
+ exceptMethod = append(exceptMethod, action)
+}
+
+func initExceptMethod() []string {
+ res := make([]string, 0, 32)
+ c := &Controller{}
+ t := reflect.TypeOf(c)
+ for i := 0; i < t.NumMethod(); i++ {
+ m := t.Method(i)
+ res = append(res, m.Name)
+ }
+ return res
+}
+
+// ControllerInfo holds information about the controller.
+type ControllerInfo struct {
+ pattern string
+ controllerType reflect.Type
+ methods map[string]string
+ handler http.Handler
+ runFunction HandleFunc
+ routerType int
+ initialize func() ControllerInterface
+ methodParams []*param.MethodParam
+ sessionOn bool
+}
+
+type ControllerOption func(*ControllerInfo)
+
+func (c *ControllerInfo) GetPattern() string {
+ return c.pattern
+}
+
+func (c *ControllerInfo) GetMethod() map[string]string {
+ return c.methods
+}
+
+func WithRouterMethods(ctrlInterface ControllerInterface, mappingMethod ...string) ControllerOption {
+ return func(c *ControllerInfo) {
+ c.methods = parseMappingMethods(ctrlInterface, mappingMethod)
+ }
+}
+
+func WithRouterSessionOn(sessionOn bool) ControllerOption {
+ return func(c *ControllerInfo) {
+ c.sessionOn = sessionOn
+ }
+}
+
+type filterChainConfig struct {
+ pattern string
+ chain FilterChain
+ opts []FilterOpt
+}
+
+// ControllerRegister containers registered router rules, controller handlers and filters.
+type ControllerRegister struct {
+ routers map[string]*Tree
+ enablePolicy bool
+ enableFilter bool
+ policies map[string]*Tree
+ filters [FinishRouter + 1][]*FilterRouter
+ pool sync.Pool
+
+ // the filter created by FilterChain
+ chainRoot *FilterRouter
+
+ // keep registered chain and build it when serve http
+ filterChains []filterChainConfig
+
+ cfg *Config
+}
+
+// NewControllerRegister returns a new ControllerRegister.
+// Usually you should not use this method
+// please use NewControllerRegisterWithCfg
+func NewControllerRegister() *ControllerRegister {
+ return NewControllerRegisterWithCfg(BeeApp.Cfg)
+}
+
+func NewControllerRegisterWithCfg(cfg *Config) *ControllerRegister {
+ res := &ControllerRegister{
+ routers: make(map[string]*Tree),
+ policies: make(map[string]*Tree),
+ pool: sync.Pool{
+ New: func() interface{} {
+ return beecontext.NewContext()
+ },
+ },
+ cfg: cfg,
+ filterChains: make([]filterChainConfig, 0, 4),
+ }
+ res.chainRoot = newFilterRouter("/*", res.serveHttp, WithCaseSensitive(false))
+ return res
+}
+
+// Init will be executed when HttpServer start running
+func (p *ControllerRegister) Init() {
+ for i := len(p.filterChains) - 1; i >= 0; i-- {
+ fc := p.filterChains[i]
+ root := p.chainRoot
+ filterFunc := fc.chain(func(ctx *beecontext.Context) {
+ var preFilterParams map[string]string
+ root.filter(ctx, p.getUrlPath(ctx), preFilterParams)
+ })
+ p.chainRoot = newFilterRouter(fc.pattern, filterFunc, fc.opts...)
+ p.chainRoot.next = root
+ }
+}
+
+// Add controller handler and pattern rules to ControllerRegister.
+// usage:
+//
+// default methods is the same name as method
+// Add("/user",&UserController{})
+// Add("/api/list",&RestController{},"*:ListFood")
+// Add("/api/create",&RestController{},"post:CreateFood")
+// Add("/api/update",&RestController{},"put:UpdateFood")
+// Add("/api/delete",&RestController{},"delete:DeleteFood")
+// Add("/api",&RestController{},"get,post:ApiFunc"
+// Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
+func (p *ControllerRegister) Add(pattern string, c ControllerInterface, opts ...ControllerOption) {
+ p.addWithMethodParams(pattern, c, nil, opts...)
+}
+
+func parseMappingMethods(c ControllerInterface, mappingMethods []string) map[string]string {
+ reflectVal := reflect.ValueOf(c)
+ t := reflect.Indirect(reflectVal).Type()
+ methods := make(map[string]string)
+
+ if len(mappingMethods) == 0 {
+ return methods
+ }
+
+ semi := strings.Split(mappingMethods[0], ";")
+ for _, v := range semi {
+ colon := strings.Split(v, ":")
+ if len(colon) != 2 {
+ panic("method mapping format is invalid")
+ }
+ comma := strings.Split(colon[0], ",")
+ for _, m := range comma {
+ if m != "*" && !HTTPMETHOD[strings.ToUpper(m)] {
+ panic(v + " is an invalid method mapping. Method doesn't exist " + m)
+ }
+ if val := reflectVal.MethodByName(colon[1]); val.IsValid() {
+ methods[strings.ToUpper(m)] = colon[1]
+ continue
+ }
+ panic("'" + colon[1] + "' method doesn't exist in the controller " + t.Name())
+ }
+ }
+
+ return methods
+}
+
+func (p *ControllerRegister) addRouterForMethod(route *ControllerInfo) {
+ if len(route.methods) == 0 {
+ for m := range HTTPMETHOD {
+ p.addToRouter(m, route.pattern, route)
+ }
+ return
+ }
+ for k := range route.methods {
+ if k != "*" {
+ p.addToRouter(k, route.pattern, route)
+ continue
+ }
+ for m := range HTTPMETHOD {
+ p.addToRouter(m, route.pattern, route)
+ }
+ }
+}
+
+func (p *ControllerRegister) addWithMethodParams(pattern string, c ControllerInterface, methodParams []*param.MethodParam, opts ...ControllerOption) {
+ reflectVal := reflect.ValueOf(c)
+ t := reflect.Indirect(reflectVal).Type()
+
+ route := p.createBeegoRouter(t, pattern)
+ route.initialize = func() ControllerInterface {
+ vc := reflect.New(route.controllerType)
+ execController, ok := vc.Interface().(ControllerInterface)
+ if !ok {
+ panic("controller is not ControllerInterface")
+ }
+
+ elemVal := reflect.ValueOf(c).Elem()
+ elemType := reflect.TypeOf(c).Elem()
+ execElem := reflect.ValueOf(execController).Elem()
+
+ numOfFields := elemVal.NumField()
+ for i := 0; i < numOfFields; i++ {
+ fieldType := elemType.Field(i)
+ elemField := execElem.FieldByName(fieldType.Name)
+ if elemField.CanSet() {
+ fieldVal := elemVal.Field(i)
+ elemField.Set(fieldVal)
+ }
+ }
+
+ return execController
+ }
+ route.methodParams = methodParams
+ for i := range opts {
+ opts[i](route)
+ }
+
+ globalSessionOn := p.cfg.WebConfig.Session.SessionOn
+ if !globalSessionOn && route.sessionOn {
+ logs.Warn("global sessionOn is false, sessionOn of router [%s] can't be set to true", route.pattern)
+ route.sessionOn = globalSessionOn
+ }
+
+ p.addRouterForMethod(route)
+}
+
+func (p *ControllerRegister) addToRouter(method, pattern string, r *ControllerInfo) {
+ if !p.cfg.RouterCaseSensitive {
+ pattern = strings.ToLower(pattern)
+ }
+ if t, ok := p.routers[method]; ok {
+ t.AddRouter(pattern, r)
+ } else {
+ t := NewTree()
+ t.AddRouter(pattern, r)
+ p.routers[method] = t
+ }
+}
+
+// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller
+// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
+func (p *ControllerRegister) Include(cList ...ControllerInterface) {
+ for _, c := range cList {
+ reflectVal := reflect.ValueOf(c)
+ t := reflect.Indirect(reflectVal).Type()
+ key := t.PkgPath() + ":" + t.Name()
+ if comm, ok := GlobalControllerRouter[key]; ok {
+ for _, a := range comm {
+ for _, f := range a.Filters {
+ p.InsertFilter(f.Pattern, f.Pos, f.Filter, WithReturnOnOutput(f.ReturnOnOutput), WithResetParams(f.ResetParams))
+ }
+ p.addWithMethodParams(a.Router, c, a.MethodParams, WithRouterMethods(c, strings.Join(a.AllowHTTPMethods, ",")+":"+a.Method))
+ }
+ }
+ }
+}
+
+// GetContext returns a context from pool, so usually you should remember to call Reset function to clean the context
+// And don't forget to give back context to pool
+// example:
+//
+// ctx := p.GetContext()
+// ctx.Reset(w, q)
+// defer p.GiveBackContext(ctx)
+func (p *ControllerRegister) GetContext() *beecontext.Context {
+ return p.pool.Get().(*beecontext.Context)
+}
+
+// GiveBackContext put the ctx into pool so that it could be reuse
+func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
+ p.pool.Put(ctx)
+}
+
+// CtrlGet add get method
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlGet("/api/:id", MyController.Ping)
+//
+// If the receiver of function Ping is pointer, you should use CtrlGet("/api/:id", (*MyController).Ping)
+func (p *ControllerRegister) CtrlGet(pattern string, f interface{}) {
+ p.AddRouterMethod(http.MethodGet, pattern, f)
+}
+
+// CtrlPost add post method
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlPost("/api/:id", MyController.Ping)
+//
+// If the receiver of function Ping is pointer, you should use CtrlPost("/api/:id", (*MyController).Ping)
+func (p *ControllerRegister) CtrlPost(pattern string, f interface{}) {
+ p.AddRouterMethod(http.MethodPost, pattern, f)
+}
+
+// CtrlHead add head method
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlHead("/api/:id", MyController.Ping)
+//
+// If the receiver of function Ping is pointer, you should use CtrlHead("/api/:id", (*MyController).Ping)
+func (p *ControllerRegister) CtrlHead(pattern string, f interface{}) {
+ p.AddRouterMethod(http.MethodHead, pattern, f)
+}
+
+// CtrlPut add put method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlPut("/api/:id", MyController.Ping)
+
+func (p *ControllerRegister) CtrlPut(pattern string, f interface{}) {
+ p.AddRouterMethod(http.MethodPut, pattern, f)
+}
+
+// CtrlPatch add patch method
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlPatch("/api/:id", MyController.Ping)
+func (p *ControllerRegister) CtrlPatch(pattern string, f interface{}) {
+ p.AddRouterMethod(http.MethodPatch, pattern, f)
+}
+
+// CtrlDelete add delete method
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlDelete("/api/:id", MyController.Ping)
+func (p *ControllerRegister) CtrlDelete(pattern string, f interface{}) {
+ p.AddRouterMethod(http.MethodDelete, pattern, f)
+}
+
+// CtrlOptions add options method
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlOptions("/api/:id", MyController.Ping)
+func (p *ControllerRegister) CtrlOptions(pattern string, f interface{}) {
+ p.AddRouterMethod(http.MethodOptions, pattern, f)
+}
+
+// CtrlAny add all method
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlAny("/api/:id", MyController.Ping)
+func (p *ControllerRegister) CtrlAny(pattern string, f interface{}) {
+ p.AddRouterMethod("*", pattern, f)
+}
+
+// AddRouterMethod add http method router
+// usage:
+//
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// AddRouterMethod("get","/api/:id", MyController.Ping)
+func (p *ControllerRegister) AddRouterMethod(httpMethod, pattern string, f interface{}) {
+ httpMethod = p.getUpperMethodString(httpMethod)
+ ct, methodName := getReflectTypeAndMethod(f)
+
+ p.addBeegoTypeRouter(ct, methodName, httpMethod, pattern)
+}
+
+// addBeegoTypeRouter add beego type router
+func (p *ControllerRegister) addBeegoTypeRouter(ct reflect.Type, ctMethod, httpMethod, pattern string) {
+ route := p.createBeegoRouter(ct, pattern)
+ methods := p.getHttpMethodMapMethod(httpMethod, ctMethod)
+ route.methods = methods
+
+ p.addRouterForMethod(route)
+}
+
+// createBeegoRouter create beego router base on reflect type and pattern
+func (p *ControllerRegister) createBeegoRouter(ct reflect.Type, pattern string) *ControllerInfo {
+ route := &ControllerInfo{}
+ route.pattern = pattern
+ route.routerType = routerTypeBeego
+ route.sessionOn = p.cfg.WebConfig.Session.SessionOn
+ route.controllerType = ct
+ return route
+}
+
+// createRestfulRouter create restful router with filter function and pattern
+func (p *ControllerRegister) createRestfulRouter(f HandleFunc, pattern string) *ControllerInfo {
+ route := &ControllerInfo{}
+ route.pattern = pattern
+ route.routerType = routerTypeRESTFul
+ route.sessionOn = p.cfg.WebConfig.Session.SessionOn
+ route.runFunction = f
+ return route
+}
+
+// createHandlerRouter create handler router with handler and pattern
+func (p *ControllerRegister) createHandlerRouter(h http.Handler, pattern string) *ControllerInfo {
+ route := &ControllerInfo{}
+ route.pattern = pattern
+ route.routerType = routerTypeHandler
+ route.sessionOn = p.cfg.WebConfig.Session.SessionOn
+ route.handler = h
+ return route
+}
+
+// getHttpMethodMapMethod based on http method and controller method, if ctMethod is empty, then it will
+// use http method as the controller method
+func (p *ControllerRegister) getHttpMethodMapMethod(httpMethod, ctMethod string) map[string]string {
+ methods := make(map[string]string)
+ // not match-all sign, only add for the http method
+ if httpMethod != "*" {
+
+ if ctMethod == "" {
+ ctMethod = httpMethod
+ }
+ methods[httpMethod] = ctMethod
+ return methods
+ }
+
+ // add all http method
+ for val := range HTTPMETHOD {
+ if ctMethod == "" {
+ methods[val] = val
+ } else {
+ methods[val] = ctMethod
+ }
+ }
+ return methods
+}
+
+// getUpperMethodString get upper string of method, and panic if the method
+// is not valid
+func (p *ControllerRegister) getUpperMethodString(method string) string {
+ method = strings.ToUpper(method)
+ if method != "*" && !HTTPMETHOD[method] {
+ panic("not support http method: " + method)
+ }
+ return method
+}
+
+// get reflect controller type and method by controller method expression
+func getReflectTypeAndMethod(f interface{}) (controllerType reflect.Type, method string) {
+ // check f is a function
+ funcType := reflect.TypeOf(f)
+ if funcType.Kind() != reflect.Func {
+ panic("not a method")
+ }
+
+ // get function name
+ funcObj := runtime.FuncForPC(reflect.ValueOf(f).Pointer())
+ if funcObj == nil {
+ panic("cannot find the method")
+ }
+ funcNameSli := strings.Split(funcObj.Name(), ".")
+ lFuncSli := len(funcNameSli)
+ if lFuncSli == 0 {
+ panic("invalid method full name: " + funcObj.Name())
+ }
+
+ method = funcNameSli[lFuncSli-1]
+ if len(method) == 0 {
+ panic("method name is empty")
+ } else if method[0] > 96 || method[0] < 65 {
+ panic(fmt.Sprintf("%s is not a public method", method))
+ }
+
+ // check only one param which is the method receiver
+ if numIn := funcType.NumIn(); numIn != 1 {
+ panic("invalid number of param in")
+ }
+
+ controllerType = funcType.In(0)
+
+ // check controller has the method
+ _, exists := controllerType.MethodByName(method)
+ if !exists {
+ panic(controllerType.String() + " has no method " + method)
+ }
+
+ // check the receiver implement ControllerInterface
+ if controllerType.Kind() == reflect.Ptr {
+ controllerType = controllerType.Elem()
+ }
+ controller := reflect.New(controllerType)
+ _, ok := controller.Interface().(ControllerInterface)
+ if !ok {
+ panic(controllerType.String() + " is not implemented ControllerInterface")
+ }
+
+ return
+}
+
+// HandleFunc define how to process the request
+type HandleFunc func(ctx *beecontext.Context)
+
+// Get add get method
+// usage:
+//
+// Get("/", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Get(pattern string, f HandleFunc) {
+ p.AddMethod("get", pattern, f)
+}
+
+// Post add post method
+// usage:
+//
+// Post("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Post(pattern string, f HandleFunc) {
+ p.AddMethod("post", pattern, f)
+}
+
+// Put add put method
+// usage:
+//
+// Put("/api/:id", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Put(pattern string, f HandleFunc) {
+ p.AddMethod("put", pattern, f)
+}
+
+// Delete add delete method
+// usage:
+//
+// Delete("/api/:id", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Delete(pattern string, f HandleFunc) {
+ p.AddMethod("delete", pattern, f)
+}
+
+// Head add head method
+// usage:
+//
+// Head("/api/:id", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Head(pattern string, f HandleFunc) {
+ p.AddMethod("head", pattern, f)
+}
+
+// Patch add patch method
+// usage:
+//
+// Patch("/api/:id", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Patch(pattern string, f HandleFunc) {
+ p.AddMethod("patch", pattern, f)
+}
+
+// Options add options method
+// usage:
+//
+// Options("/api/:id", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Options(pattern string, f HandleFunc) {
+ p.AddMethod("options", pattern, f)
+}
+
+// Any add all method
+// usage:
+//
+// Any("/api/:id", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) Any(pattern string, f HandleFunc) {
+ p.AddMethod("*", pattern, f)
+}
+
+// AddMethod add http method router
+// usage:
+//
+// AddMethod("get","/api/:id", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (p *ControllerRegister) AddMethod(method, pattern string, f HandleFunc) {
+ method = p.getUpperMethodString(method)
+
+ route := p.createRestfulRouter(f, pattern)
+ methods := p.getHttpMethodMapMethod(method, "")
+ route.methods = methods
+
+ p.addRouterForMethod(route)
+}
+
+// Handler add user defined Handler
+func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) {
+ route := p.createHandlerRouter(h, pattern)
+ if len(options) > 0 {
+ if _, ok := options[0].(bool); ok {
+ pattern = path.Join(pattern, "?:all(.*)")
+ }
+ }
+ for m := range HTTPMETHOD {
+ p.addToRouter(m, pattern, route)
+ }
+}
+
+// AddAuto router to ControllerRegister.
+// example beego.AddAuto(&MainController{}),
+// MainController has method List and Page.
+// visit the url /main/list to execute List function
+// /main/page to execute Page function.
+func (p *ControllerRegister) AddAuto(c ControllerInterface) {
+ p.AddAutoPrefix("/", c)
+}
+
+// AddAutoPrefix Add auto router to ControllerRegister with prefix.
+// example beego.AddAutoPrefix("/admin",&MainController{}),
+// MainController has method List and Page.
+// visit the url /admin/main/list to execute List function
+// /admin/main/page to execute Page function.
+func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) {
+ reflectVal := reflect.ValueOf(c)
+ rt := reflectVal.Type()
+ ct := reflect.Indirect(reflectVal).Type()
+ controllerName := strings.TrimSuffix(ct.Name(), "Controller")
+ for i := 0; i < rt.NumMethod(); i++ {
+ methodName := rt.Method(i).Name
+ if !utils.InSlice(methodName, exceptMethod) {
+ p.addAutoPrefixMethod(prefix, controllerName, methodName, ct)
+ }
+ }
+}
+
+func (p *ControllerRegister) addAutoPrefixMethod(prefix, controllerName, methodName string, ctrl reflect.Type) {
+ pattern := path.Join(prefix, strings.ToLower(controllerName), strings.ToLower(methodName), "*")
+ patternInit := path.Join(prefix, controllerName, methodName, "*")
+ patternFix := path.Join(prefix, strings.ToLower(controllerName), strings.ToLower(methodName))
+ patternFixInit := path.Join(prefix, controllerName, methodName)
+
+ route := p.createBeegoRouter(ctrl, pattern)
+ route.methods = map[string]string{"*": methodName}
+ for m := range HTTPMETHOD {
+
+ p.addToRouter(m, pattern, route)
+
+ // only case sensitive, we add three more routes
+ if p.cfg.RouterCaseSensitive {
+ p.addToRouter(m, patternInit, route)
+ p.addToRouter(m, patternFix, route)
+ p.addToRouter(m, patternFixInit, route)
+ }
+ }
+}
+
+// InsertFilter Add a FilterFunc with pattern rule and action constant.
+// params is for:
+// 1. setting the returnOnOutput value (false allows multiple filters to execute)
+// 2. determining whether or not params need to be reset.
+func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) error {
+ opts = append(opts, WithCaseSensitive(p.cfg.RouterCaseSensitive))
+ mr := newFilterRouter(pattern, filter, opts...)
+ return p.insertFilterRouter(pos, mr)
+}
+
+// InsertFilterChain is similar to InsertFilter,
+// but it will using chainRoot.filterFunc as input to build a new filterFunc
+// for example, assume that chainRoot is funcA
+// and we add new FilterChain
+//
+// fc := func(next) {
+// return func(ctx) {
+// // do something
+// next(ctx)
+// // do something
+// }
+// }
+func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, opts ...FilterOpt) {
+ opts = append([]FilterOpt{WithCaseSensitive(p.cfg.RouterCaseSensitive)}, opts...)
+ p.filterChains = append(p.filterChains, filterChainConfig{
+ pattern: pattern,
+ chain: chain,
+ opts: opts,
+ })
+}
+
+// add Filter into
+func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) {
+ if pos < BeforeStatic || pos > FinishRouter {
+ return errors.New("can not find your filter position")
+ }
+ p.enableFilter = true
+ p.filters[pos] = append(p.filters[pos], mr)
+ return nil
+}
+
+// URLFor does another controller handler in this request function.
+// it can access any controller method.
+func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) string {
+ paths := strings.Split(endpoint, ".")
+ if len(paths) <= 1 {
+ logs.Warn("urlfor endpoint must like path.controller.method")
+ return ""
+ }
+ if len(values)%2 != 0 {
+ logs.Warn("urlfor params must key-value pair")
+ return ""
+ }
+ params := make(map[string]string)
+ if len(values) > 0 {
+ key := ""
+ for k, v := range values {
+ if k%2 == 0 {
+ key = fmt.Sprint(v)
+ } else {
+ params[key] = fmt.Sprint(v)
+ }
+ }
+ }
+ controllerName := strings.Join(paths[:len(paths)-1], "/")
+ methodName := paths[len(paths)-1]
+ for m, t := range p.routers {
+ ok, url := p.getURL(t, "/", controllerName, methodName, params, m)
+ if ok {
+ return url
+ }
+ }
+ return ""
+}
+
+func (p *ControllerRegister) getURL(t *Tree, url, controllerName, methodName string, params map[string]string, httpMethod string) (bool, string) {
+ for _, subtree := range t.fixrouters {
+ u := path.Join(url, subtree.prefix)
+ ok, u := p.getURL(subtree, u, controllerName, methodName, params, httpMethod)
+ if ok {
+ return ok, u
+ }
+ }
+ if t.wildcard != nil {
+ u := path.Join(url, urlPlaceholder)
+ ok, u := p.getURL(t.wildcard, u, controllerName, methodName, params, httpMethod)
+ if ok {
+ return ok, u
+ }
+ }
+ for _, l := range t.leaves {
+ if c, ok := l.runObject.(*ControllerInfo); ok {
+ if c.routerType == routerTypeBeego &&
+ strings.HasSuffix(path.Join(c.controllerType.PkgPath(), c.controllerType.Name()), `/`+controllerName) {
+ find := false
+ if HTTPMETHOD[strings.ToUpper(methodName)] {
+ if len(c.methods) == 0 {
+ find = true
+ } else if m, ok := c.methods[strings.ToUpper(methodName)]; ok && m == strings.ToUpper(methodName) {
+ find = true
+ } else if m, ok = c.methods["*"]; ok && m == methodName {
+ find = true
+ }
+ }
+ if !find {
+ for m, md := range c.methods {
+ if (m == "*" || m == httpMethod) && md == methodName {
+ find = true
+ }
+ }
+ }
+ if find {
+ if l.regexps == nil {
+ if len(l.wildcards) == 0 {
+ return true, strings.Replace(url, "/"+urlPlaceholder, "", 1) + toURL(params)
+ }
+ if len(l.wildcards) == 1 {
+ if v, ok := params[l.wildcards[0]]; ok {
+ delete(params, l.wildcards[0])
+ return true, strings.Replace(url, urlPlaceholder, v, 1) + toURL(params)
+ }
+ return false, ""
+ }
+ if len(l.wildcards) == 3 && l.wildcards[0] == "." {
+ if p, ok := params[":path"]; ok {
+ if e, isok := params[":ext"]; isok {
+ delete(params, ":path")
+ delete(params, ":ext")
+ return true, strings.Replace(url, urlPlaceholder, p+"."+e, -1) + toURL(params)
+ }
+ }
+ }
+ canSkip := false
+ for _, v := range l.wildcards {
+ if v == ":" {
+ canSkip = true
+ continue
+ }
+ if u, ok := params[v]; ok {
+ delete(params, v)
+ url = strings.Replace(url, urlPlaceholder, u, 1)
+ } else {
+ if canSkip {
+ canSkip = false
+ continue
+ }
+ return false, ""
+ }
+ }
+ return true, url + toURL(params)
+ }
+ var i int
+ var startReg bool
+ regURL := ""
+ for _, v := range strings.Trim(l.regexps.String(), "^$") {
+ if v == '(' {
+ startReg = true
+ continue
+ } else if v == ')' {
+ startReg = false
+ if v, ok := params[l.wildcards[i]]; ok {
+ delete(params, l.wildcards[i])
+ regURL = regURL + v
+ i++
+ } else {
+ break
+ }
+ } else if !startReg {
+ regURL = string(append([]rune(regURL), v))
+ }
+ }
+ if l.regexps.MatchString(regURL) {
+ ps := strings.Split(regURL, "/")
+ for _, p := range ps {
+ url = strings.Replace(url, urlPlaceholder, p, 1)
+ }
+ return true, url + toURL(params)
+ }
+ }
+ }
+ }
+ }
+
+ return false, ""
+}
+
+func (p *ControllerRegister) execFilter(context *beecontext.Context, urlPath string, pos int) (started bool) {
+ var preFilterParams map[string]string
+ for _, filterR := range p.filters[pos] {
+ b, done := filterR.filter(context, urlPath, preFilterParams)
+ if done {
+ return b
+ }
+ }
+ return false
+}
+
+// Implement http.Handler interface.
+func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
+ ctx := p.GetContext()
+
+ ctx.Reset(rw, r)
+ defer p.GiveBackContext(ctx)
+
+ var preFilterParams map[string]string
+ p.chainRoot.filter(ctx, p.getUrlPath(ctx), preFilterParams)
+}
+
+func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
+ var err error
+ startTime := time.Now()
+ r := ctx.Request
+ rw := ctx.ResponseWriter.ResponseWriter
+ var (
+ runRouter reflect.Type
+ findRouter bool
+ runMethod string
+ methodParams []*param.MethodParam
+ routerInfo *ControllerInfo
+ isRunnable bool
+ currentSessionOn bool
+ originRouterInfo *ControllerInfo
+ originFindRouter bool
+ )
+
+ if p.cfg.RecoverFunc != nil {
+ defer p.cfg.RecoverFunc(ctx, p.cfg)
+ }
+
+ ctx.Output.EnableGzip = p.cfg.EnableGzip
+
+ if p.cfg.RunMode == DEV {
+ ctx.Output.Header("Server", p.cfg.ServerName)
+ }
+
+ urlPath := p.getUrlPath(ctx)
+
+ // filter wrong http method
+ if !HTTPMETHOD[r.Method] {
+ exception("405", ctx)
+ goto Admin
+ }
+
+ // filter for static file
+ if len(p.filters[BeforeStatic]) > 0 && p.execFilter(ctx, urlPath, BeforeStatic) {
+ goto Admin
+ }
+
+ serverStaticRouter(ctx)
+
+ if ctx.ResponseWriter.Started {
+ findRouter = true
+ goto Admin
+ }
+
+ if r.Method != http.MethodGet && r.Method != http.MethodHead {
+ body := ctx.Input.Context.Request.Body
+ if body == nil {
+ body = io.NopCloser(bytes.NewReader([]byte{}))
+ }
+
+ if ctx.Input.IsUpload() {
+ ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
+ body,
+ p.cfg.MaxUploadSize)
+ } else if p.cfg.CopyRequestBody {
+ // connection will close if the incoming data are larger (RFC 7231, 6.5.11)
+ if r.ContentLength > p.cfg.MaxMemory {
+ logs.Error(errors.New("payload too large"))
+ exception("413", ctx)
+ goto Admin
+ }
+ ctx.Input.CopyBody(p.cfg.MaxMemory)
+ } else {
+ ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
+ body,
+ p.cfg.MaxMemory)
+ }
+
+ err = ctx.Input.ParseFormOrMultiForm(p.cfg.MaxMemory)
+ if err != nil {
+ logs.Error(err)
+ if strings.Contains(err.Error(), `http: request body too large`) {
+ exception("413", ctx)
+ } else {
+ exception("500", ctx)
+ }
+ goto Admin
+ }
+ }
+
+ // session init
+ currentSessionOn = p.cfg.WebConfig.Session.SessionOn
+ originRouterInfo, originFindRouter = p.FindRouter(ctx)
+ if originFindRouter {
+ currentSessionOn = originRouterInfo.sessionOn
+ }
+ if currentSessionOn {
+ ctx.Input.CruSession, err = GlobalSessions.SessionStart(rw, r)
+ if err != nil {
+ logs.Error(err)
+ exception("503", ctx)
+ goto Admin
+ }
+ defer func() {
+ if ctx.Input.CruSession != nil {
+ ctx.Input.CruSession.SessionRelease(nil, rw)
+ }
+ }()
+ }
+ if len(p.filters[BeforeRouter]) > 0 && p.execFilter(ctx, urlPath, BeforeRouter) {
+ goto Admin
+ }
+ // User can define RunController and RunMethod in filter
+ if ctx.Input.RunController != nil && ctx.Input.RunMethod != "" {
+ findRouter = true
+ runMethod = ctx.Input.RunMethod
+ runRouter = ctx.Input.RunController
+ } else {
+ routerInfo, findRouter = p.FindRouter(ctx)
+ }
+
+ // if no matches to url, throw a not found exception
+ if !findRouter {
+ exception("404", ctx)
+ goto Admin
+ }
+ if splat := ctx.Input.Param(":splat"); splat != "" {
+ for k, v := range strings.Split(splat, "/") {
+ ctx.Input.SetParam(strconv.Itoa(k), v)
+ }
+ }
+
+ if routerInfo != nil {
+ // store router pattern into context
+ ctx.Input.SetData("RouterPattern", routerInfo.pattern)
+ }
+
+ // execute middleware filters
+ if len(p.filters[BeforeExec]) > 0 && p.execFilter(ctx, urlPath, BeforeExec) {
+ goto Admin
+ }
+
+ // check policies
+ if p.execPolicy(ctx, urlPath) {
+ goto Admin
+ }
+
+ if routerInfo != nil {
+ if routerInfo.routerType == routerTypeRESTFul {
+ if _, ok := routerInfo.methods[r.Method]; ok {
+ isRunnable = true
+ routerInfo.runFunction(ctx)
+ } else {
+ exception("405", ctx)
+ goto Admin
+ }
+ } else if routerInfo.routerType == routerTypeHandler {
+ isRunnable = true
+ routerInfo.handler.ServeHTTP(ctx.ResponseWriter, ctx.Request)
+ } else {
+ runRouter = routerInfo.controllerType
+ methodParams = routerInfo.methodParams
+ method := r.Method
+ if r.Method == http.MethodPost && ctx.Input.Query("_method") == http.MethodPut {
+ method = http.MethodPut
+ }
+ if r.Method == http.MethodPost && ctx.Input.Query("_method") == http.MethodDelete {
+ method = http.MethodDelete
+ }
+ if m, ok := routerInfo.methods[method]; ok {
+ runMethod = m
+ } else if m, ok = routerInfo.methods["*"]; ok {
+ runMethod = m
+ } else {
+ runMethod = method
+ }
+ }
+ }
+
+ // also defined runRouter & runMethod from filter
+ if !isRunnable {
+ // Invoke the request handler
+ var execController ControllerInterface
+ if routerInfo != nil && routerInfo.initialize != nil {
+ execController = routerInfo.initialize()
+ } else {
+ vc := reflect.New(runRouter)
+ var ok bool
+ execController, ok = vc.Interface().(ControllerInterface)
+ if !ok {
+ panic("controller is not ControllerInterface")
+ }
+ }
+
+ // call the controller init function
+ execController.Init(ctx, runRouter.Name(), runMethod, execController)
+
+ // call prepare function
+ execController.Prepare()
+
+ // if XSRF is Enable then check cookie where there has any cookie in the request's cookie _csrf
+ if p.cfg.WebConfig.EnableXSRF {
+ execController.XSRFToken()
+ if r.Method == http.MethodPost || r.Method == http.MethodDelete || r.Method == http.MethodPut ||
+ (r.Method == http.MethodPost && (ctx.Input.Query("_method") == http.MethodDelete || ctx.Input.Query("_method") == http.MethodPut)) {
+ execController.CheckXSRFCookie()
+ }
+ }
+
+ execController.URLMapping()
+
+ if !ctx.ResponseWriter.Started {
+ // exec main logic
+ switch runMethod {
+ case http.MethodGet:
+ execController.Get()
+ case http.MethodPost:
+ execController.Post()
+ case http.MethodDelete:
+ execController.Delete()
+ case http.MethodPut:
+ execController.Put()
+ case http.MethodHead:
+ execController.Head()
+ case http.MethodPatch:
+ execController.Patch()
+ case http.MethodOptions:
+ execController.Options()
+ case http.MethodTrace:
+ execController.Trace()
+ default:
+ if !execController.HandlerFunc(runMethod) {
+ vc := reflect.ValueOf(execController)
+ method := vc.MethodByName(runMethod)
+ in := param.ConvertParams(methodParams, method.Type(), ctx)
+ out := method.Call(in)
+
+ // For backward compatibility we only handle response if we had incoming methodParams
+ if methodParams != nil {
+ p.handleParamResponse(ctx, execController, out)
+ }
+ }
+ }
+
+ // render template
+ if !ctx.ResponseWriter.Started && ctx.Output.Status == 0 {
+ if p.cfg.WebConfig.AutoRender {
+ if err := execController.Render(); err != nil {
+ logs.Error(err)
+ }
+ }
+ }
+ }
+
+ // finish all runRouter. release resource
+ execController.Finish()
+ }
+
+ // execute middleware filters
+ if len(p.filters[AfterExec]) > 0 && p.execFilter(ctx, urlPath, AfterExec) {
+ goto Admin
+ }
+
+ if len(p.filters[FinishRouter]) > 0 && p.execFilter(ctx, urlPath, FinishRouter) {
+ goto Admin
+ }
+
+Admin:
+ // admin module record QPS
+
+ statusCode := ctx.ResponseWriter.Status
+ if statusCode == 0 {
+ statusCode = 200
+ }
+
+ LogAccess(ctx, &startTime, statusCode)
+
+ timeDur := time.Since(startTime)
+ ctx.ResponseWriter.Elapsed = timeDur
+ if p.cfg.Listen.EnableAdmin {
+ pattern := ""
+ if routerInfo != nil {
+ pattern = routerInfo.pattern
+ }
+
+ if FilterMonitorFunc(r.Method, r.URL.Path, timeDur, pattern, statusCode) {
+ routerName := ""
+ if runRouter != nil {
+ routerName = runRouter.Name()
+ }
+ go StatisticsMap.AddStatistics(r.Method, r.URL.Path, routerName, timeDur)
+ }
+ }
+
+ if p.cfg.RunMode == DEV && !p.cfg.Log.AccessLogs {
+ match := map[bool]string{true: "match", false: "nomatch"}
+ devInfo := fmt.Sprintf("|%15s|%s %3d %s|%13s|%8s|%s %-7s %s %-3s",
+ ctx.Input.IP(),
+ logs.ColorByStatus(statusCode), statusCode, logs.ResetColor(),
+ timeDur.String(),
+ match[findRouter],
+ logs.ColorByMethod(r.Method), r.Method, logs.ResetColor(),
+ r.URL.Path)
+ if routerInfo != nil {
+ devInfo += fmt.Sprintf(" r:%s", routerInfo.pattern)
+ }
+
+ logs.Debug(devInfo)
+ }
+ // Call WriteHeader if status code has been set changed
+ if ctx.Output.Status != 0 {
+ ctx.ResponseWriter.WriteHeader(ctx.Output.Status)
+ }
+}
+
+func (p *ControllerRegister) getUrlPath(ctx *beecontext.Context) string {
+ urlPath := ctx.Request.URL.Path
+ if !p.cfg.RouterCaseSensitive {
+ urlPath = strings.ToLower(urlPath)
+ }
+ return urlPath
+}
+
+func (p *ControllerRegister) handleParamResponse(context *beecontext.Context, execController ControllerInterface, results []reflect.Value) {
+ // looping in reverse order for the case when both error and value are returned and error sets the response status code
+ for i := len(results) - 1; i >= 0; i-- {
+ result := results[i]
+ if result.Kind() != reflect.Interface || !result.IsNil() {
+ resultValue := result.Interface()
+ context.RenderMethodResult(resultValue)
+ }
+ }
+ if !context.ResponseWriter.Started && len(results) > 0 && context.Output.Status == 0 {
+ context.Output.SetStatus(200)
+ }
+}
+
+// FindRouter Find Router info for URL
+func (p *ControllerRegister) FindRouter(context *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) {
+ urlPath := context.Input.URL()
+ if !p.cfg.RouterCaseSensitive {
+ urlPath = strings.ToLower(urlPath)
+ }
+ httpMethod := context.Input.Method()
+ if t, ok := p.routers[httpMethod]; ok {
+ runObject := t.Match(urlPath, context)
+ if r, ok := runObject.(*ControllerInfo); ok {
+ return r, true
+ }
+ }
+ return
+}
+
+// GetAllControllerInfo get all ControllerInfo
+func (p *ControllerRegister) GetAllControllerInfo() (routerInfos []*ControllerInfo) {
+ for _, webTree := range p.routers {
+ composeControllerInfos(webTree, &routerInfos)
+ }
+ return
+}
+
+func composeControllerInfos(tree *Tree, routerInfos *[]*ControllerInfo) {
+ if tree.fixrouters != nil {
+ for _, subTree := range tree.fixrouters {
+ composeControllerInfos(subTree, routerInfos)
+ }
+ }
+ if tree.wildcard != nil {
+ composeControllerInfos(tree.wildcard, routerInfos)
+ }
+ if tree.leaves != nil {
+ for _, l := range tree.leaves {
+ if c, ok := l.runObject.(*ControllerInfo); ok {
+ *routerInfos = append(*routerInfos, c)
+ }
+ }
+ }
+}
+
+func toURL(params map[string]string) string {
+ if len(params) == 0 {
+ return ""
+ }
+ u := "?"
+ for k, v := range params {
+ u += k + "=" + v + "&"
+ }
+ return strings.TrimRight(u, "&")
+}
+
+// LogAccess logging info HTTP Access
+func LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
+ BeeApp.LogAccess(ctx, startTime, statusCode)
+}
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/server.go b/src/vendor/github.com/beego/beego/v2/server/web/server.go
new file mode 100644
index 000000000..fe4c6164b
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/server.go
@@ -0,0 +1,959 @@
+// Copyright 2014 beego Author. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package web
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "fmt"
+ "io/ioutil"
+ "net"
+ "net/http"
+ "net/http/fcgi"
+ "os"
+ "path"
+ "strconv"
+ "strings"
+ "text/template"
+ "time"
+
+ "golang.org/x/crypto/acme/autocert"
+
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/core/utils"
+ beecontext "github.com/beego/beego/v2/server/web/context"
+ "github.com/beego/beego/v2/server/web/grace"
+)
+
+// BeeApp is an application instance
+// If you are using single server, you could use this
+// But if you need multiple servers, do not use this
+var BeeApp *HttpServer
+
+func init() {
+ // create beego application
+ BeeApp = NewHttpSever()
+}
+
+// HttpServer defines beego application with a new PatternServeMux.
+type HttpServer struct {
+ Handlers *ControllerRegister
+ Server *http.Server
+ Cfg *Config
+ LifeCycleCallbacks []LifeCycleCallback
+}
+
+// NewHttpSever returns a new beego application.
+// this method will use the BConfig as the configure to create HttpServer
+// Be careful that when you update BConfig, the server's Cfg will be updated too
+func NewHttpSever() *HttpServer {
+ return NewHttpServerWithCfg(BConfig)
+}
+
+// NewHttpServerWithCfg will create an sever with specific cfg
+func NewHttpServerWithCfg(cfg *Config) *HttpServer {
+ cr := NewControllerRegisterWithCfg(cfg)
+ app := &HttpServer{
+ Handlers: cr,
+ Server: &http.Server{},
+ Cfg: cfg,
+ }
+
+ return app
+}
+
+// MiddleWare function for http.Handler
+type MiddleWare func(http.Handler) http.Handler
+
+// LifeCycleCallback configures callback.
+// Developer can implement this interface to add custom logic to server lifecycle
+type LifeCycleCallback interface {
+ AfterStart(app *HttpServer)
+ BeforeShutdown(app *HttpServer)
+}
+
+// Run beego application.
+func (app *HttpServer) Run(addr string, mws ...MiddleWare) {
+ initBeforeHTTPRun()
+
+ // init...
+ app.initAddr(addr)
+ app.Handlers.Init()
+
+ addr = app.Cfg.Listen.HTTPAddr
+
+ if app.Cfg.Listen.HTTPPort != 0 {
+ addr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPAddr, app.Cfg.Listen.HTTPPort)
+ }
+
+ var (
+ err error
+ l net.Listener
+ endRunning = make(chan bool, 1)
+ )
+
+ // run cgi server
+ if app.Cfg.Listen.EnableFcgi {
+ for _, lifeCycleCallback := range app.LifeCycleCallbacks {
+ lifeCycleCallback.AfterStart(app)
+ }
+ if app.Cfg.Listen.EnableStdIo {
+ if err = fcgi.Serve(nil, app.Handlers); err == nil { // standard I/O
+ logs.Info("Use FCGI via standard I/O")
+ } else {
+ logs.Critical("Cannot use FCGI via standard I/O", err)
+ }
+ for _, lifeCycleCallback := range app.LifeCycleCallbacks {
+ lifeCycleCallback.BeforeShutdown(app)
+ }
+ return
+ }
+ if app.Cfg.Listen.HTTPPort == 0 {
+ // remove the Socket file before start
+ if utils.FileExists(addr) {
+ os.Remove(addr)
+ }
+ l, err = net.Listen("unix", addr)
+ } else {
+ l, err = net.Listen("tcp", addr)
+ }
+ if err != nil {
+ logs.Critical("Listen for Fcgi: ", err)
+ }
+ if err = fcgi.Serve(l, app.Handlers); err != nil {
+ logs.Critical("fcgi.Serve: ", err)
+ }
+ for _, lifeCycleCallback := range app.LifeCycleCallbacks {
+ lifeCycleCallback.BeforeShutdown(app)
+ }
+ return
+ }
+
+ app.Server.Handler = app.Handlers
+ for i := len(mws) - 1; i >= 0; i-- {
+ if mws[i] == nil {
+ continue
+ }
+ app.Server.Handler = mws[i](app.Server.Handler)
+ }
+ app.Server.ReadTimeout = time.Duration(app.Cfg.Listen.ServerTimeOut) * time.Second
+ app.Server.WriteTimeout = time.Duration(app.Cfg.Listen.ServerTimeOut) * time.Second
+ app.Server.ErrorLog = logs.GetLogger("HTTP")
+
+ // run graceful mode
+ if app.Cfg.Listen.Graceful {
+ var opts []grace.ServerOption
+ for _, lifeCycleCallback := range app.LifeCycleCallbacks {
+ lifeCycleCallbackDup := lifeCycleCallback
+ opts = append(opts, grace.WithShutdownCallback(func() {
+ lifeCycleCallbackDup.BeforeShutdown(app)
+ }))
+ }
+
+ httpsAddr := app.Cfg.Listen.HTTPSAddr
+ app.Server.Addr = httpsAddr
+ if app.Cfg.Listen.EnableHTTPS || app.Cfg.Listen.EnableMutualHTTPS {
+ go func() {
+ time.Sleep(1000 * time.Microsecond)
+ if app.Cfg.Listen.HTTPSPort != 0 {
+ httpsAddr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPSAddr, app.Cfg.Listen.HTTPSPort)
+ app.Server.Addr = httpsAddr
+ }
+ server := grace.NewServer(httpsAddr, app.Server.Handler, opts...)
+ server.Server.ReadTimeout = app.Server.ReadTimeout
+ server.Server.WriteTimeout = app.Server.WriteTimeout
+ var ln net.Listener
+ if app.Cfg.Listen.EnableMutualHTTPS {
+ if ln, err = server.ListenMutualTLS(app.Cfg.Listen.HTTPSCertFile,
+ app.Cfg.Listen.HTTPSKeyFile,
+ app.Cfg.Listen.TrustCaFile); err != nil {
+ logs.Critical("ListenMutualTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
+ return
+ }
+ } else {
+ if app.Cfg.Listen.AutoTLS {
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist(app.Cfg.Listen.Domains...),
+ Cache: autocert.DirCache(app.Cfg.Listen.TLSCacheDir),
+ }
+ app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
+ app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile = "", ""
+ }
+ if ln, err = server.ListenTLS(app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile); err != nil {
+ logs.Critical("ListenTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
+ return
+ }
+ }
+ for _, callback := range app.LifeCycleCallbacks {
+ callback.AfterStart(app)
+ }
+ if err = server.ServeTLS(ln); err != nil {
+ logs.Critical("ServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
+ time.Sleep(100 * time.Microsecond)
+ }
+ endRunning <- true
+ }()
+ }
+ if app.Cfg.Listen.EnableHTTP {
+ go func() {
+ server := grace.NewServer(addr, app.Server.Handler, opts...)
+ server.Server.ReadTimeout = app.Server.ReadTimeout
+ server.Server.WriteTimeout = app.Server.WriteTimeout
+ if app.Cfg.Listen.ListenTCP4 {
+ server.Network = "tcp4"
+ }
+ ln, err := net.Listen(server.Network, server.Addr)
+ logs.Info("graceful http server Running on http://%s", server.Addr)
+ if err != nil {
+ logs.Critical("Listen for HTTP[graceful mode]: ", err)
+ endRunning <- true
+ return
+ }
+ for _, callback := range app.LifeCycleCallbacks {
+ callback.AfterStart(app)
+ }
+ if err := server.ServeWithListener(ln); err != nil {
+ logs.Critical("ServeWithListener: ", err, fmt.Sprintf("%d", os.Getpid()))
+ time.Sleep(100 * time.Microsecond)
+ }
+ endRunning <- true
+ }()
+ }
+ <-endRunning
+ return
+ }
+
+ // run normal mode
+ if app.Cfg.Listen.EnableHTTPS || app.Cfg.Listen.EnableMutualHTTPS {
+ go func() {
+ time.Sleep(1000 * time.Microsecond)
+ if app.Cfg.Listen.HTTPSPort != 0 {
+ app.Server.Addr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPSAddr, app.Cfg.Listen.HTTPSPort)
+ } else if app.Cfg.Listen.EnableHTTP {
+ logs.Info("Start https server error, conflict with http. Please reset https port")
+ return
+ }
+ logs.Info("https server Running on https://%s", app.Server.Addr)
+ if app.Cfg.Listen.AutoTLS {
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist(app.Cfg.Listen.Domains...),
+ Cache: autocert.DirCache(app.Cfg.Listen.TLSCacheDir),
+ }
+ app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
+ app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile = "", ""
+ } else if app.Cfg.Listen.EnableMutualHTTPS {
+ pool := x509.NewCertPool()
+ data, err := ioutil.ReadFile(app.Cfg.Listen.TrustCaFile)
+ if err != nil {
+ logs.Info("MutualHTTPS should provide TrustCaFile")
+ return
+ }
+ pool.AppendCertsFromPEM(data)
+ app.Server.TLSConfig = &tls.Config{
+ ClientCAs: pool,
+ ClientAuth: tls.ClientAuthType(app.Cfg.Listen.ClientAuth),
+ }
+ }
+ if err := app.Server.ListenAndServeTLS(app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile); err != nil {
+ logs.Critical("ListenAndServeTLS: ", err)
+ time.Sleep(100 * time.Microsecond)
+ endRunning <- true
+ }
+ }()
+ }
+ if app.Cfg.Listen.EnableHTTP {
+ go func() {
+ app.Server.Addr = addr
+ logs.Info("http server Running on http://%s", app.Server.Addr)
+ if app.Cfg.Listen.ListenTCP4 {
+ ln, err := net.Listen("tcp4", app.Server.Addr)
+ if err != nil {
+ logs.Critical("Listen for HTTP[normal mode]: ", err)
+ time.Sleep(100 * time.Microsecond)
+ endRunning <- true
+ return
+ }
+ if err = app.Server.Serve(ln); err != nil {
+ logs.Critical("Serve: ", err)
+ time.Sleep(100 * time.Microsecond)
+ endRunning <- true
+ return
+ }
+ } else {
+ if err := app.Server.ListenAndServe(); err != nil {
+ logs.Critical("ListenAndServe: ", err)
+ time.Sleep(100 * time.Microsecond)
+ endRunning <- true
+ }
+ }
+ }()
+ }
+ <-endRunning
+}
+
+// Router see HttpServer.Router
+func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *HttpServer {
+ return RouterWithOpts(rootpath, c, WithRouterMethods(c, mappingMethods...))
+}
+
+func RouterWithOpts(rootpath string, c ControllerInterface, opts ...ControllerOption) *HttpServer {
+ return BeeApp.RouterWithOpts(rootpath, c, opts...)
+}
+
+// Router adds a patterned controller handler to BeeApp.
+// it's an alias method of HttpServer.Router.
+// usage:
+// simple router
+// beego.Router("/admin", &admin.UserController{})
+// beego.Router("/admin/index", &admin.ArticleController{})
+//
+// regex router
+//
+// beego.Router("/api/:id([0-9]+)", &controllers.RController{})
+//
+// custom rules
+// beego.Router("/api/list",&RestController{},"*:ListFood")
+// beego.Router("/api/create",&RestController{},"post:CreateFood")
+// beego.Router("/api/update",&RestController{},"put:UpdateFood")
+// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
+func (app *HttpServer) Router(rootPath string, c ControllerInterface, mappingMethods ...string) *HttpServer {
+ return app.RouterWithOpts(rootPath, c, WithRouterMethods(c, mappingMethods...))
+}
+
+func (app *HttpServer) RouterWithOpts(rootPath string, c ControllerInterface, opts ...ControllerOption) *HttpServer {
+ app.Handlers.Add(rootPath, c, opts...)
+ return app
+}
+
+// UnregisterFixedRoute see HttpServer.UnregisterFixedRoute
+func UnregisterFixedRoute(fixedRoute string, method string) *HttpServer {
+ return BeeApp.UnregisterFixedRoute(fixedRoute, method)
+}
+
+// UnregisterFixedRoute unregisters the route with the specified fixedRoute. It is particularly useful
+// in web applications that inherit most routes from a base webapp via the underscore
+// import, and aim to overwrite only certain paths.
+// The method parameter can be empty or "*" for all HTTP methods, or a particular
+// method type (e.g. "GET" or "POST") for selective removal.
+//
+// Usage (replace "GET" with "*" for all methods):
+// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
+// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
+func (app *HttpServer) UnregisterFixedRoute(fixedRoute string, method string) *HttpServer {
+ subPaths := splitPath(fixedRoute)
+ if method == "" || method == "*" {
+ for m := range HTTPMETHOD {
+ if _, ok := app.Handlers.routers[m]; !ok {
+ continue
+ }
+ if app.Handlers.routers[m].prefix == strings.Trim(fixedRoute, "/ ") {
+ findAndRemoveSingleTree(app.Handlers.routers[m])
+ continue
+ }
+ findAndRemoveTree(subPaths, app.Handlers.routers[m], m)
+ }
+ return app
+ }
+ // Single HTTP method
+ um := strings.ToUpper(method)
+ if _, ok := app.Handlers.routers[um]; ok {
+ if app.Handlers.routers[um].prefix == strings.Trim(fixedRoute, "/ ") {
+ findAndRemoveSingleTree(app.Handlers.routers[um])
+ return app
+ }
+ findAndRemoveTree(subPaths, app.Handlers.routers[um], um)
+ }
+ return app
+}
+
+func findAndRemoveTree(paths []string, entryPointTree *Tree, method string) {
+ for i := range entryPointTree.fixrouters {
+ if entryPointTree.fixrouters[i].prefix == paths[0] {
+ if len(paths) == 1 {
+ if len(entryPointTree.fixrouters[i].fixrouters) > 0 {
+ // If the route had children subtrees, remove just the functional leaf,
+ // to allow children to function as before
+ if len(entryPointTree.fixrouters[i].leaves) > 0 {
+ entryPointTree.fixrouters[i].leaves[0] = nil
+ entryPointTree.fixrouters[i].leaves = entryPointTree.fixrouters[i].leaves[1:]
+ }
+ } else {
+ // Remove the *Tree from the fixrouters slice
+ entryPointTree.fixrouters[i] = nil
+
+ if i == len(entryPointTree.fixrouters)-1 {
+ entryPointTree.fixrouters = entryPointTree.fixrouters[:i]
+ } else {
+ entryPointTree.fixrouters = append(entryPointTree.fixrouters[:i], entryPointTree.fixrouters[i+1:len(entryPointTree.fixrouters)]...)
+ }
+ }
+ return
+ }
+ findAndRemoveTree(paths[1:], entryPointTree.fixrouters[i], method)
+ }
+ }
+}
+
+func findAndRemoveSingleTree(entryPointTree *Tree) {
+ if entryPointTree == nil {
+ return
+ }
+ if len(entryPointTree.fixrouters) > 0 {
+ // If the route had children subtrees, remove just the functional leaf,
+ // to allow children to function as before
+ if len(entryPointTree.leaves) > 0 {
+ entryPointTree.leaves[0] = nil
+ entryPointTree.leaves = entryPointTree.leaves[1:]
+ }
+ }
+}
+
+// Include see HttpServer.Include
+func Include(cList ...ControllerInterface) *HttpServer {
+ return BeeApp.Include(cList...)
+}
+
+// Include will generate router file in the router/xxx.go from the controller's comments
+// usage:
+// beego.Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
+// type BankAccount struct{
+// beego.Controller
+// }
+//
+// register the function
+// func (b *BankAccount)Mapping(){
+// b.Mapping("ShowAccount" , b.ShowAccount)
+// b.Mapping("ModifyAccount", b.ModifyAccount)
+// }
+//
+// //@router /account/:id [get]
+// func (b *BankAccount) ShowAccount(){
+// //logic
+// }
+//
+//
+// //@router /account/:id [post]
+// func (b *BankAccount) ModifyAccount(){
+// //logic
+// }
+//
+// the comments @router url methodlist
+// url support all the function Router's pattern
+// methodlist [get post head put delete options *]
+func (app *HttpServer) Include(cList ...ControllerInterface) *HttpServer {
+ app.Handlers.Include(cList...)
+ return app
+}
+
+// RESTRouter see HttpServer.RESTRouter
+func RESTRouter(rootpath string, c ControllerInterface) *HttpServer {
+ return BeeApp.RESTRouter(rootpath, c)
+}
+
+// RESTRouter adds a restful controller handler to BeeApp.
+// its' controller implements beego.ControllerInterface and
+// defines a param "pattern/:objectId" to visit each resource.
+func (app *HttpServer) RESTRouter(rootpath string, c ControllerInterface) *HttpServer {
+ app.Router(rootpath, c)
+ app.Router(path.Join(rootpath, ":objectId"), c)
+ return app
+}
+
+// AutoRouter see HttpServer.AutoRouter
+func AutoRouter(c ControllerInterface) *HttpServer {
+ return BeeApp.AutoRouter(c)
+}
+
+// AutoRouter adds defined controller handler to BeeApp.
+// it's same to HttpServer.AutoRouter.
+// if beego.AddAuto(&MainController{}) and MainController has methods List and Page,
+// visit the url /main/list to exec List function or /main/page to exec Page function.
+func (app *HttpServer) AutoRouter(c ControllerInterface) *HttpServer {
+ app.Handlers.AddAuto(c)
+ return app
+}
+
+// AutoPrefix see HttpServer.AutoPrefix
+func AutoPrefix(prefix string, c ControllerInterface) *HttpServer {
+ return BeeApp.AutoPrefix(prefix, c)
+}
+
+// AutoPrefix adds controller handler to BeeApp with prefix.
+// it's same to HttpServer.AutoRouterWithPrefix.
+// if beego.AutoPrefix("/admin",&MainController{}) and MainController has methods List and Page,
+// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function.
+func (app *HttpServer) AutoPrefix(prefix string, c ControllerInterface) *HttpServer {
+ app.Handlers.AddAutoPrefix(prefix, c)
+ return app
+}
+
+// CtrlGet see HttpServer.CtrlGet
+func CtrlGet(rootpath string, f interface{}) {
+ BeeApp.CtrlGet(rootpath, f)
+}
+
+// CtrlGet used to register router for CtrlGet method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlGet("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlGet(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlGet(rootpath, f)
+ return app
+}
+
+// CtrlPost see HttpServer.CtrlGet
+func CtrlPost(rootpath string, f interface{}) {
+ BeeApp.CtrlPost(rootpath, f)
+}
+
+// CtrlPost used to register router for CtrlPost method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlPost("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlPost(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlPost(rootpath, f)
+ return app
+}
+
+// CtrlHead see HttpServer.CtrlHead
+func CtrlHead(rootpath string, f interface{}) {
+ BeeApp.CtrlHead(rootpath, f)
+}
+
+// CtrlHead used to register router for CtrlHead method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlHead("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlHead(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlHead(rootpath, f)
+ return app
+}
+
+// CtrlPut see HttpServer.CtrlPut
+func CtrlPut(rootpath string, f interface{}) {
+ BeeApp.CtrlPut(rootpath, f)
+}
+
+// CtrlPut used to register router for CtrlPut method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlPut("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlPut(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlPut(rootpath, f)
+ return app
+}
+
+// CtrlPatch see HttpServer.CtrlPatch
+func CtrlPatch(rootpath string, f interface{}) {
+ BeeApp.CtrlPatch(rootpath, f)
+}
+
+// CtrlPatch used to register router for CtrlPatch method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlPatch("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlPatch(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlPatch(rootpath, f)
+ return app
+}
+
+// CtrlDelete see HttpServer.CtrlDelete
+func CtrlDelete(rootpath string, f interface{}) {
+ BeeApp.CtrlDelete(rootpath, f)
+}
+
+// CtrlDelete used to register router for CtrlDelete method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlDelete("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlDelete(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlDelete(rootpath, f)
+ return app
+}
+
+// CtrlOptions see HttpServer.CtrlOptions
+func CtrlOptions(rootpath string, f interface{}) {
+ BeeApp.CtrlOptions(rootpath, f)
+}
+
+// CtrlOptions used to register router for CtrlOptions method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlOptions("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlOptions(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlOptions(rootpath, f)
+ return app
+}
+
+// CtrlAny see HttpServer.CtrlAny
+func CtrlAny(rootpath string, f interface{}) {
+ BeeApp.CtrlAny(rootpath, f)
+}
+
+// CtrlAny used to register router for CtrlAny method
+// usage:
+// type MyController struct {
+// web.Controller
+// }
+// func (m MyController) Ping() {
+// m.Ctx.Output.Body([]byte("hello world"))
+// }
+//
+// CtrlAny("/api/:id", MyController.Ping)
+func (app *HttpServer) CtrlAny(rootpath string, f interface{}) *HttpServer {
+ app.Handlers.CtrlAny(rootpath, f)
+ return app
+}
+
+// Get see HttpServer.Get
+func Get(rootpath string, f HandleFunc) *HttpServer {
+ return BeeApp.Get(rootpath, f)
+}
+
+// Get used to register router for Get method
+// usage:
+// beego.Get("/", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Get(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Get(rootpath, f)
+ return app
+}
+
+// Post see HttpServer.Post
+func Post(rootpath string, f HandleFunc) *HttpServer {
+ return BeeApp.Post(rootpath, f)
+}
+
+// Post used to register router for Post method
+// usage:
+// beego.Post("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Post(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Post(rootpath, f)
+ return app
+}
+
+// Delete see HttpServer.Delete
+func Delete(rootpath string, f HandleFunc) *HttpServer {
+ return BeeApp.Delete(rootpath, f)
+}
+
+// Delete used to register router for Delete method
+// usage:
+// beego.Delete("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Delete(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Delete(rootpath, f)
+ return app
+}
+
+// Put see HttpServer.Put
+func Put(rootpath string, f HandleFunc) *HttpServer {
+ return BeeApp.Put(rootpath, f)
+}
+
+// Put used to register router for Put method
+// usage:
+// beego.Put("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Put(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Put(rootpath, f)
+ return app
+}
+
+// Head see HttpServer.Head
+func Head(rootpath string, f HandleFunc) *HttpServer {
+ return BeeApp.Head(rootpath, f)
+}
+
+// Head used to register router for Head method
+// usage:
+// beego.Head("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Head(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Head(rootpath, f)
+ return app
+}
+
+// Options see HttpServer.Options
+func Options(rootpath string, f HandleFunc) *HttpServer {
+ BeeApp.Handlers.Options(rootpath, f)
+ return BeeApp
+}
+
+// Options used to register router for Options method
+// usage:
+// beego.Options("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Options(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Options(rootpath, f)
+ return app
+}
+
+// Patch see HttpServer.Patch
+func Patch(rootpath string, f HandleFunc) *HttpServer {
+ return BeeApp.Patch(rootpath, f)
+}
+
+// Patch used to register router for Patch method
+// usage:
+// beego.Patch("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Patch(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Patch(rootpath, f)
+ return app
+}
+
+// Any see HttpServer.Any
+func Any(rootpath string, f HandleFunc) *HttpServer {
+ return BeeApp.Any(rootpath, f)
+}
+
+// Any used to register router for all methods
+// usage:
+// beego.Any("/api", func(ctx *context.Context){
+// ctx.Output.Body("hello world")
+// })
+func (app *HttpServer) Any(rootpath string, f HandleFunc) *HttpServer {
+ app.Handlers.Any(rootpath, f)
+ return app
+}
+
+// Handler see HttpServer.Handler
+func Handler(rootpath string, h http.Handler, options ...interface{}) *HttpServer {
+ return BeeApp.Handler(rootpath, h, options...)
+}
+
+// Handler used to register a Handler router
+// usage:
+// beego.Handler("/api", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
+// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
+// }))
+func (app *HttpServer) Handler(rootpath string, h http.Handler, options ...interface{}) *HttpServer {
+ app.Handlers.Handler(rootpath, h, options...)
+ return app
+}
+
+// InserFilter see HttpServer.InsertFilter
+func InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) *HttpServer {
+ return BeeApp.InsertFilter(pattern, pos, filter, opts...)
+}
+
+// InsertFilter adds a FilterFunc with pattern condition and action constant.
+// The pos means action constant including
+// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
+// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
+func (app *HttpServer) InsertFilter(pattern string, pos int, filter FilterFunc, opts ...FilterOpt) *HttpServer {
+ app.Handlers.InsertFilter(pattern, pos, filter, opts...)
+ return app
+}
+
+// InsertFilterChain see HttpServer.InsertFilterChain
+func InsertFilterChain(pattern string, filterChain FilterChain, opts ...FilterOpt) *HttpServer {
+ return BeeApp.InsertFilterChain(pattern, filterChain, opts...)
+}
+
+// InsertFilterChain adds a FilterFunc built by filterChain.
+// This filter will be executed before all filters.
+// the filter's behavior like stack's behavior
+// and the last filter is serving the http request
+func (app *HttpServer) InsertFilterChain(pattern string, filterChain FilterChain, opts ...FilterOpt) *HttpServer {
+ app.Handlers.InsertFilterChain(pattern, filterChain, opts...)
+ return app
+}
+
+func (app *HttpServer) initAddr(addr string) {
+ strs := strings.Split(addr, ":")
+ if len(strs) > 0 && strs[0] != "" {
+ app.Cfg.Listen.HTTPAddr = strs[0]
+ app.Cfg.Listen.Domains = []string{strs[0]}
+ }
+ if len(strs) > 1 && strs[1] != "" {
+ app.Cfg.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
+ }
+}
+
+func (app *HttpServer) LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
+ // Skip logging if AccessLogs config is false
+ if !app.Cfg.Log.AccessLogs {
+ return
+ }
+ // Skip logging static requests unless EnableStaticLogs config is true
+ if !app.Cfg.Log.EnableStaticLogs && DefaultAccessLogFilter.Filter(ctx) {
+ return
+ }
+ var (
+ requestTime time.Time
+ elapsedTime time.Duration
+ r = ctx.Request
+ )
+ if startTime != nil {
+ requestTime = *startTime
+ elapsedTime = time.Since(*startTime)
+ }
+ record := &logs.AccessLogRecord{
+ RemoteAddr: ctx.Input.IP(),
+ RequestTime: requestTime,
+ RequestMethod: r.Method,
+ Request: fmt.Sprintf("%s %s %s", r.Method, r.RequestURI, r.Proto),
+ ServerProtocol: r.Proto,
+ Host: r.Host,
+ Status: statusCode,
+ ElapsedTime: elapsedTime,
+ HTTPReferrer: r.Header.Get("Referer"),
+ HTTPUserAgent: r.Header.Get("User-Agent"),
+ RemoteUser: r.Header.Get("Remote-User"),
+ BodyBytesSent: r.ContentLength,
+ }
+ logs.AccessLog(record, app.Cfg.Log.AccessLogsFormat)
+}
+
+// PrintTree prints all registered routers.
+func (app *HttpServer) PrintTree() M {
+ var (
+ content = M{}
+ methods = []string{}
+ methodsData = make(M)
+ )
+ for method, t := range app.Handlers.routers {
+
+ resultList := new([][]string)
+
+ printTree(resultList, t)
+
+ methods = append(methods, template.HTMLEscapeString(method))
+ methodsData[template.HTMLEscapeString(method)] = resultList
+ }
+
+ content["Data"] = methodsData
+ content["Methods"] = methods
+ return content
+}
+
+func printTree(resultList *[][]string, t *Tree) {
+ for _, tr := range t.fixrouters {
+ printTree(resultList, tr)
+ }
+ if t.wildcard != nil {
+ printTree(resultList, t.wildcard)
+ }
+ for _, l := range t.leaves {
+ if v, ok := l.runObject.(*ControllerInfo); ok {
+ if v.routerType == routerTypeBeego {
+ result := []string{
+ template.HTMLEscapeString(v.pattern),
+ template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
+ template.HTMLEscapeString(v.controllerType.String()),
+ }
+ *resultList = append(*resultList, result)
+ } else if v.routerType == routerTypeRESTFul {
+ result := []string{
+ template.HTMLEscapeString(v.pattern),
+ template.HTMLEscapeString(fmt.Sprintf("%s", v.methods)),
+ "",
+ }
+ *resultList = append(*resultList, result)
+ } else if v.routerType == routerTypeHandler {
+ result := []string{
+ template.HTMLEscapeString(v.pattern),
+ "",
+ "",
+ }
+ *resultList = append(*resultList, result)
+ }
+ }
+ }
+}
+
+func (app *HttpServer) reportFilter() M {
+ filterTypeData := make(M)
+ // filterTypes := []string{}
+ if app.Handlers.enableFilter {
+ // var filterType string
+ for k, fr := range map[int]string{
+ BeforeStatic: "Before Static",
+ BeforeRouter: "Before Router",
+ BeforeExec: "Before Exec",
+ AfterExec: "After Exec",
+ FinishRouter: "Finish Router",
+ } {
+ if bf := app.Handlers.filters[k]; len(bf) > 0 {
+ resultList := new([][]string)
+ for _, f := range bf {
+ result := []string{
+ // void xss
+ template.HTMLEscapeString(f.pattern),
+ template.HTMLEscapeString(utils.GetFuncName(f.filterFunc)),
+ }
+ *resultList = append(*resultList, result)
+ }
+ filterTypeData[fr] = resultList
+ }
+ }
+ }
+
+ return filterTypeData
+}
diff --git a/src/vendor/github.com/beego/beego/session/README.md b/src/vendor/github.com/beego/beego/v2/server/web/session/README.md
similarity index 61%
rename from src/vendor/github.com/beego/beego/session/README.md
rename to src/vendor/github.com/beego/beego/v2/server/web/session/README.md
index a7cd5fa1e..8dd70f67d 100644
--- a/src/vendor/github.com/beego/beego/session/README.md
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/README.md
@@ -1,67 +1,66 @@
session
==============
-session is a Go session manager. It can use many session providers. Just like the `database/sql` and `database/sql/driver`.
+session is a Go session manager. It can use many session providers. Just like the `database/sql`
+and `database/sql/driver`.
## How to install?
- go get github.com/beego/beego/session
-
+ go get github.com/beego/beego/v2/server/web/session
## What providers are supported?
As of now this session manager support memory, file, Redis and MySQL.
-
## How to use it?
First you must import it
import (
- "github.com/beego/beego/session"
+ "github.com/beego/beego/v2/server/web/session"
)
Then in you web app init the global session manager
-
+
var globalSessions *session.Manager
* Use **memory** as provider:
- func init() {
- globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid","gclifetime":3600}`)
- go globalSessions.GC()
- }
+ func init() {
+ globalSessions, _ = session.NewManager("memory", `{"cookieName":"gosessionid","gclifetime":3600}`)
+ go globalSessions.GC()
+ }
* Use **file** as provider, the last param is the path where you want file to be stored:
- func init() {
- globalSessions, _ = session.NewManager("file",`{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"./tmp"}`)
- go globalSessions.GC()
- }
+ func init() {
+ globalSessions, _ = session.NewManager("file",`{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"./tmp"}`)
+ go globalSessions.GC()
+ }
* Use **Redis** as provider, the last param is the Redis conn address,poolsize,password:
- func init() {
- globalSessions, _ = session.NewManager("redis", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:6379,100,astaxie"}`)
- go globalSessions.GC()
- }
-
-* Use **MySQL** as provider, the last param is the DSN, learn more from [mysql](https://github.com/go-sql-driver/mysql#dsn-data-source-name):
+ func init() {
+ globalSessions, _ = session.NewManager("redis", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:6379,100,astaxie"}`)
+ go globalSessions.GC()
+ }
- func init() {
- globalSessions, _ = session.NewManager(
- "mysql", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"username:password@protocol(address)/dbname?param=value"}`)
- go globalSessions.GC()
- }
+* Use **MySQL** as provider, the last param is the DSN, learn more
+ from [mysql](https://github.com/go-sql-driver/mysql#dsn-data-source-name):
+
+ func init() {
+ globalSessions, _ = session.NewManager(
+ "mysql", `{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"username:password@protocol(address)/dbname?param=value"}`)
+ go globalSessions.GC()
+ }
* Use **Cookie** as provider:
- func init() {
- globalSessions, _ = session.NewManager(
- "cookie", `{"cookieName":"gosessionid","enableSetCookie":false,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}`)
- go globalSessions.GC()
- }
-
+ func init() {
+ globalSessions, _ = session.NewManager(
+ "cookie", `{"cookieName":"gosessionid","enableSetCookie":false,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}`)
+ go globalSessions.GC()
+ }
Finally in the handlerfunc you can use it like this
@@ -80,14 +79,13 @@ Finally in the handlerfunc you can use it like this
}
}
-
## How to write own provider?
When you develop a web app, maybe you want to write own provider because you must meet the requirements.
-Writing a provider is easy. You only need to define two struct types
-(Session and Provider), which satisfy the interface definition.
-Maybe you will find the **memory** provider is a good example.
+Writing a provider is easy. You only need to define two struct types
+(Session and Provider), which satisfy the interface definition. Maybe you will find the **memory** provider is a good
+example.
type SessionStore interface {
Set(key, value interface{}) error //set session value
@@ -101,14 +99,13 @@ Maybe you will find the **memory** provider is a good example.
type Provider interface {
SessionInit(gclifetime int64, config string) error
SessionRead(sid string) (SessionStore, error)
- SessionExist(sid string) bool
+ SessionExist(sid string) (bool, error)
SessionRegenerate(oldsid, sid string) (SessionStore, error)
SessionDestroy(sid string) error
SessionAll() int //get all active session
SessionGC()
}
-
## LICENSE
BSD License http://creativecommons.org/licenses/BSD/
diff --git a/src/vendor/github.com/beego/beego/session/sess_cookie.go b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_cookie.go
similarity index 75%
rename from src/vendor/github.com/beego/beego/session/sess_cookie.go
rename to src/vendor/github.com/beego/beego/v2/server/web/session/sess_cookie.go
index 6ad5debc3..622fb2fe2 100644
--- a/src/vendor/github.com/beego/beego/session/sess_cookie.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_cookie.go
@@ -15,6 +15,7 @@
package session
import (
+ "context"
"crypto/aes"
"crypto/cipher"
"encoding/json"
@@ -34,7 +35,7 @@ type CookieSessionStore struct {
// Set value to cookie session.
// the value are encoded as gob with hash block string.
-func (st *CookieSessionStore) Set(key, value interface{}) error {
+func (st *CookieSessionStore) Set(ctx context.Context, key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
st.values[key] = value
@@ -42,7 +43,7 @@ func (st *CookieSessionStore) Set(key, value interface{}) error {
}
// Get value from cookie session
-func (st *CookieSessionStore) Get(key interface{}) interface{} {
+func (st *CookieSessionStore) Get(ctx context.Context, key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
if v, ok := st.values[key]; ok {
@@ -52,7 +53,7 @@ func (st *CookieSessionStore) Get(key interface{}) interface{} {
}
// Delete value in cookie session
-func (st *CookieSessionStore) Delete(key interface{}) error {
+func (st *CookieSessionStore) Delete(ctx context.Context, key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
delete(st.values, key)
@@ -60,7 +61,7 @@ func (st *CookieSessionStore) Delete(key interface{}) error {
}
// Flush Clean all values in cookie session
-func (st *CookieSessionStore) Flush() error {
+func (st *CookieSessionStore) Flush(context.Context) error {
st.lock.Lock()
defer st.lock.Unlock()
st.values = make(map[interface{}]interface{})
@@ -68,22 +69,24 @@ func (st *CookieSessionStore) Flush() error {
}
// SessionID Return id of this cookie session
-func (st *CookieSessionStore) SessionID() string {
+func (st *CookieSessionStore) SessionID(context.Context) string {
return st.sid
}
// SessionRelease Write cookie session to http response cookie
-func (st *CookieSessionStore) SessionRelease(w http.ResponseWriter) {
+func (st *CookieSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
st.lock.Lock()
encodedCookie, err := encodeCookie(cookiepder.block, cookiepder.config.SecurityKey, cookiepder.config.SecurityName, st.values)
st.lock.Unlock()
if err == nil {
- cookie := &http.Cookie{Name: cookiepder.config.CookieName,
+ cookie := &http.Cookie{
+ Name: cookiepder.config.CookieName,
Value: url.QueryEscape(encodedCookie),
Path: "/",
HttpOnly: true,
Secure: cookiepder.config.Secure,
- MaxAge: cookiepder.config.Maxage}
+ MaxAge: cookiepder.config.Maxage,
+ }
http.SetCookie(w, cookie)
}
}
@@ -112,7 +115,7 @@ type CookieProvider struct {
// securityName - recognized name in encoded cookie string
// cookieName - cookie name
// maxage - cookie max life time.
-func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error {
+func (pder *CookieProvider) SessionInit(ctx context.Context, maxlifetime int64, config string) error {
pder.config = &cookieConfig{}
err := json.Unmarshal([]byte(config), pder.config)
if err != nil {
@@ -134,7 +137,7 @@ func (pder *CookieProvider) SessionInit(maxlifetime int64, config string) error
// SessionRead Get SessionStore in cooke.
// decode cooke string to map and put into SessionStore with sid.
-func (pder *CookieProvider) SessionRead(sid string) (Store, error) {
+func (pder *CookieProvider) SessionRead(ctx context.Context, sid string) (Store, error) {
maps, _ := decodeCookie(pder.block,
pder.config.SecurityKey,
pder.config.SecurityName,
@@ -147,31 +150,31 @@ func (pder *CookieProvider) SessionRead(sid string) (Store, error) {
}
// SessionExist Cookie session is always existed
-func (pder *CookieProvider) SessionExist(sid string) bool {
- return true
+func (pder *CookieProvider) SessionExist(ctx context.Context, sid string) (bool, error) {
+ return true, nil
}
// SessionRegenerate Implement method, no used.
-func (pder *CookieProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
+func (pder *CookieProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error) {
return nil, nil
}
// SessionDestroy Implement method, no used.
-func (pder *CookieProvider) SessionDestroy(sid string) error {
+func (pder *CookieProvider) SessionDestroy(ctx context.Context, sid string) error {
return nil
}
// SessionGC Implement method, no used.
-func (pder *CookieProvider) SessionGC() {
+func (pder *CookieProvider) SessionGC(context.Context) {
}
// SessionAll Implement method, return 0.
-func (pder *CookieProvider) SessionAll() int {
+func (pder *CookieProvider) SessionAll(context.Context) int {
return 0
}
// SessionUpdate Implement method, no used.
-func (pder *CookieProvider) SessionUpdate(sid string) error {
+func (pder *CookieProvider) SessionUpdate(ctx context.Context, sid string) error {
return nil
}
diff --git a/src/vendor/github.com/beego/beego/session/sess_file.go b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_file.go
similarity index 77%
rename from src/vendor/github.com/beego/beego/session/sess_file.go
rename to src/vendor/github.com/beego/beego/v2/server/web/session/sess_file.go
index 47ad54a7f..14cec1d9a 100644
--- a/src/vendor/github.com/beego/beego/session/sess_file.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_file.go
@@ -15,6 +15,7 @@
package session
import (
+ "context"
"errors"
"fmt"
"io/ioutil"
@@ -40,7 +41,7 @@ type FileSessionStore struct {
}
// Set value to file session
-func (fs *FileSessionStore) Set(key, value interface{}) error {
+func (fs *FileSessionStore) Set(ctx context.Context, key, value interface{}) error {
fs.lock.Lock()
defer fs.lock.Unlock()
fs.values[key] = value
@@ -48,7 +49,7 @@ func (fs *FileSessionStore) Set(key, value interface{}) error {
}
// Get value from file session
-func (fs *FileSessionStore) Get(key interface{}) interface{} {
+func (fs *FileSessionStore) Get(ctx context.Context, key interface{}) interface{} {
fs.lock.RLock()
defer fs.lock.RUnlock()
if v, ok := fs.values[key]; ok {
@@ -58,7 +59,7 @@ func (fs *FileSessionStore) Get(key interface{}) interface{} {
}
// Delete value in file session by given key
-func (fs *FileSessionStore) Delete(key interface{}) error {
+func (fs *FileSessionStore) Delete(ctx context.Context, key interface{}) error {
fs.lock.Lock()
defer fs.lock.Unlock()
delete(fs.values, key)
@@ -66,7 +67,7 @@ func (fs *FileSessionStore) Delete(key interface{}) error {
}
// Flush Clean all values in file session
-func (fs *FileSessionStore) Flush() error {
+func (fs *FileSessionStore) Flush(context.Context) error {
fs.lock.Lock()
defer fs.lock.Unlock()
fs.values = make(map[interface{}]interface{})
@@ -74,12 +75,12 @@ func (fs *FileSessionStore) Flush() error {
}
// SessionID Get file session store id
-func (fs *FileSessionStore) SessionID() string {
+func (fs *FileSessionStore) SessionID(context.Context) string {
return fs.sid
}
// SessionRelease Write file session to local file with Gob string
-func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
+func (fs *FileSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
b, err := EncodeGob(fs.values)
@@ -90,7 +91,7 @@ func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) {
_, err = os.Stat(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid))
var f *os.File
if err == nil {
- f, err = os.OpenFile(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid), os.O_RDWR, 0777)
+ f, err = os.OpenFile(path.Join(filepder.savePath, string(fs.sid[0]), string(fs.sid[1]), fs.sid), os.O_RDWR, 0o777)
if err != nil {
SLogger.Println(err)
return
@@ -119,7 +120,7 @@ type FileProvider struct {
// SessionInit Init file session provider.
// savePath sets the session files path.
-func (fp *FileProvider) SessionInit(maxlifetime int64, savePath string) error {
+func (fp *FileProvider) SessionInit(ctx context.Context, maxlifetime int64, savePath string) error {
fp.maxlifetime = maxlifetime
fp.savePath = savePath
return nil
@@ -128,7 +129,7 @@ func (fp *FileProvider) SessionInit(maxlifetime int64, savePath string) error {
// SessionRead Read file session by sid.
// if file is not exist, create it.
// the file path is generated from sid string.
-func (fp *FileProvider) SessionRead(sid string) (Store, error) {
+func (fp *FileProvider) SessionRead(ctx context.Context, sid string) (Store, error) {
invalidChars := "./"
if strings.ContainsAny(sid, invalidChars) {
return nil, errors.New("the sid shouldn't have following characters: " + invalidChars)
@@ -139,23 +140,32 @@ func (fp *FileProvider) SessionRead(sid string) (Store, error) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
- err := os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0755)
+ sessionPath := filepath.Join(fp.savePath, string(sid[0]), string(sid[1]))
+ sidPath := filepath.Join(sessionPath, sid)
+ err := os.MkdirAll(sessionPath, 0o755)
if err != nil {
SLogger.Println(err.Error())
}
- _, err = os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
var f *os.File
- if err == nil {
- f, err = os.OpenFile(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid), os.O_RDWR, 0777)
- } else if os.IsNotExist(err) {
- f, err = os.Create(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
- } else {
+ _, err = os.Stat(sidPath)
+ switch {
+ case err == nil:
+ f, err = os.OpenFile(sidPath, os.O_RDWR, 0o777)
+ if err != nil {
+ return nil, err
+ }
+ case os.IsNotExist(err):
+ f, err = os.Create(sidPath)
+ if err != nil {
+ return nil, err
+ }
+ default:
return nil, err
}
defer f.Close()
- os.Chtimes(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid), time.Now(), time.Now())
+ os.Chtimes(sidPath, time.Now(), time.Now())
var kv map[interface{}]interface{}
b, err := ioutil.ReadAll(f)
if err != nil {
@@ -176,21 +186,21 @@ func (fp *FileProvider) SessionRead(sid string) (Store, error) {
// SessionExist Check file session exist.
// it checks the file named from sid exist or not.
-func (fp *FileProvider) SessionExist(sid string) bool {
+func (fp *FileProvider) SessionExist(ctx context.Context, sid string) (bool, error) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
if len(sid) < 2 {
- SLogger.Println("min length of session id is 2", sid)
- return false
+ SLogger.Println("min length of session id is 2 but got length: ", sid)
+ return false, errors.New("min length of session id is 2")
}
_, err := os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
- return err == nil
+ return err == nil, nil
}
// SessionDestroy Remove all files in this save path
-func (fp *FileProvider) SessionDestroy(sid string) error {
+func (fp *FileProvider) SessionDestroy(ctx context.Context, sid string) error {
filepder.lock.Lock()
defer filepder.lock.Unlock()
os.Remove(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
@@ -198,7 +208,7 @@ func (fp *FileProvider) SessionDestroy(sid string) error {
}
// SessionGC Recycle files in save path
-func (fp *FileProvider) SessionGC() {
+func (fp *FileProvider) SessionGC(context.Context) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
@@ -208,11 +218,9 @@ func (fp *FileProvider) SessionGC() {
// SessionAll Get active file session number.
// it walks save path to count files.
-func (fp *FileProvider) SessionAll() int {
+func (fp *FileProvider) SessionAll(context.Context) int {
a := &activeSession{}
- err := filepath.Walk(fp.savePath, func(path string, f os.FileInfo, err error) error {
- return a.visit(path, f, err)
- })
+ err := filepath.Walk(fp.savePath, a.visit)
if err != nil {
SLogger.Printf("filepath.Walk() returned %v\n", err)
return 0
@@ -222,7 +230,7 @@ func (fp *FileProvider) SessionAll() int {
// SessionRegenerate Generate new sid for file session.
// it delete old file and create new file named from new sid.
-func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
+func (fp *FileProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
@@ -237,7 +245,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
return nil, fmt.Errorf("newsid %s exist", newSidFile)
}
- err = os.MkdirAll(newPath, 0755)
+ err = os.MkdirAll(newPath, 0o755)
if err != nil {
SLogger.Println(err.Error())
}
@@ -264,7 +272,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
}
}
- ioutil.WriteFile(newSidFile, b, 0777)
+ ioutil.WriteFile(newSidFile, b, 0o777)
os.Remove(oldSidFile)
os.Chtimes(newSidFile, time.Now(), time.Now())
ss := &FileSessionStore{sid: sid, values: kv}
diff --git a/src/vendor/github.com/beego/beego/session/sess_mem.go b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_mem.go
similarity index 75%
rename from src/vendor/github.com/beego/beego/session/sess_mem.go
rename to src/vendor/github.com/beego/beego/v2/server/web/session/sess_mem.go
index 64d8b0561..b0a821ba6 100644
--- a/src/vendor/github.com/beego/beego/session/sess_mem.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_mem.go
@@ -16,6 +16,7 @@ package session
import (
"container/list"
+ "context"
"net/http"
"sync"
"time"
@@ -26,14 +27,14 @@ var mempder = &MemProvider{list: list.New(), sessions: make(map[string]*list.Ele
// MemSessionStore memory session store.
// it saved sessions in a map in memory.
type MemSessionStore struct {
- sid string //session id
- timeAccessed time.Time //last access time
- value map[interface{}]interface{} //session store
+ sid string // session id
+ timeAccessed time.Time // last access time
+ value map[interface{}]interface{} // session store
lock sync.RWMutex
}
// Set value to memory session
-func (st *MemSessionStore) Set(key, value interface{}) error {
+func (st *MemSessionStore) Set(ctx context.Context, key, value interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
st.value[key] = value
@@ -41,7 +42,7 @@ func (st *MemSessionStore) Set(key, value interface{}) error {
}
// Get value from memory session by key
-func (st *MemSessionStore) Get(key interface{}) interface{} {
+func (st *MemSessionStore) Get(ctx context.Context, key interface{}) interface{} {
st.lock.RLock()
defer st.lock.RUnlock()
if v, ok := st.value[key]; ok {
@@ -51,7 +52,7 @@ func (st *MemSessionStore) Get(key interface{}) interface{} {
}
// Delete in memory session by key
-func (st *MemSessionStore) Delete(key interface{}) error {
+func (st *MemSessionStore) Delete(ctx context.Context, key interface{}) error {
st.lock.Lock()
defer st.lock.Unlock()
delete(st.value, key)
@@ -59,7 +60,7 @@ func (st *MemSessionStore) Delete(key interface{}) error {
}
// Flush clear all values in memory session
-func (st *MemSessionStore) Flush() error {
+func (st *MemSessionStore) Flush(context.Context) error {
st.lock.Lock()
defer st.lock.Unlock()
st.value = make(map[interface{}]interface{})
@@ -67,12 +68,12 @@ func (st *MemSessionStore) Flush() error {
}
// SessionID get this id of memory session store
-func (st *MemSessionStore) SessionID() string {
+func (st *MemSessionStore) SessionID(context.Context) string {
return st.sid
}
// SessionRelease Implement method, no used.
-func (st *MemSessionStore) SessionRelease(w http.ResponseWriter) {
+func (st *MemSessionStore) SessionRelease(ctx context.Context, w http.ResponseWriter) {
}
// MemProvider Implement the provider interface
@@ -85,17 +86,17 @@ type MemProvider struct {
}
// SessionInit init memory session
-func (pder *MemProvider) SessionInit(maxlifetime int64, savePath string) error {
+func (pder *MemProvider) SessionInit(ctx context.Context, maxlifetime int64, savePath string) error {
pder.maxlifetime = maxlifetime
pder.savePath = savePath
return nil
}
// SessionRead get memory session store by sid
-func (pder *MemProvider) SessionRead(sid string) (Store, error) {
+func (pder *MemProvider) SessionRead(ctx context.Context, sid string) (Store, error) {
pder.lock.RLock()
if element, ok := pder.sessions[sid]; ok {
- go pder.SessionUpdate(sid)
+ go pder.SessionUpdate(nil, sid)
pder.lock.RUnlock()
return element.Value.(*MemSessionStore), nil
}
@@ -109,20 +110,20 @@ func (pder *MemProvider) SessionRead(sid string) (Store, error) {
}
// SessionExist check session store exist in memory session by sid
-func (pder *MemProvider) SessionExist(sid string) bool {
+func (pder *MemProvider) SessionExist(ctx context.Context, sid string) (bool, error) {
pder.lock.RLock()
defer pder.lock.RUnlock()
if _, ok := pder.sessions[sid]; ok {
- return true
+ return true, nil
}
- return false
+ return false, nil
}
// SessionRegenerate generate new sid for session store in memory session
-func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
+func (pder *MemProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error) {
pder.lock.RLock()
if element, ok := pder.sessions[oldsid]; ok {
- go pder.SessionUpdate(oldsid)
+ go pder.SessionUpdate(nil, oldsid)
pder.lock.RUnlock()
pder.lock.Lock()
element.Value.(*MemSessionStore).sid = sid
@@ -141,7 +142,7 @@ func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
}
// SessionDestroy delete session store in memory session by id
-func (pder *MemProvider) SessionDestroy(sid string) error {
+func (pder *MemProvider) SessionDestroy(ctx context.Context, sid string) error {
pder.lock.Lock()
defer pder.lock.Unlock()
if element, ok := pder.sessions[sid]; ok {
@@ -153,7 +154,7 @@ func (pder *MemProvider) SessionDestroy(sid string) error {
}
// SessionGC clean expired session stores in memory session
-func (pder *MemProvider) SessionGC() {
+func (pder *MemProvider) SessionGC(context.Context) {
pder.lock.RLock()
for {
element := pder.list.Back()
@@ -175,12 +176,12 @@ func (pder *MemProvider) SessionGC() {
}
// SessionAll get count number of memory session
-func (pder *MemProvider) SessionAll() int {
+func (pder *MemProvider) SessionAll(context.Context) int {
return pder.list.Len()
}
// SessionUpdate expand time of session store by id in memory session
-func (pder *MemProvider) SessionUpdate(sid string) error {
+func (pder *MemProvider) SessionUpdate(ctx context.Context, sid string) error {
pder.lock.Lock()
defer pder.lock.Unlock()
if element, ok := pder.sessions[sid]; ok {
diff --git a/src/vendor/github.com/beego/beego/session/sess_utils.go b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_utils.go
similarity index 98%
rename from src/vendor/github.com/beego/beego/session/sess_utils.go
rename to src/vendor/github.com/beego/beego/v2/server/web/session/sess_utils.go
index a22ac6308..b26493367 100644
--- a/src/vendor/github.com/beego/beego/session/sess_utils.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/sess_utils.go
@@ -29,7 +29,7 @@ import (
"strconv"
"time"
- "github.com/beego/beego/utils"
+ "github.com/beego/beego/v2/core/utils"
)
func init() {
@@ -98,7 +98,7 @@ func encrypt(block cipher.Block, value []byte) ([]byte, error) {
// decrypt decrypts a value using the given block in counter mode.
//
-// The value to be decrypted must be prepended by a initialization vector
+// The value to be decrypted must be prepended by an initialization vector
// (http://goo.gl/zF67k) with the length of the block size.
func decrypt(block cipher.Block, value []byte) ([]byte, error) {
size := block.BlockSize()
diff --git a/src/vendor/github.com/beego/beego/session/session.go b/src/vendor/github.com/beego/beego/v2/server/web/session/session.go
similarity index 76%
rename from src/vendor/github.com/beego/beego/session/session.go
rename to src/vendor/github.com/beego/beego/v2/server/web/session/session.go
index 024c5eefe..b5300abc5 100644
--- a/src/vendor/github.com/beego/beego/session/session.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/session.go
@@ -16,7 +16,7 @@
//
// Usage:
// import(
-// "github.com/beego/beego/session"
+// "github.com/beego/beego/v2/server/web/session"
// )
//
// func init() {
@@ -24,10 +24,11 @@
// go globalSessions.GC()
// }
//
-// more docs: http://beego.me/docs/module/session.md
+// more docs: http://beego.vip/docs/module/session.md
package session
import (
+ "context"
"crypto/rand"
"encoding/hex"
"errors"
@@ -43,24 +44,24 @@ import (
// Store contains all data for one session process with specific id.
type Store interface {
- Set(key, value interface{}) error //set session value
- Get(key interface{}) interface{} //get session value
- Delete(key interface{}) error //delete session value
- SessionID() string //back current sessionID
- SessionRelease(w http.ResponseWriter) // release the resource & save data to provider & return the data
- Flush() error //delete all data
+ Set(ctx context.Context, key, value interface{}) error // set session value
+ Get(ctx context.Context, key interface{}) interface{} // get session value
+ Delete(ctx context.Context, key interface{}) error // delete session value
+ SessionID(ctx context.Context) string // back current sessionID
+ SessionRelease(ctx context.Context, w http.ResponseWriter) // release the resource & save data to provider & return the data
+ Flush(ctx context.Context) error // delete all data
}
// Provider contains global session methods and saved SessionStores.
// it can operate a SessionStore by its id.
type Provider interface {
- SessionInit(gclifetime int64, config string) error
- SessionRead(sid string) (Store, error)
- SessionExist(sid string) bool
- SessionRegenerate(oldsid, sid string) (Store, error)
- SessionDestroy(sid string) error
- SessionAll() int //get all active session
- SessionGC()
+ SessionInit(ctx context.Context, gclifetime int64, config string) error
+ SessionRead(ctx context.Context, sid string) (Store, error)
+ SessionExist(ctx context.Context, sid string) (bool, error)
+ SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error)
+ SessionDestroy(ctx context.Context, sid string) error
+ SessionAll(ctx context.Context) int // get all active session
+ SessionGC(ctx context.Context)
}
var provides = make(map[string]Provider)
@@ -69,19 +70,15 @@ var provides = make(map[string]Provider)
var SLogger = NewSessionLog(os.Stderr)
// Register makes a session provide available by the provided name.
-// If Register is called twice with the same name or if driver is nil,
-// it panics.
+// If provider is nil, it panic
func Register(name string, provide Provider) {
if provide == nil {
panic("session: Register provide is nil")
}
- if _, dup := provides[name]; dup {
- panic("session: Register called twice for provider " + name)
- }
provides[name] = provide
}
-//GetProvider
+// GetProvider
func GetProvider(name string) (Provider, error) {
provider, ok := provides[name]
if !ok {
@@ -90,25 +87,6 @@ func GetProvider(name string) (Provider, error) {
return provider, nil
}
-// ManagerConfig define the session config
-type ManagerConfig struct {
- CookieName string `json:"cookieName"`
- EnableSetCookie bool `json:"enableSetCookie,omitempty"`
- Gclifetime int64 `json:"gclifetime"`
- Maxlifetime int64 `json:"maxLifetime"`
- DisableHTTPOnly bool `json:"disableHTTPOnly"`
- Secure bool `json:"secure"`
- CookieLifeTime int `json:"cookieLifeTime"`
- ProviderConfig string `json:"providerConfig"`
- Domain string `json:"domain"`
- SessionIDLength int64 `json:"sessionIDLength"`
- EnableSidInHTTPHeader bool `json:"EnableSidInHTTPHeader"`
- SessionNameInHTTPHeader string `json:"SessionNameInHTTPHeader"`
- EnableSidInURLQuery bool `json:"EnableSidInURLQuery"`
- SessionIDPrefix string `json:"sessionIDPrefix"`
- CookieSameSite http.SameSite `json:"cookieSameSite"`
-}
-
// Manager contains Provider and its configuration.
type Manager struct {
provider Provider
@@ -149,7 +127,7 @@ func NewManager(provideName string, cf *ManagerConfig) (*Manager, error) {
}
}
- err := provider.SessionInit(cf.Maxlifetime, cf.ProviderConfig)
+ err := provider.SessionInit(nil, cf.Maxlifetime, cf.ProviderConfig)
if err != nil {
return nil, err
}
@@ -212,8 +190,14 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
return nil, errs
}
- if sid != "" && manager.provider.SessionExist(sid) {
- return manager.provider.SessionRead(sid)
+ if sid != "" {
+ exists, err := manager.provider.SessionExist(nil, sid)
+ if err != nil {
+ return nil, err
+ }
+ if exists {
+ return manager.provider.SessionRead(nil, sid)
+ }
}
// Generate a new session
@@ -222,7 +206,7 @@ func (manager *Manager) SessionStart(w http.ResponseWriter, r *http.Request) (se
return nil, errs
}
- session, err = manager.provider.SessionRead(sid)
+ session, err = manager.provider.SessionRead(nil, sid)
if err != nil {
return nil, err
}
@@ -265,10 +249,11 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
}
sid, _ := url.QueryUnescape(cookie.Value)
- manager.provider.SessionDestroy(sid)
+ manager.provider.SessionDestroy(nil, sid)
if manager.config.EnableSetCookie {
expiration := time.Now()
- cookie = &http.Cookie{Name: manager.config.CookieName,
+ cookie = &http.Cookie{
+ Name: manager.config.CookieName,
Path: "/",
HttpOnly: !manager.config.DisableHTTPOnly,
Expires: expiration,
@@ -283,14 +268,14 @@ func (manager *Manager) SessionDestroy(w http.ResponseWriter, r *http.Request) {
// GetSessionStore Get SessionStore by its id.
func (manager *Manager) GetSessionStore(sid string) (sessions Store, err error) {
- sessions, err = manager.provider.SessionRead(sid)
+ sessions, err = manager.provider.SessionRead(nil, sid)
return
}
// GC Start session gc process.
// it can do gc in times after gc lifetime.
func (manager *Manager) GC() {
- manager.provider.SessionGC()
+ manager.provider.SessionGC(nil)
time.AfterFunc(time.Duration(manager.config.Gclifetime)*time.Second, func() { manager.GC() })
}
@@ -300,15 +285,18 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
if err != nil {
return nil, err
}
+
var session Store
+
cookie, err := r.Cookie(manager.config.CookieName)
if err != nil || cookie.Value == "" {
// delete old cookie
- session, err = manager.provider.SessionRead(sid)
+ session, err = manager.provider.SessionRead(nil, sid)
if err != nil {
return nil, err
}
- cookie = &http.Cookie{Name: manager.config.CookieName,
+ cookie = &http.Cookie{
+ Name: manager.config.CookieName,
Value: url.QueryEscape(sid),
Path: "/",
HttpOnly: !manager.config.DisableHTTPOnly,
@@ -321,16 +309,15 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
if err != nil {
return nil, err
}
- session, err = manager.provider.SessionRegenerate(oldsid, sid)
+
+ session, err = manager.provider.SessionRegenerate(nil, oldsid, sid)
if err != nil {
return nil, err
}
+
cookie.Value = url.QueryEscape(sid)
cookie.HttpOnly = true
cookie.Path = "/"
- cookie.Secure = manager.isSecure(r)
- cookie.Domain = manager.config.Domain
- cookie.SameSite = manager.config.CookieSameSite
}
if manager.config.CookieLifeTime > 0 {
cookie.MaxAge = manager.config.CookieLifeTime
@@ -351,7 +338,7 @@ func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Reque
// GetActiveSession Get all active sessions count number.
func (manager *Manager) GetActiveSession() int {
- return manager.provider.SessionAll()
+ return manager.provider.SessionAll(nil)
}
// SetSecure Set cookie with https.
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/session/session_config.go b/src/vendor/github.com/beego/beego/v2/server/web/session/session_config.go
new file mode 100644
index 000000000..d9514003d
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/session_config.go
@@ -0,0 +1,143 @@
+package session
+
+import "net/http"
+
+// ManagerConfig define the session config
+type ManagerConfig struct {
+ EnableSetCookie bool `json:"enableSetCookie,omitempty"`
+ DisableHTTPOnly bool `json:"disableHTTPOnly"`
+ Secure bool `json:"secure"`
+ EnableSidInHTTPHeader bool `json:"EnableSidInHTTPHeader"`
+ EnableSidInURLQuery bool `json:"EnableSidInURLQuery"`
+ CookieName string `json:"cookieName"`
+ Gclifetime int64 `json:"gclifetime"`
+ Maxlifetime int64 `json:"maxLifetime"`
+ CookieLifeTime int `json:"cookieLifeTime"`
+ ProviderConfig string `json:"providerConfig"`
+ Domain string `json:"domain"`
+ SessionIDLength int64 `json:"sessionIDLength"`
+ SessionNameInHTTPHeader string `json:"SessionNameInHTTPHeader"`
+ SessionIDPrefix string `json:"sessionIDPrefix"`
+ CookieSameSite http.SameSite `json:"cookieSameSite"`
+}
+
+func (c *ManagerConfig) Opts(opts ...ManagerConfigOpt) {
+ for _, opt := range opts {
+ opt(c)
+ }
+}
+
+type ManagerConfigOpt func(config *ManagerConfig)
+
+func NewManagerConfig(opts ...ManagerConfigOpt) *ManagerConfig {
+ config := &ManagerConfig{}
+ for _, opt := range opts {
+ opt(config)
+ }
+ return config
+}
+
+// CfgCookieName set key of session id
+func CfgCookieName(cookieName string) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.CookieName = cookieName
+ }
+}
+
+// CfgCookieName set len of session id
+func CfgSessionIdLength(length int64) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.SessionIDLength = length
+ }
+}
+
+// CfgSessionIdPrefix set prefix of session id
+func CfgSessionIdPrefix(prefix string) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.SessionIDPrefix = prefix
+ }
+}
+
+// CfgSetCookie whether set `Set-Cookie` header in HTTP response
+func CfgSetCookie(enable bool) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.EnableSetCookie = enable
+ }
+}
+
+// CfgGcLifeTime set session gc lift time
+func CfgGcLifeTime(lifeTime int64) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.Gclifetime = lifeTime
+ }
+}
+
+// CfgMaxLifeTime set session lift time
+func CfgMaxLifeTime(lifeTime int64) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.Maxlifetime = lifeTime
+ }
+}
+
+// CfgGcLifeTime set session lift time
+func CfgCookieLifeTime(lifeTime int) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.CookieLifeTime = lifeTime
+ }
+}
+
+// CfgProviderConfig configure session provider
+func CfgProviderConfig(providerConfig string) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.ProviderConfig = providerConfig
+ }
+}
+
+// CfgDomain set cookie domain
+func CfgDomain(domain string) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.Domain = domain
+ }
+}
+
+// CfgSessionIdInHTTPHeader enable session id in http header
+func CfgSessionIdInHTTPHeader(enable bool) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.EnableSidInHTTPHeader = enable
+ }
+}
+
+// CfgSetSessionNameInHTTPHeader set key of session id in http header
+func CfgSetSessionNameInHTTPHeader(name string) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.SessionNameInHTTPHeader = name
+ }
+}
+
+// EnableSidInURLQuery enable session id in query string
+func CfgEnableSidInURLQuery(enable bool) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.EnableSidInURLQuery = enable
+ }
+}
+
+// DisableHTTPOnly set HTTPOnly for http.Cookie
+func CfgHTTPOnly(HTTPOnly bool) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.DisableHTTPOnly = !HTTPOnly
+ }
+}
+
+// CfgSecure set Secure for http.Cookie
+func CfgSecure(Enable bool) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.Secure = Enable
+ }
+}
+
+// CfgSameSite set http.SameSite
+func CfgSameSite(sameSite http.SameSite) ManagerConfigOpt {
+ return func(config *ManagerConfig) {
+ config.CookieSameSite = sameSite
+ }
+}
diff --git a/src/vendor/github.com/beego/beego/v2/server/web/session/session_provider_type.go b/src/vendor/github.com/beego/beego/v2/server/web/session/session_provider_type.go
new file mode 100644
index 000000000..78dc116dc
--- /dev/null
+++ b/src/vendor/github.com/beego/beego/v2/server/web/session/session_provider_type.go
@@ -0,0 +1,18 @@
+package session
+
+type ProviderType string
+
+const (
+ ProviderCookie ProviderType = `cookie`
+ ProviderFile ProviderType = `file`
+ ProviderMemory ProviderType = `memory`
+ ProviderCouchbase ProviderType = `couchbase`
+ ProviderLedis ProviderType = `ledis`
+ ProviderMemcache ProviderType = `memcache`
+ ProviderMysql ProviderType = `mysql`
+ ProviderPostgresql ProviderType = `postgresql`
+ ProviderRedis ProviderType = `redis`
+ ProviderRedisCluster ProviderType = `redis_cluster`
+ ProviderRedisSentinel ProviderType = `redis_sentinel`
+ ProviderSsdb ProviderType = `ssdb`
+)
diff --git a/src/vendor/github.com/beego/beego/staticfile.go b/src/vendor/github.com/beego/beego/v2/server/web/staticfile.go
similarity index 94%
rename from src/vendor/github.com/beego/beego/staticfile.go
rename to src/vendor/github.com/beego/beego/v2/server/web/staticfile.go
index f1135e36c..7a120f68f 100644
--- a/src/vendor/github.com/beego/beego/staticfile.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/staticfile.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"bytes"
@@ -26,9 +26,10 @@ import (
"sync"
"time"
- "github.com/beego/beego/context"
- "github.com/beego/beego/logs"
- "github.com/hashicorp/golang-lru"
+ lru "github.com/hashicorp/golang-lru"
+
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/server/web/context"
)
var errNotStaticRequest = errors.New("request not a static file request")
@@ -64,17 +65,17 @@ func serverStaticRouter(ctx *context.Context) {
}
ctx.Redirect(302, redirectURL)
} else {
- //serveFile will list dir
+ // serveFile will list dir
http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath)
}
return
} else if fileInfo.Size() > int64(BConfig.WebConfig.StaticCacheFileSize) {
- //over size file serve with http module
+ // over size file serve with http module
http.ServeFile(ctx.ResponseWriter, ctx.Request, filePath)
return
}
- var enableCompress = BConfig.EnableGzip && isStaticCompress(filePath)
+ enableCompress := BConfig.EnableGzip && isStaticCompress(filePath)
var acceptEncoding string
if enableCompress {
acceptEncoding = context.ParseEncoding(ctx.Request)
@@ -101,7 +102,7 @@ type serveContentHolder struct {
data []byte
modTime time.Time
size int64
- originSize int64 //original file size:to judge file changed
+ originSize int64 // original file size:to judge file changed
encoding string
}
@@ -116,7 +117,7 @@ var (
func openFile(filePath string, fi os.FileInfo, acceptEncoding string) (bool, string, *serveContentHolder, *serveContentReader, error) {
if staticFileLruCache == nil {
- //avoid lru cache error
+ // avoid lru cache error
if BConfig.WebConfig.StaticCacheFileNum >= 1 {
staticFileLruCache, _ = lru.New(BConfig.WebConfig.StaticCacheFileNum)
} else {
diff --git a/src/vendor/github.com/beego/beego/toolbox/statistics.go b/src/vendor/github.com/beego/beego/v2/server/web/statistics.go
similarity index 80%
rename from src/vendor/github.com/beego/beego/toolbox/statistics.go
rename to src/vendor/github.com/beego/beego/v2/server/web/statistics.go
index fd73dfb38..d0f3ebd9d 100644
--- a/src/vendor/github.com/beego/beego/toolbox/statistics.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/statistics.go
@@ -12,12 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package toolbox
+package web
import (
"fmt"
+ "html/template"
"sync"
"time"
+
+ "github.com/beego/beego/v2/core/utils"
)
// Statistics struct
@@ -33,7 +36,7 @@ type Statistics struct {
// URLMap contains several statistics struct to log different data
type URLMap struct {
lock sync.RWMutex
- LengthLimit int //limit the urlmap's length if it's equal to 0 there's no limit
+ LengthLimit int // limit the urlmap's length if it's equal to 0 there's no limit
urlmap map[string]map[string]*Statistics
}
@@ -63,7 +66,6 @@ func (m *URLMap) AddStatistics(requestMethod, requestURL, requestController stri
}
m.urlmap[requestURL][requestMethod] = nb
}
-
} else {
if m.LengthLimit > 0 && m.LengthLimit <= len(m.urlmap) {
return
@@ -87,7 +89,7 @@ func (m *URLMap) GetMap() map[string]interface{} {
m.lock.RLock()
defer m.lock.RUnlock()
- var fields = []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"}
+ fields := []string{"requestUrl", "method", "times", "used", "max used", "min used", "avg used"}
var resultLists [][]string
content := make(map[string]interface{})
@@ -96,17 +98,17 @@ func (m *URLMap) GetMap() map[string]interface{} {
for k, v := range m.urlmap {
for kk, vv := range v {
result := []string{
- fmt.Sprintf("% -50s", k),
+ fmt.Sprintf("% -50s", template.HTMLEscapeString(k)),
fmt.Sprintf("% -10s", kk),
fmt.Sprintf("% -16d", vv.RequestNum),
fmt.Sprintf("%d", vv.TotalTime),
- fmt.Sprintf("% -16s", toS(vv.TotalTime)),
+ fmt.Sprintf("% -16s", utils.ToShortTimeFormat(vv.TotalTime)),
fmt.Sprintf("%d", vv.MaxTime),
- fmt.Sprintf("% -16s", toS(vv.MaxTime)),
+ fmt.Sprintf("% -16s", utils.ToShortTimeFormat(vv.MaxTime)),
fmt.Sprintf("%d", vv.MinTime),
- fmt.Sprintf("% -16s", toS(vv.MinTime)),
+ fmt.Sprintf("% -16s", utils.ToShortTimeFormat(vv.MinTime)),
fmt.Sprintf("%d", time.Duration(int64(vv.TotalTime)/vv.RequestNum)),
- fmt.Sprintf("% -16s", toS(time.Duration(int64(vv.TotalTime)/vv.RequestNum))),
+ fmt.Sprintf("% -16s", utils.ToShortTimeFormat(time.Duration(int64(vv.TotalTime)/vv.RequestNum))),
}
resultLists = append(resultLists, result)
}
@@ -128,10 +130,10 @@ func (m *URLMap) GetMapData() []map[string]interface{} {
"request_url": k,
"method": kk,
"times": vv.RequestNum,
- "total_time": toS(vv.TotalTime),
- "max_time": toS(vv.MaxTime),
- "min_time": toS(vv.MinTime),
- "avg_time": toS(time.Duration(int64(vv.TotalTime) / vv.RequestNum)),
+ "total_time": utils.ToShortTimeFormat(vv.TotalTime),
+ "max_time": utils.ToShortTimeFormat(vv.MaxTime),
+ "min_time": utils.ToShortTimeFormat(vv.MinTime),
+ "avg_time": utils.ToShortTimeFormat(time.Duration(int64(vv.TotalTime) / vv.RequestNum)),
}
resultLists = append(resultLists, result)
}
diff --git a/src/vendor/github.com/beego/beego/template.go b/src/vendor/github.com/beego/beego/v2/server/web/template.go
similarity index 94%
rename from src/vendor/github.com/beego/beego/template.go
rename to src/vendor/github.com/beego/beego/v2/server/web/template.go
index b871e74b0..715c992d5 100644
--- a/src/vendor/github.com/beego/beego/template.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/template.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"errors"
@@ -27,8 +27,8 @@ import (
"strings"
"sync"
- "github.com/beego/beego/logs"
- "github.com/beego/beego/utils"
+ "github.com/beego/beego/v2/core/logs"
+ "github.com/beego/beego/v2/core/utils"
)
var (
@@ -103,7 +103,7 @@ func init() {
beegoTplFuncMap["lt"] = lt // <
beegoTplFuncMap["ne"] = ne // !=
- beegoTplFuncMap["urlfor"] = URLFor // build a URL to match a Controller and it's method
+ beegoTplFuncMap["urlfor"] = URLFor // build an URL to match a Controller and it's method
}
// AddFuncMap let user to register a func in the template.
@@ -163,12 +163,12 @@ func AddTemplateExt(ext string) {
}
// AddViewPath adds a new path to the supported view paths.
-//Can later be used by setting a controller ViewPath to this folder
-//will panic if called after beego.Run()
+// Can later be used by setting a controller ViewPath to this folder
+// will panic if called after beego.Run()
func AddViewPath(viewPath string) error {
if beeViewPathTemplateLocked {
if _, exist := beeViewPathTemplates[viewPath]; exist {
- return nil //Ignore if viewpath already exists
+ return nil // Ignore if viewpath already exists
}
panic("Can not add new view paths after beego.Run()")
}
@@ -202,9 +202,7 @@ func BuildTemplate(dir string, files ...string) error {
root: dir,
files: make(map[string][]string),
}
- err = Walk(fs, dir, func(path string, f os.FileInfo, err error) error {
- return self.visit(path, f, err)
- })
+ err = Walk(fs, dir, self.visit)
if err != nil {
fmt.Printf("Walk() returned %v\n", err)
return err
@@ -303,7 +301,7 @@ func _getTemplate(t0 *template.Template, root string, fs http.FileSystem, subMod
if tpl != nil {
continue
}
- //first check filename
+ // first check filename
for _, otherFile := range others {
if otherFile == m[1] {
var subMods1 [][]string
@@ -316,7 +314,7 @@ func _getTemplate(t0 *template.Template, root string, fs http.FileSystem, subMod
break
}
}
- //second check define
+ // second check define
for _, otherFile := range others {
var data []byte
fileAbsPath := filepath.Join(root, otherFile)
@@ -351,7 +349,6 @@ func _getTemplate(t0 *template.Template, root string, fs http.FileSystem, subMod
}
}
}
-
}
return
}
@@ -368,14 +365,14 @@ func SetTemplateFSFunc(fnt templateFSFunc) {
}
// SetViewsPath sets view directory path in beego application.
-func SetViewsPath(path string) *App {
+func SetViewsPath(path string) *HttpServer {
BConfig.WebConfig.ViewsPath = path
return BeeApp
}
// SetStaticPath sets static directory path and proper url pattern in beego application.
// if beego.SetStaticPath("static","public"), visit /static/* to load static file in folder "public".
-func SetStaticPath(url string, path string) *App {
+func SetStaticPath(url string, path string) *HttpServer {
if !strings.HasPrefix(url, "/") {
url = "/" + url
}
@@ -387,7 +384,7 @@ func SetStaticPath(url string, path string) *App {
}
// DelStaticPath removes the static folder setting in this url pattern in beego application.
-func DelStaticPath(url string) *App {
+func DelStaticPath(url string) *HttpServer {
if !strings.HasPrefix(url, "/") {
url = "/" + url
}
@@ -399,7 +396,7 @@ func DelStaticPath(url string) *App {
}
// AddTemplateEngine add a new templatePreProcessor which support extension
-func AddTemplateEngine(extension string, fn templatePreProcessor) *App {
+func AddTemplateEngine(extension string, fn templatePreProcessor) *HttpServer {
AddTemplateExt(extension)
beeTemplateEngines[extension] = fn
return BeeApp
diff --git a/src/vendor/github.com/beego/beego/templatefunc.go b/src/vendor/github.com/beego/beego/v2/server/web/templatefunc.go
similarity index 75%
rename from src/vendor/github.com/beego/beego/templatefunc.go
rename to src/vendor/github.com/beego/beego/v2/server/web/templatefunc.go
index 6f02b8d65..a44784d86 100644
--- a/src/vendor/github.com/beego/beego/templatefunc.go
+++ b/src/vendor/github.com/beego/beego/v2/server/web/templatefunc.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package beego
+package web
import (
"errors"
@@ -25,13 +25,8 @@ import (
"strconv"
"strings"
"time"
-)
-const (
- formatTime = "15:04:05"
- formatDate = "2006-01-02"
- formatDateTime = "2006-01-02 15:04:05"
- formatDateTimeT = "2006-01-02T15:04:05"
+ "github.com/beego/beego/v2/server/web/context"
)
// Substr returns the substr from start to length.
@@ -54,15 +49,14 @@ func Substr(s string, start, length int) string {
// HTML2str returns escaping text convert from html.
func HTML2str(html string) string {
-
re := regexp.MustCompile(`\<[\S\s]+?\>`)
html = re.ReplaceAllStringFunc(html, strings.ToLower)
- //remove STYLE
+ // remove STYLE
re = regexp.MustCompile(`\