mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #15769 from grafana/15768_xorm_upgrade
upgrade xorm packages to latest versions
This commit is contained in:
commit
8ba4eb47e7
312
Gopkg.lock
generated
312
Gopkg.lock
generated
@ -2,30 +2,39 @@
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f8ad8a53fa865a70efbe215b0ca34735523f50ea39e0efde319ab6fc80089b44"
|
||||
name = "cloud.google.com/go"
|
||||
packages = ["compute/metadata"]
|
||||
pruneopts = "NUT"
|
||||
revision = "056a55f54a6cc77b440b31a56a5e7c3982d32811"
|
||||
version = "v0.22.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:167b6f65a6656de568092189ae791253939f076df60231fdd64588ac703892a1"
|
||||
name = "github.com/BurntSushi/toml"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "b26d9c308763d68093482582cea63d69be07a0f0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7d23e6e1889b8bb4bbb37a564708fdab4497ce232c3a99d66406c975b642a6ff"
|
||||
name = "github.com/Unknwon/com"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "7677a1d7c1137cd3dd5ba7a076d0c898a1ef4520"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:1610787cd9726e29d8fecc2a80e43e4fced008a1f560fec6688fc4d946f17835"
|
||||
name = "github.com/VividCortex/mysqlerr"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "6c6b55f8796f578c870b7e19bafb16103bc40095"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ebe102b61c1615d2954734e3cfe1b6b06a5088c25a41055b38661d41ad7b8f27"
|
||||
name = "github.com/aws/aws-sdk-go"
|
||||
packages = [
|
||||
"aws",
|
||||
@ -69,399 +78,507 @@
|
||||
"service/resourcegroupstaggingapi",
|
||||
"service/resourcegroupstaggingapi/resourcegroupstaggingapiiface",
|
||||
"service/s3",
|
||||
"service/sts"
|
||||
"service/sts",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "62936e15518acb527a1a9cb4a39d96d94d0fd9a2"
|
||||
version = "v1.16.15"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:79cad073c7be02632d3fa52f62486848b089f560db1e94536de83a408c0f4726"
|
||||
name = "github.com/benbjohnson/clock"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "7dc76406b6d3c05b5f71a86293cbcf3c4ea03b19"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:707ebe952a8b3d00b343c01536c79c73771d100f63ec6babeaed5c79e2b8a8dd"
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
pruneopts = "NUT"
|
||||
revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:433a2ff0ef4e2f8634614aab3174783c5ff80120b487712db96cc3712f409583"
|
||||
name = "github.com/bmizerany/assert"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "b7ed37b82869576c289d7d97fb2bbd8b64a0cb28"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d8f9145c361920507a4f85ffb7f70b96beaedacba2ce8c00aa663adb08689d3e"
|
||||
name = "github.com/bradfitz/gomemcache"
|
||||
packages = ["memcache"]
|
||||
pruneopts = "NUT"
|
||||
revision = "1952afaa557dc08e8e0d89eafab110fb501c1a2b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8ecb89af7dfe3ac401bdb0c9390b134ef96a97e85f732d2b0604fb7b3977839f"
|
||||
name = "github.com/codahale/hdrhistogram"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "3a0bb77429bd3a61596f5e8a3172445844342120"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5dba68a1600a235630e208cb7196b24e58fcbb77bb7a6bec08fcd23f081b0a58"
|
||||
name = "github.com/codegangsta/cli"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1"
|
||||
version = "v1.20.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = "NUT"
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1b318d2dd6cea8a1a8d8ec70348852303bd3e491df74e8bca6e32eb5a4d06970"
|
||||
name = "github.com/denisenkom/go-mssqldb"
|
||||
packages = [
|
||||
".",
|
||||
"internal/cp"
|
||||
"internal/cp",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "270bc3860bb94dd3a3ffd047377d746c5e276726"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:2da5f11ad66ff01a27a5c3dba4620b7eee2327be75b32c9ee9f87c9a8001ecbf"
|
||||
name = "github.com/facebookgo/inject"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "cc1aa653e50f6a9893bcaef89e673e5b24e1e97b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:1108df7f658c90db041e0d6174d55be689aaeb0585913b9c3c7aab51a3a6b2b1"
|
||||
name = "github.com/facebookgo/structtag"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "217e25fb96916cc60332e399c9aa63f5c422ceed"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ade392a843b2035effb4b4a2efa2c3bab3eb29b992e98bacf9c898b0ecb54e45"
|
||||
name = "github.com/fatih/color"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-ini/ini"
|
||||
packages = ["."]
|
||||
revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
|
||||
version = "v1.36.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:682a0aca743a1a4a36697f3d7f86c0ed403c4e3a780db9935f633242855eac9c"
|
||||
name = "github.com/go-macaron/binding"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "ac54ee249c27dca7e76fad851a4a04b73bd1b183"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:6326b27f8e0c8e135c8674ddbc619fae879664ac832e8e6fa6a23ce0d279ed4d"
|
||||
name = "github.com/go-macaron/gzip"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "cad1c6580a07c56f5f6bc52d66002a05985c5854"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:fb8711b648d1ff03104fc1d9593a13cb1d5120be7ba2b01641c14ccae286a9e3"
|
||||
name = "github.com/go-macaron/inject"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "d8a0b8677191f4380287cfebd08e462217bac7ad"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:21577aafe885f088e8086a3415f154c63c0b7ce956a6994df2ac5776bc01b7e3"
|
||||
name = "github.com/go-macaron/session"
|
||||
packages = [
|
||||
".",
|
||||
"memcache",
|
||||
"postgres",
|
||||
"redis"
|
||||
"redis",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "068d408f9c54c7fa7fcc5e2bdd3241ab21280c9e"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:fddd4bada6100d6fc49a9f32f18ba5718db45a58e4b00aa6377e1cfbf06af34f"
|
||||
name = "github.com/go-sql-driver/mysql"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "2cc627ac8defc45d65066ae98f898166f580f9a4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a1efdbc2762667c8a41cbf02b19a0549c846bf2c1d08cad4f445e3344089f1f0"
|
||||
name = "github.com/go-stack/stack"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:06d21295033f211588d0ad7ff391cc1b27e72b60cb6d4b7db0d70cffae4cf228"
|
||||
name = "github.com/go-xorm/builder"
|
||||
packages = ["."]
|
||||
revision = "bad0a612f0d6277b953910822ab5dfb30dd18237"
|
||||
version = "v0.2.0"
|
||||
pruneopts = "NUT"
|
||||
revision = "1d658d7596c25394aab557ef5b50ef35bf706384"
|
||||
version = "v0.3.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b26928aab0fff92592e8728c5bc9d6e404fa2017d6a8e841ae5e60a42237f6fc"
|
||||
name = "github.com/go-xorm/core"
|
||||
packages = ["."]
|
||||
revision = "da1adaf7a28ca792961721a34e6e04945200c890"
|
||||
version = "v0.5.7"
|
||||
pruneopts = "NUT"
|
||||
revision = "ccc80c1adf1f6172bbc548877f50a1163041a40a"
|
||||
version = "v0.6.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:407316703b32d68ccf5d39bdae57d411b6954e253e07d0fff0988a3f39861f2f"
|
||||
name = "github.com/go-xorm/xorm"
|
||||
packages = ["."]
|
||||
revision = "1933dd69e294c0a26c0266637067f24dbb25770c"
|
||||
version = "v0.6.4"
|
||||
pruneopts = "NUT"
|
||||
revision = "1f39c590c64924f358c0d89016ac9b2bb84e9125"
|
||||
version = "v0.7.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ffbb19fb66f140b5ea059428d1f84246a055d1bc3d9456c1e5c3d143611f03d0"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"proto",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/timestamp"
|
||||
"ptypes/timestamp",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "927b65914520a8b7d44f5c9057611cfec6b2e2d0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:f14d1b50e0075fb00177f12a96dd7addf93d1e2883c25befd17285b779549795"
|
||||
name = "github.com/gopherjs/gopherjs"
|
||||
packages = ["js"]
|
||||
pruneopts = "NUT"
|
||||
revision = "8dffc02ea1cb8398bb73f30424697c60fcf8d4c5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3b708ebf63bfa9ba3313bedb8526bc0bb284e51474e65e958481476a9d4a12aa"
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4e771d1c6e15ca4516ad971c34205c822b5cff2747179679d7b321e4e1bfe431"
|
||||
name = "github.com/gosimple/slug"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "e9f42fa127660e552d0ad2b589868d403a9be7c6"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:08e53c69cd267ef7d71eeae5d953153d0d2bc1b8e0b498731fe9acaead7001b6"
|
||||
name = "github.com/grafana/grafana-plugin-model"
|
||||
packages = [
|
||||
"go/datasource",
|
||||
"go/renderer"
|
||||
"go/renderer",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "84176c64269d8060f99e750ee8aba6f062753336"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:58ba5285227b0f635652cd4aa82c4cfd00b590191eadd823462f0c9f64e3ae07"
|
||||
name = "github.com/hashicorp/go-hclog"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "69ff559dc25f3b435631604f573a5fa1efdb6433"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:532090ffc3b05a7e4c0229dd2698d79149f2e0683df993224a8b202f607fb605"
|
||||
name = "github.com/hashicorp/go-plugin"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "e8d22c780116115ae5624720c9af0c97afe4f551"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8925116d1edcd85fc0c014e1aa69ce12892489b48ee633a605c46d893b8c151f"
|
||||
name = "github.com/hashicorp/go-version"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "23480c0665776210b5fbbac6eaaee40e3e6a96b7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8deb0c5545c824dfeb0ac77ab8eb67a3d541eab76df5c85ce93064ef02d44cd0"
|
||||
name = "github.com/hashicorp/yamux"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "7221087c3d281fda5f794e28c2ea4c6e4d5c4558"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:efbe016b6d198cf44f1db0ed2fbdf1b36ebf1f6956cc9b76d6affa96f022d368"
|
||||
name = "github.com/inconshreveable/log15"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "0decfc6c20d9ca0ad143b0e89dcaa20f810b4fb3"
|
||||
version = "v2.13"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1f2aebae7e7c856562355ec0198d8ca2fa222fb05e5b1b66632a1fce39631885"
|
||||
name = "github.com/jmespath/go-jmespath"
|
||||
packages = ["."]
|
||||
revision = "0b12d6b5"
|
||||
pruneopts = "NUT"
|
||||
revision = "c2b33e84"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6ddab442e52381bab82fb6c07ef3f4b565ff7ec4b8fae96d8dd4b8573a460597"
|
||||
name = "github.com/jtolds/gls"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "77f18212c9c7edc9bd6a33d383a7b545ce62f064"
|
||||
version = "v4.2.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1da1796a71eb70f1e3e085984d044f67840bb0326816ec8276231aa87b1b9fc3"
|
||||
name = "github.com/klauspost/compress"
|
||||
packages = [
|
||||
"flate",
|
||||
"gzip"
|
||||
"gzip",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "6c8db69c4b49dd4df1fff66996cf556176d0b9bf"
|
||||
version = "v1.2.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5e55a8699c9ff7aba1e4c8952aeda209685d88d4cb63a8766c338e333b8e65d6"
|
||||
name = "github.com/klauspost/cpuid"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "ae7887de9fa5d2db4eaa8174a7eff2c1ac00f2da"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b95da1293525625ef6f07be79d537b9bf2ecd7901efcf9a92193edafbd55b9ef"
|
||||
name = "github.com/klauspost/crc32"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "cb6bfca970f6908083f26f39a79009d608efd5cd"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7b21c7fc5551b46d1308b4ffa9e9e49b66c7a8b0ba88c0130474b0e7a20d859f"
|
||||
name = "github.com/kr/pretty"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "73f6ac0b30a98e433b289500d779f50c1a6f0712"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c3a7836b5904db0f8b609595b619916a6831cb35b8b714aec39f96d00c6155d8"
|
||||
name = "github.com/kr/text"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "e2ffdb16a802fe2bb95e2e35ff34f0e53aeef34f"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7a1e592f0349d56fac8ce47f28469e4e7f4ce637cb26f40c88da9dff25db1c98"
|
||||
name = "github.com/lib/pq"
|
||||
packages = [
|
||||
".",
|
||||
"oid"
|
||||
"oid",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "d34b9ff171c21ad295489235aec8b6626023cd04"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:08c231ec84231a7e23d67e4b58f975e1423695a32467a362ee55a803f9de8061"
|
||||
name = "github.com/mattn/go-colorable"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
|
||||
version = "v0.0.9"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bc4f7eec3b7be8c6cb1f0af6c1e3333d5bb71072951aaaae2f05067b0803f287"
|
||||
name = "github.com/mattn/go-isatty"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:536979f1c56397dbf91c2785159b37dec37e35d3bffa3cd1cfe66d25f51f8088"
|
||||
name = "github.com/mattn/go-sqlite3"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "323a32be5a2421b8c7087225079c6c900ec397cd"
|
||||
version = "v1.7.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5985ef4caf91ece5d54817c11ea25f182697534f8ae6521eadcd628c142ac4b6"
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
pruneopts = "NUT"
|
||||
revision = "3247c84500bff8d9fb6d579d800f20b3e091582c"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:18b773b92ac82a451c1276bd2776c1e55ce057ee202691ab33c8d6690efcc048"
|
||||
name = "github.com/mitchellh/go-testing-interface"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "a61a99592b77c9ba629d254a693acffaeb4b7e28"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3b517122f3aad1ecce45a630ea912b3092b4729f25532a911d0cb2935a1f9352"
|
||||
name = "github.com/oklog/run"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "4dadeb3030eda0273a12382bb2348ffc7c9d1a39"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7da29c22bcc5c2ffb308324377dc00b5084650348c2799e573ed226d8cc9faf0"
|
||||
name = "github.com/opentracing/opentracing-go"
|
||||
packages = [
|
||||
".",
|
||||
"ext",
|
||||
"log"
|
||||
"log",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:748946761cf99c8b73cef5a3c0ee3e040859dd713a20cece0d0e0dc04e6ceca7"
|
||||
name = "github.com/patrickmn/go-cache"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "a3647f8e31d79543b2d0f0ae2fe5c379d72cedc0"
|
||||
version = "v2.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4759bed95e3a52febc18c071db28790a5c6e9e106ee201a37add6f6a056f8f9c"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"api",
|
||||
"api/prometheus/v1",
|
||||
"prometheus",
|
||||
"prometheus/promhttp"
|
||||
"prometheus/promhttp",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "967789050ba94deca04a5e84cce8ad472ce313c1"
|
||||
version = "v0.9.0-pre1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:32d10bdfa8f09ecf13598324dba86ab891f11db3c538b6a34d1c3b5b99d7c36b"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
pruneopts = "NUT"
|
||||
revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:768b555b86742de2f28beb37f1dedce9a75f91f871d75b5717c96399c1a78c08"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
"internal/bitbucket.org/ww/goautoneg",
|
||||
"model"
|
||||
"model",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "d811d2e9bf898806ecfb6ef6296774b13ffc314c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:c4a213a8d73fbb0b13f717ba7996116602ef18ecb42b91d77405877914cb0349"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
"internal/util",
|
||||
"nfs",
|
||||
"xfs"
|
||||
"xfs",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "8b1c2da0d56deffdbb9e48d4414b4e674bd8083e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:16e2136a67ec44aa2d1d6b0fd65394b3c4a8b2a1b6730c77967f7b7b06b179b2"
|
||||
name = "github.com/rainycape/unidecode"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "cb7f23ec59bec0d61b19c56cd88cee3d0cc1870c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04"
|
||||
name = "github.com/sergi/go-diff"
|
||||
packages = ["diffmatchpatch"]
|
||||
pruneopts = "NUT"
|
||||
revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1f0b284a6858827de4c27c66b49b2b25df3e16b031c2b57b7892273131e7dd2b"
|
||||
name = "github.com/smartystreets/assertions"
|
||||
packages = [
|
||||
".",
|
||||
"internal/go-render/render",
|
||||
"internal/oglematchers"
|
||||
"internal/oglematchers",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "7678a5452ebea5b7090a6b163f844c133f523da2"
|
||||
version = "1.8.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7efd0b2309cdd6468029fa30c808c50a820c9344df07e1a4bbdaf18f282907aa"
|
||||
name = "github.com/smartystreets/goconvey"
|
||||
packages = [
|
||||
"convey",
|
||||
"convey/gotest",
|
||||
"convey/reporting"
|
||||
"convey/reporting",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "9e8dc3f972df6c8fcc0375ef492c24d0bb204857"
|
||||
version = "1.6.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a66add8dd963bfc72649017c1b321198f596cb4958cb1a11ff91a1be8691020b"
|
||||
name = "github.com/teris-io/shortid"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "771a37caa5cf0c81f585d7b6df4dfc77e0615b5c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3d48c38e0eca8c66df62379c5ae7a83fb5cd839b94f241354c07ba077da7bc45"
|
||||
name = "github.com/uber/jaeger-client-go"
|
||||
packages = [
|
||||
".",
|
||||
@ -479,45 +596,55 @@
|
||||
"thrift-gen/jaeger",
|
||||
"thrift-gen/sampling",
|
||||
"thrift-gen/zipkincore",
|
||||
"utils"
|
||||
"utils",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b043381d944715b469fd6b37addfd30145ca1758"
|
||||
version = "v2.14.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0f09db8429e19d57c8346ad76fbbc679341fa86073d3b8fb5ac919f0357d8f4c"
|
||||
name = "github.com/uber/jaeger-lib"
|
||||
packages = ["metrics"]
|
||||
pruneopts = "NUT"
|
||||
revision = "ed3a127ec5fef7ae9ea95b01b542c47fbd999ce5"
|
||||
version = "v1.5.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4c7d12ad3ef47bb03892a52e2609dc9a9cff93136ca9c7d31c00b79fcbc23c7b"
|
||||
name = "github.com/yudai/gojsondiff"
|
||||
packages = [
|
||||
".",
|
||||
"formatter"
|
||||
"formatter",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "7b1b7adf999dab73a6eb02669c3d82dbb27a3dd6"
|
||||
version = "1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e50cbf8eba568d59b71e08c22c2a77809ed4646ae06ef4abb32b3d3d3fdb1a77"
|
||||
name = "github.com/yudai/golcs"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:758f363e0dff33cf00b234be2efb12f919d79b42d5ae3909ff9eb69ef2c3cca5"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"ed25519",
|
||||
"ed25519/internal/edwards25519",
|
||||
"md4",
|
||||
"pbkdf2"
|
||||
"pbkdf2",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1a580b3eff7814fc9b40602fd35256c63b50f491"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:0b3fee9c4472022a0982ee0d81e08b3cc3e595f50befd7a4b358b48540d9d8c5"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
@ -527,35 +654,43 @@
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"internal/timeseries",
|
||||
"trace"
|
||||
"trace",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "2491c5de3490fced2f6cff376127c667efeed857"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:46bd4e66bfce5e77f08fc2e8dcacc3676e679241ce83d9c150ff0397d686dd44"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"google",
|
||||
"internal",
|
||||
"jws",
|
||||
"jwt"
|
||||
"jwt",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "cdc340f7c179dbbfa4afd43b7614e8fcadde4269"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:39ebcc2b11457b703ae9ee2e8cca0f68df21969c6102cb3b705f76cca0ea0239"
|
||||
name = "golang.org/x/sync"
|
||||
packages = ["errgroup"]
|
||||
pruneopts = "NUT"
|
||||
revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ec21c5bf0572488865b93e30ffd9132afbf85bec0b20c2d6cbcf349cf2031ed5"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
pruneopts = "NUT"
|
||||
revision = "7c87d13f8e835d2fb3a70a2912c811ed0c1d241b"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e7071ed636b5422cc51c0e3a6cebc229d6c9fffc528814b519a980641422d619"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
@ -571,12 +706,14 @@
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable"
|
||||
"unicode/rangetable",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:dbd5568923513ee74aa626d027e2a8a352cf8f35df41d19f4e34491d1858c38b"
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
".",
|
||||
@ -589,18 +726,22 @@
|
||||
"internal/modules",
|
||||
"internal/remote_api",
|
||||
"internal/urlfetch",
|
||||
"urlfetch"
|
||||
"urlfetch",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:3c24554c312721e98fa6b76403e7100cf974eb46b1255ea7fc6471db9a9ce498"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
pruneopts = "NUT"
|
||||
revision = "7bb2a897381c9c5ab2aeb8614f758d7766af68ff"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:840b77b6eb539b830bb760b6e30b688ed2ff484bd83466fce2395835ed9367fe"
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
@ -627,78 +768,177 @@
|
||||
"stats",
|
||||
"status",
|
||||
"tap",
|
||||
"transport"
|
||||
"transport",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1e2570b1b19ade82d8dbb31bba4e65e9f9ef5b34"
|
||||
version = "v1.11.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "v3"
|
||||
digest = "1:1244a9b3856f70d5ffb74bbfd780fc9d47f93f2049fa265c6fb602878f507bf8"
|
||||
name = "gopkg.in/alexcesaro/quotedprintable.v3"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "2caba252f4dc53eaf6b553000885530023f54623"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:aea6e9483c167cc6fdf1274c442558c5dda8fd3373372be04d98c79100868da1"
|
||||
name = "gopkg.in/asn1-ber.v1"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "379148ca0225df7a432012b8df0355c2a2063ac0"
|
||||
version = "v1.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:24bfc2e8bf971485cb5ba0f0e5b08a1b806cca5828134df76b32d1ea50f2ab49"
|
||||
name = "gopkg.in/bufio.v1"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "567b2bfa514e796916c4747494d6ff5132a1dfce"
|
||||
version = "v1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e05711632e1515319b014e8fe4cbe1d30ab024c473403f60cf0fdeb4c586a474"
|
||||
name = "gopkg.in/ini.v1"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "6529cf7c58879c08d927016dde4477f18a0634cb"
|
||||
version = "v1.36.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c847b7fea4c7e6db5281a37dffc4620cb78c1227403a79e5aa290db517657ac1"
|
||||
name = "gopkg.in/ldap.v3"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "5c2c0f997205c29de14cb6c35996370c2c5dfab1"
|
||||
version = "v3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3b0cf3a465fd07f76e5fc1a9d0783c662dac0de9fc73d713ebe162768fd87b5f"
|
||||
name = "gopkg.in/macaron.v1"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "c1be95e6d21e769e44e1ec33cec9da5837861c10"
|
||||
version = "v1.3.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
digest = "1:d52332f9e9f2c6343652e13aa3fd40cfd03353520c9a48d90f21215d3012d50f"
|
||||
name = "gopkg.in/mail.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "5bc5c8bb07bd8d2803831fbaf8cbd630fcde2c68"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:00126f697efdcab42f07c89ac8bf0095fb2328aef6464e070055154088cea859"
|
||||
name = "gopkg.in/redis.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "e6179049628164864e6e84e973cfb56335748dea"
|
||||
version = "v2.3.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a50fabe7a46692dc7c656310add3d517abe7914df02afd151ef84da884605dc8"
|
||||
name = "gopkg.in/square/go-jose.v2"
|
||||
packages = [
|
||||
".",
|
||||
"cipher",
|
||||
"json"
|
||||
"json",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "ef984e69dd356202fd4e4910d4d9c24468bdf0b8"
|
||||
version = "v2.1.9"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "88f0eb826b9c154ba46ea3bb64767707d86db75449ec75199eb2b8cf2b337fd4"
|
||||
input-imports = [
|
||||
"github.com/BurntSushi/toml",
|
||||
"github.com/Unknwon/com",
|
||||
"github.com/VividCortex/mysqlerr",
|
||||
"github.com/aws/aws-sdk-go/aws",
|
||||
"github.com/aws/aws-sdk-go/aws/awserr",
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil",
|
||||
"github.com/aws/aws-sdk-go/aws/credentials",
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
|
||||
"github.com/aws/aws-sdk-go/aws/defaults",
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata",
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints",
|
||||
"github.com/aws/aws-sdk-go/aws/request",
|
||||
"github.com/aws/aws-sdk-go/aws/session",
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch",
|
||||
"github.com/aws/aws-sdk-go/service/ec2",
|
||||
"github.com/aws/aws-sdk-go/service/ec2/ec2iface",
|
||||
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi",
|
||||
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface",
|
||||
"github.com/aws/aws-sdk-go/service/s3",
|
||||
"github.com/aws/aws-sdk-go/service/sts",
|
||||
"github.com/benbjohnson/clock",
|
||||
"github.com/bmizerany/assert",
|
||||
"github.com/codegangsta/cli",
|
||||
"github.com/davecgh/go-spew/spew",
|
||||
"github.com/denisenkom/go-mssqldb",
|
||||
"github.com/facebookgo/inject",
|
||||
"github.com/fatih/color",
|
||||
"github.com/go-macaron/binding",
|
||||
"github.com/go-macaron/gzip",
|
||||
"github.com/go-macaron/session",
|
||||
"github.com/go-macaron/session/memcache",
|
||||
"github.com/go-macaron/session/postgres",
|
||||
"github.com/go-macaron/session/redis",
|
||||
"github.com/go-sql-driver/mysql",
|
||||
"github.com/go-stack/stack",
|
||||
"github.com/go-xorm/core",
|
||||
"github.com/go-xorm/xorm",
|
||||
"github.com/gorilla/websocket",
|
||||
"github.com/gosimple/slug",
|
||||
"github.com/grafana/grafana-plugin-model/go/datasource",
|
||||
"github.com/grafana/grafana-plugin-model/go/renderer",
|
||||
"github.com/hashicorp/go-hclog",
|
||||
"github.com/hashicorp/go-plugin",
|
||||
"github.com/hashicorp/go-version",
|
||||
"github.com/inconshreveable/log15",
|
||||
"github.com/lib/pq",
|
||||
"github.com/mattn/go-isatty",
|
||||
"github.com/mattn/go-sqlite3",
|
||||
"github.com/opentracing/opentracing-go",
|
||||
"github.com/opentracing/opentracing-go/ext",
|
||||
"github.com/opentracing/opentracing-go/log",
|
||||
"github.com/patrickmn/go-cache",
|
||||
"github.com/pkg/errors",
|
||||
"github.com/prometheus/client_golang/api",
|
||||
"github.com/prometheus/client_golang/api/prometheus/v1",
|
||||
"github.com/prometheus/client_golang/prometheus",
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp",
|
||||
"github.com/prometheus/client_model/go",
|
||||
"github.com/prometheus/common/expfmt",
|
||||
"github.com/prometheus/common/model",
|
||||
"github.com/smartystreets/goconvey/convey",
|
||||
"github.com/teris-io/shortid",
|
||||
"github.com/uber/jaeger-client-go/config",
|
||||
"github.com/yudai/gojsondiff",
|
||||
"github.com/yudai/gojsondiff/formatter",
|
||||
"golang.org/x/net/context/ctxhttp",
|
||||
"golang.org/x/oauth2",
|
||||
"golang.org/x/oauth2/google",
|
||||
"golang.org/x/oauth2/jwt",
|
||||
"golang.org/x/sync/errgroup",
|
||||
"gopkg.in/ini.v1",
|
||||
"gopkg.in/ldap.v3",
|
||||
"gopkg.in/macaron.v1",
|
||||
"gopkg.in/mail.v2",
|
||||
"gopkg.in/square/go-jose.v2",
|
||||
"gopkg.in/yaml.v2",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
@ -81,11 +81,15 @@ ignored = [
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-xorm/core"
|
||||
version = "=0.5.7"
|
||||
version = "=0.6.2"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/go-xorm/builder"
|
||||
version = "=0.3.4"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-xorm/xorm"
|
||||
version = "=0.6.4"
|
||||
version = "=0.7.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
|
@ -309,7 +309,9 @@ func PauseAlert(cmd *m.PauseAlertCommand) error {
|
||||
params = append(params, v)
|
||||
}
|
||||
|
||||
res, err := sess.Exec(buffer.String(), params...)
|
||||
sqlOrArgs := append([]interface{}{buffer.String()}, params...)
|
||||
|
||||
res, err := sess.Exec(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -258,11 +258,15 @@ func (r *SqlAnnotationRepo) Delete(params *annotations.DeleteParams) error {
|
||||
queryParams = []interface{}{params.DashboardId, params.PanelId, params.OrgId}
|
||||
}
|
||||
|
||||
if _, err := sess.Exec(annoTagSql, queryParams...); err != nil {
|
||||
sqlOrArgs := append([]interface{}{annoTagSql}, queryParams...)
|
||||
|
||||
if _, err := sess.Exec(sqlOrArgs...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := sess.Exec(sql, queryParams...); err != nil {
|
||||
sqlOrArgs = append([]interface{}{sql}, queryParams...)
|
||||
|
||||
if _, err := sess.Exec(sqlOrArgs...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ func GetDashboardVersions(query *m.GetDashboardVersionsQuery) error {
|
||||
dashboard_version.message,
|
||||
dashboard_version.data,`+
|
||||
dialect.Quote("user")+`.login as created_by`).
|
||||
Join("LEFT", "user", `dashboard_version.created_by = `+dialect.Quote("user")+`.id`).
|
||||
Join("LEFT", dialect.Quote("user"), `dashboard_version.created_by = `+dialect.Quote("user")+`.id`).
|
||||
Join("LEFT", "dashboard", `dashboard.id = dashboard_version.dashboard_id`).
|
||||
Where("dashboard_version.dashboard_id=? AND dashboard.org_id=?", query.DashboardId, query.OrgId).
|
||||
OrderBy("dashboard_version.version DESC").
|
||||
@ -102,7 +102,8 @@ func DeleteExpiredVersions(cmd *m.DeleteExpiredVersionsCommand) error {
|
||||
|
||||
if len(versionIdsToDelete) > 0 {
|
||||
deleteExpiredSql := `DELETE FROM dashboard_version WHERE id IN (?` + strings.Repeat(",?", len(versionIdsToDelete)-1) + `)`
|
||||
expiredResponse, err := sess.Exec(deleteExpiredSql, versionIdsToDelete...)
|
||||
sqlOrArgs := append([]interface{}{deleteExpiredSql}, versionIdsToDelete...)
|
||||
expiredResponse, err := sess.Exec(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ func GetOrgUsers(query *m.GetOrgUsersQuery) error {
|
||||
query.Result = make([]*m.OrgUserDTO, 0)
|
||||
|
||||
sess := x.Table("org_user")
|
||||
sess.Join("INNER", "user", fmt.Sprintf("org_user.user_id=%s.id", x.Dialect().Quote("user")))
|
||||
sess.Join("INNER", x.Dialect().Quote("user"), fmt.Sprintf("org_user.user_id=%s.id", x.Dialect().Quote("user")))
|
||||
|
||||
whereConditions := make([]string, 0)
|
||||
whereParams := make([]interface{}, 0)
|
||||
|
@ -280,7 +280,7 @@ func RemoveTeamMember(cmd *m.RemoveTeamMemberCommand) error {
|
||||
func GetTeamMembers(query *m.GetTeamMembersQuery) error {
|
||||
query.Result = make([]*m.TeamMemberDTO, 0)
|
||||
sess := x.Table("team_member")
|
||||
sess.Join("INNER", "user", fmt.Sprintf("team_member.user_id=%s.id", x.Dialect().Quote("user")))
|
||||
sess.Join("INNER", x.Dialect().Quote("user"), fmt.Sprintf("team_member.user_id=%s.id", x.Dialect().Quote("user")))
|
||||
if query.OrgId != 0 {
|
||||
sess.Where("team_member.org_id=?", query.OrgId)
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ func TestUserDataAccess(t *testing.T) {
|
||||
func GetOrgUsersForTest(query *m.GetOrgUsersQuery) error {
|
||||
query.Result = make([]*m.OrgUserDTO, 0)
|
||||
sess := x.Table("org_user")
|
||||
sess.Join("LEFT ", "user", fmt.Sprintf("org_user.user_id=%s.id", x.Dialect().Quote("user")))
|
||||
sess.Join("LEFT ", x.Dialect().Quote("user"), fmt.Sprintf("org_user.user_id=%s.id", x.Dialect().Quote("user")))
|
||||
sess.Where("org_user.org_id=?", query.OrgId)
|
||||
sess.Cols("org_user.org_id", "org_user.user_id", "user.email", "user.login", "org_user.role")
|
||||
|
||||
|
191
vendor/github.com/go-ini/ini/LICENSE
generated
vendored
191
vendor/github.com/go-ini/ini/LICENSE
generated
vendored
@ -1,191 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, "control" means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object code,
|
||||
generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||
available under the License, as indicated by a copyright notice that is included
|
||||
in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative Works
|
||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||
on behalf of the copyright owner. For the purposes of this definition,
|
||||
"submitted" means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||
the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such Contributor
|
||||
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If You institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||
Contribution incorporated within the Work constitutes direct or contributory
|
||||
patent infringement, then any patent licenses granted to You under this License
|
||||
for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution.
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||
in any medium, with or without modifications, and in Source or Object form,
|
||||
provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source form
|
||||
of the Work, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||
identifying information. (Don't include the brackets!) The text should be
|
||||
enclosed in the appropriate comment syntax for the file format. We also
|
||||
recommend that a file or class name and description of purpose be included on
|
||||
the same "printed page" as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright 2014 Unknwon
|
||||
|
||||
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.
|
32
vendor/github.com/go-ini/ini/error.go
generated
vendored
32
vendor/github.com/go-ini/ini/error.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
// Copyright 2016 Unknwon
|
||||
//
|
||||
// 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 ini
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ErrDelimiterNotFound struct {
|
||||
Line string
|
||||
}
|
||||
|
||||
func IsErrDelimiterNotFound(err error) bool {
|
||||
_, ok := err.(ErrDelimiterNotFound)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrDelimiterNotFound) Error() string {
|
||||
return fmt.Sprintf("key-value delimiter not found: %s", err.Line)
|
||||
}
|
407
vendor/github.com/go-ini/ini/file.go
generated
vendored
407
vendor/github.com/go-ini/ini/file.go
generated
vendored
@ -1,407 +0,0 @@
|
||||
// Copyright 2017 Unknwon
|
||||
//
|
||||
// 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 ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// File represents a combination of a or more INI file(s) in memory.
|
||||
type File struct {
|
||||
options LoadOptions
|
||||
dataSources []dataSource
|
||||
|
||||
// Should make things safe, but sometimes doesn't matter.
|
||||
BlockMode bool
|
||||
lock sync.RWMutex
|
||||
|
||||
// To keep data in order.
|
||||
sectionList []string
|
||||
// Actual data is stored here.
|
||||
sections map[string]*Section
|
||||
|
||||
NameMapper
|
||||
ValueMapper
|
||||
}
|
||||
|
||||
// newFile initializes File object with given data sources.
|
||||
func newFile(dataSources []dataSource, opts LoadOptions) *File {
|
||||
return &File{
|
||||
BlockMode: true,
|
||||
dataSources: dataSources,
|
||||
sections: make(map[string]*Section),
|
||||
sectionList: make([]string, 0, 10),
|
||||
options: opts,
|
||||
}
|
||||
}
|
||||
|
||||
// Empty returns an empty file object.
|
||||
func Empty() *File {
|
||||
// Ignore error here, we sure our data is good.
|
||||
f, _ := Load([]byte(""))
|
||||
return f
|
||||
}
|
||||
|
||||
// NewSection creates a new section.
|
||||
func (f *File) NewSection(name string) (*Section, error) {
|
||||
if len(name) == 0 {
|
||||
return nil, errors.New("error creating new section: empty section name")
|
||||
} else if f.options.Insensitive && name != DEFAULT_SECTION {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
|
||||
if f.BlockMode {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
}
|
||||
|
||||
if inSlice(name, f.sectionList) {
|
||||
return f.sections[name], nil
|
||||
}
|
||||
|
||||
f.sectionList = append(f.sectionList, name)
|
||||
f.sections[name] = newSection(f, name)
|
||||
return f.sections[name], nil
|
||||
}
|
||||
|
||||
// NewRawSection creates a new section with an unparseable body.
|
||||
func (f *File) NewRawSection(name, body string) (*Section, error) {
|
||||
section, err := f.NewSection(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
section.isRawSection = true
|
||||
section.rawBody = body
|
||||
return section, nil
|
||||
}
|
||||
|
||||
// NewSections creates a list of sections.
|
||||
func (f *File) NewSections(names ...string) (err error) {
|
||||
for _, name := range names {
|
||||
if _, err = f.NewSection(name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSection returns section by given name.
|
||||
func (f *File) GetSection(name string) (*Section, error) {
|
||||
if len(name) == 0 {
|
||||
name = DEFAULT_SECTION
|
||||
}
|
||||
if f.options.Insensitive {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
|
||||
if f.BlockMode {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
}
|
||||
|
||||
sec := f.sections[name]
|
||||
if sec == nil {
|
||||
return nil, fmt.Errorf("section '%s' does not exist", name)
|
||||
}
|
||||
return sec, nil
|
||||
}
|
||||
|
||||
// Section assumes named section exists and returns a zero-value when not.
|
||||
func (f *File) Section(name string) *Section {
|
||||
sec, err := f.GetSection(name)
|
||||
if err != nil {
|
||||
// Note: It's OK here because the only possible error is empty section name,
|
||||
// but if it's empty, this piece of code won't be executed.
|
||||
sec, _ = f.NewSection(name)
|
||||
return sec
|
||||
}
|
||||
return sec
|
||||
}
|
||||
|
||||
// Section returns list of Section.
|
||||
func (f *File) Sections() []*Section {
|
||||
if f.BlockMode {
|
||||
f.lock.RLock()
|
||||
defer f.lock.RUnlock()
|
||||
}
|
||||
|
||||
sections := make([]*Section, len(f.sectionList))
|
||||
for i, name := range f.sectionList {
|
||||
sections[i] = f.sections[name]
|
||||
}
|
||||
return sections
|
||||
}
|
||||
|
||||
// ChildSections returns a list of child sections of given section name.
|
||||
func (f *File) ChildSections(name string) []*Section {
|
||||
return f.Section(name).ChildSections()
|
||||
}
|
||||
|
||||
// SectionStrings returns list of section names.
|
||||
func (f *File) SectionStrings() []string {
|
||||
list := make([]string, len(f.sectionList))
|
||||
copy(list, f.sectionList)
|
||||
return list
|
||||
}
|
||||
|
||||
// DeleteSection deletes a section.
|
||||
func (f *File) DeleteSection(name string) {
|
||||
if f.BlockMode {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
}
|
||||
|
||||
if len(name) == 0 {
|
||||
name = DEFAULT_SECTION
|
||||
}
|
||||
|
||||
for i, s := range f.sectionList {
|
||||
if s == name {
|
||||
f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...)
|
||||
delete(f.sections, name)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *File) reload(s dataSource) error {
|
||||
r, err := s.ReadCloser()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
return f.parse(r)
|
||||
}
|
||||
|
||||
// Reload reloads and parses all data sources.
|
||||
func (f *File) Reload() (err error) {
|
||||
for _, s := range f.dataSources {
|
||||
if err = f.reload(s); err != nil {
|
||||
// In loose mode, we create an empty default section for nonexistent files.
|
||||
if os.IsNotExist(err) && f.options.Loose {
|
||||
f.parse(bytes.NewBuffer(nil))
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Append appends one or more data sources and reloads automatically.
|
||||
func (f *File) Append(source interface{}, others ...interface{}) error {
|
||||
ds, err := parseDataSource(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.dataSources = append(f.dataSources, ds)
|
||||
for _, s := range others {
|
||||
ds, err = parseDataSource(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.dataSources = append(f.dataSources, ds)
|
||||
}
|
||||
return f.Reload()
|
||||
}
|
||||
|
||||
func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
|
||||
equalSign := "="
|
||||
if PrettyFormat || PrettyEqual {
|
||||
equalSign = " = "
|
||||
}
|
||||
|
||||
// Use buffer to make sure target is safe until finish encoding.
|
||||
buf := bytes.NewBuffer(nil)
|
||||
for i, sname := range f.sectionList {
|
||||
sec := f.Section(sname)
|
||||
if len(sec.Comment) > 0 {
|
||||
if sec.Comment[0] != '#' && sec.Comment[0] != ';' {
|
||||
sec.Comment = "; " + sec.Comment
|
||||
} else {
|
||||
sec.Comment = sec.Comment[:1] + " " + strings.TrimSpace(sec.Comment[1:])
|
||||
}
|
||||
if _, err := buf.WriteString(sec.Comment + LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if i > 0 || DefaultHeader {
|
||||
if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// Write nothing if default section is empty
|
||||
if len(sec.keyList) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if sec.isRawSection {
|
||||
if _, err := buf.WriteString(sec.rawBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if PrettySection {
|
||||
// Put a line between sections
|
||||
if _, err := buf.WriteString(LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Count and generate alignment length and buffer spaces using the
|
||||
// longest key. Keys may be modifed if they contain certain characters so
|
||||
// we need to take that into account in our calculation.
|
||||
alignLength := 0
|
||||
if PrettyFormat {
|
||||
for _, kname := range sec.keyList {
|
||||
keyLength := len(kname)
|
||||
// First case will surround key by ` and second by """
|
||||
if strings.ContainsAny(kname, "\"=:") {
|
||||
keyLength += 2
|
||||
} else if strings.Contains(kname, "`") {
|
||||
keyLength += 6
|
||||
}
|
||||
|
||||
if keyLength > alignLength {
|
||||
alignLength = keyLength
|
||||
}
|
||||
}
|
||||
}
|
||||
alignSpaces := bytes.Repeat([]byte(" "), alignLength)
|
||||
|
||||
KEY_LIST:
|
||||
for _, kname := range sec.keyList {
|
||||
key := sec.Key(kname)
|
||||
if len(key.Comment) > 0 {
|
||||
if len(indent) > 0 && sname != DEFAULT_SECTION {
|
||||
buf.WriteString(indent)
|
||||
}
|
||||
if key.Comment[0] != '#' && key.Comment[0] != ';' {
|
||||
key.Comment = "; " + key.Comment
|
||||
} else {
|
||||
key.Comment = key.Comment[:1] + " " + strings.TrimSpace(key.Comment[1:])
|
||||
}
|
||||
|
||||
// Support multiline comments
|
||||
key.Comment = strings.Replace(key.Comment, "\n", "\n; ", -1)
|
||||
|
||||
if _, err := buf.WriteString(key.Comment + LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(indent) > 0 && sname != DEFAULT_SECTION {
|
||||
buf.WriteString(indent)
|
||||
}
|
||||
|
||||
switch {
|
||||
case key.isAutoIncrement:
|
||||
kname = "-"
|
||||
case strings.ContainsAny(kname, "\"=:"):
|
||||
kname = "`" + kname + "`"
|
||||
case strings.Contains(kname, "`"):
|
||||
kname = `"""` + kname + `"""`
|
||||
}
|
||||
|
||||
for _, val := range key.ValueWithShadows() {
|
||||
if _, err := buf.WriteString(kname); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if key.isBooleanType {
|
||||
if kname != sec.keyList[len(sec.keyList)-1] {
|
||||
buf.WriteString(LineBreak)
|
||||
}
|
||||
continue KEY_LIST
|
||||
}
|
||||
|
||||
// Write out alignment spaces before "=" sign
|
||||
if PrettyFormat {
|
||||
buf.Write(alignSpaces[:alignLength-len(kname)])
|
||||
}
|
||||
|
||||
// In case key value contains "\n", "`", "\"", "#" or ";"
|
||||
if strings.ContainsAny(val, "\n`") {
|
||||
val = `"""` + val + `"""`
|
||||
} else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") {
|
||||
val = "`" + val + "`"
|
||||
}
|
||||
if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, val := range key.nestedValues {
|
||||
if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if PrettySection {
|
||||
// Put a line between sections
|
||||
if _, err := buf.WriteString(LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// WriteToIndent writes content into io.Writer with given indention.
|
||||
// If PrettyFormat has been set to be true,
|
||||
// it will align "=" sign with spaces under each section.
|
||||
func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) {
|
||||
buf, err := f.writeToBuffer(indent)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return buf.WriteTo(w)
|
||||
}
|
||||
|
||||
// WriteTo writes file content into io.Writer.
|
||||
func (f *File) WriteTo(w io.Writer) (int64, error) {
|
||||
return f.WriteToIndent(w, "")
|
||||
}
|
||||
|
||||
// SaveToIndent writes content to file system with given value indention.
|
||||
func (f *File) SaveToIndent(filename, indent string) error {
|
||||
// Note: Because we are truncating with os.Create,
|
||||
// so it's safer to save to a temporary file location and rename afte done.
|
||||
buf, err := f.writeToBuffer(indent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(filename, buf.Bytes(), 0666)
|
||||
}
|
||||
|
||||
// SaveTo writes content to file system.
|
||||
func (f *File) SaveTo(filename string) error {
|
||||
return f.SaveToIndent(filename, "")
|
||||
}
|
202
vendor/github.com/go-ini/ini/ini.go
generated
vendored
202
vendor/github.com/go-ini/ini/ini.go
generated
vendored
@ -1,202 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// 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 ini provides INI file read and write functionality in Go.
|
||||
package ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
// Name for default section. You can use this constant or the string literal.
|
||||
// In most of cases, an empty string is all you need to access the section.
|
||||
DEFAULT_SECTION = "DEFAULT"
|
||||
|
||||
// Maximum allowed depth when recursively substituing variable names.
|
||||
_DEPTH_VALUES = 99
|
||||
_VERSION = "1.36.0"
|
||||
)
|
||||
|
||||
// Version returns current package version literal.
|
||||
func Version() string {
|
||||
return _VERSION
|
||||
}
|
||||
|
||||
var (
|
||||
// Delimiter to determine or compose a new line.
|
||||
// This variable will be changed to "\r\n" automatically on Windows
|
||||
// at package init time.
|
||||
LineBreak = "\n"
|
||||
|
||||
// Variable regexp pattern: %(variable)s
|
||||
varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`)
|
||||
|
||||
// Indicate whether to align "=" sign with spaces to produce pretty output
|
||||
// or reduce all possible spaces for compact format.
|
||||
PrettyFormat = true
|
||||
|
||||
// Place spaces around "=" sign even when PrettyFormat is false
|
||||
PrettyEqual = false
|
||||
|
||||
// Explicitly write DEFAULT section header
|
||||
DefaultHeader = false
|
||||
|
||||
// Indicate whether to put a line between sections
|
||||
PrettySection = true
|
||||
)
|
||||
|
||||
func init() {
|
||||
if runtime.GOOS == "windows" {
|
||||
LineBreak = "\r\n"
|
||||
}
|
||||
}
|
||||
|
||||
func inSlice(str string, s []string) bool {
|
||||
for _, v := range s {
|
||||
if str == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// dataSource is an interface that returns object which can be read and closed.
|
||||
type dataSource interface {
|
||||
ReadCloser() (io.ReadCloser, error)
|
||||
}
|
||||
|
||||
// sourceFile represents an object that contains content on the local file system.
|
||||
type sourceFile struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) {
|
||||
return os.Open(s.name)
|
||||
}
|
||||
|
||||
// sourceData represents an object that contains content in memory.
|
||||
type sourceData struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
func (s *sourceData) ReadCloser() (io.ReadCloser, error) {
|
||||
return ioutil.NopCloser(bytes.NewReader(s.data)), nil
|
||||
}
|
||||
|
||||
// sourceReadCloser represents an input stream with Close method.
|
||||
type sourceReadCloser struct {
|
||||
reader io.ReadCloser
|
||||
}
|
||||
|
||||
func (s *sourceReadCloser) ReadCloser() (io.ReadCloser, error) {
|
||||
return s.reader, nil
|
||||
}
|
||||
|
||||
func parseDataSource(source interface{}) (dataSource, error) {
|
||||
switch s := source.(type) {
|
||||
case string:
|
||||
return sourceFile{s}, nil
|
||||
case []byte:
|
||||
return &sourceData{s}, nil
|
||||
case io.ReadCloser:
|
||||
return &sourceReadCloser{s}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s)
|
||||
}
|
||||
}
|
||||
|
||||
type LoadOptions struct {
|
||||
// Loose indicates whether the parser should ignore nonexistent files or return error.
|
||||
Loose bool
|
||||
// Insensitive indicates whether the parser forces all section and key names to lowercase.
|
||||
Insensitive bool
|
||||
// IgnoreContinuation indicates whether to ignore continuation lines while parsing.
|
||||
IgnoreContinuation bool
|
||||
// IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value.
|
||||
IgnoreInlineComment bool
|
||||
// AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing.
|
||||
// This type of keys are mostly used in my.cnf.
|
||||
AllowBooleanKeys bool
|
||||
// AllowShadows indicates whether to keep track of keys with same name under same section.
|
||||
AllowShadows bool
|
||||
// AllowNestedValues indicates whether to allow AWS-like nested values.
|
||||
// Docs: http://docs.aws.amazon.com/cli/latest/topic/config-vars.html#nested-values
|
||||
AllowNestedValues bool
|
||||
// AllowPythonMultilineValues indicates whether to allow Python-like multi-line values.
|
||||
// Docs: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
|
||||
// Relevant quote: Values can also span multiple lines, as long as they are indented deeper
|
||||
// than the first line of the value.
|
||||
AllowPythonMultilineValues bool
|
||||
// UnescapeValueDoubleQuotes indicates whether to unescape double quotes inside value to regular format
|
||||
// when value is surrounded by double quotes, e.g. key="a \"value\"" => key=a "value"
|
||||
UnescapeValueDoubleQuotes bool
|
||||
// UnescapeValueCommentSymbols indicates to unescape comment symbols (\# and \;) inside value to regular format
|
||||
// when value is NOT surrounded by any quotes.
|
||||
// Note: UNSTABLE, behavior might change to only unescape inside double quotes but may noy necessary at all.
|
||||
UnescapeValueCommentSymbols bool
|
||||
// Some INI formats allow group blocks that store a block of raw content that doesn't otherwise
|
||||
// conform to key/value pairs. Specify the names of those blocks here.
|
||||
UnparseableSections []string
|
||||
}
|
||||
|
||||
func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) {
|
||||
sources := make([]dataSource, len(others)+1)
|
||||
sources[0], err = parseDataSource(source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range others {
|
||||
sources[i+1], err = parseDataSource(others[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
f := newFile(sources, opts)
|
||||
if err = f.Reload(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Load loads and parses from INI data sources.
|
||||
// Arguments can be mixed of file name with string type, or raw data in []byte.
|
||||
// It will return error if list contains nonexistent files.
|
||||
func Load(source interface{}, others ...interface{}) (*File, error) {
|
||||
return LoadSources(LoadOptions{}, source, others...)
|
||||
}
|
||||
|
||||
// LooseLoad has exactly same functionality as Load function
|
||||
// except it ignores nonexistent files instead of returning error.
|
||||
func LooseLoad(source interface{}, others ...interface{}) (*File, error) {
|
||||
return LoadSources(LoadOptions{Loose: true}, source, others...)
|
||||
}
|
||||
|
||||
// InsensitiveLoad has exactly same functionality as Load function
|
||||
// except it forces all section and key names to be lowercased.
|
||||
func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) {
|
||||
return LoadSources(LoadOptions{Insensitive: true}, source, others...)
|
||||
}
|
||||
|
||||
// InsensitiveLoad has exactly same functionality as Load function
|
||||
// except it allows have shadow keys.
|
||||
func ShadowLoad(source interface{}, others ...interface{}) (*File, error) {
|
||||
return LoadSources(LoadOptions{AllowShadows: true}, source, others...)
|
||||
}
|
751
vendor/github.com/go-ini/ini/key.go
generated
vendored
751
vendor/github.com/go-ini/ini/key.go
generated
vendored
@ -1,751 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// 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 ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Key represents a key under a section.
|
||||
type Key struct {
|
||||
s *Section
|
||||
Comment string
|
||||
name string
|
||||
value string
|
||||
isAutoIncrement bool
|
||||
isBooleanType bool
|
||||
|
||||
isShadow bool
|
||||
shadows []*Key
|
||||
|
||||
nestedValues []string
|
||||
}
|
||||
|
||||
// newKey simply return a key object with given values.
|
||||
func newKey(s *Section, name, val string) *Key {
|
||||
return &Key{
|
||||
s: s,
|
||||
name: name,
|
||||
value: val,
|
||||
}
|
||||
}
|
||||
|
||||
func (k *Key) addShadow(val string) error {
|
||||
if k.isShadow {
|
||||
return errors.New("cannot add shadow to another shadow key")
|
||||
} else if k.isAutoIncrement || k.isBooleanType {
|
||||
return errors.New("cannot add shadow to auto-increment or boolean key")
|
||||
}
|
||||
|
||||
shadow := newKey(k.s, k.name, val)
|
||||
shadow.isShadow = true
|
||||
k.shadows = append(k.shadows, shadow)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddShadow adds a new shadow key to itself.
|
||||
func (k *Key) AddShadow(val string) error {
|
||||
if !k.s.f.options.AllowShadows {
|
||||
return errors.New("shadow key is not allowed")
|
||||
}
|
||||
return k.addShadow(val)
|
||||
}
|
||||
|
||||
func (k *Key) addNestedValue(val string) error {
|
||||
if k.isAutoIncrement || k.isBooleanType {
|
||||
return errors.New("cannot add nested value to auto-increment or boolean key")
|
||||
}
|
||||
|
||||
k.nestedValues = append(k.nestedValues, val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *Key) AddNestedValue(val string) error {
|
||||
if !k.s.f.options.AllowNestedValues {
|
||||
return errors.New("nested value is not allowed")
|
||||
}
|
||||
return k.addNestedValue(val)
|
||||
}
|
||||
|
||||
// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv
|
||||
type ValueMapper func(string) string
|
||||
|
||||
// Name returns name of key.
|
||||
func (k *Key) Name() string {
|
||||
return k.name
|
||||
}
|
||||
|
||||
// Value returns raw value of key for performance purpose.
|
||||
func (k *Key) Value() string {
|
||||
return k.value
|
||||
}
|
||||
|
||||
// ValueWithShadows returns raw values of key and its shadows if any.
|
||||
func (k *Key) ValueWithShadows() []string {
|
||||
if len(k.shadows) == 0 {
|
||||
return []string{k.value}
|
||||
}
|
||||
vals := make([]string, len(k.shadows)+1)
|
||||
vals[0] = k.value
|
||||
for i := range k.shadows {
|
||||
vals[i+1] = k.shadows[i].value
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
// NestedValues returns nested values stored in the key.
|
||||
// It is possible returned value is nil if no nested values stored in the key.
|
||||
func (k *Key) NestedValues() []string {
|
||||
return k.nestedValues
|
||||
}
|
||||
|
||||
// transformValue takes a raw value and transforms to its final string.
|
||||
func (k *Key) transformValue(val string) string {
|
||||
if k.s.f.ValueMapper != nil {
|
||||
val = k.s.f.ValueMapper(val)
|
||||
}
|
||||
|
||||
// Fail-fast if no indicate char found for recursive value
|
||||
if !strings.Contains(val, "%") {
|
||||
return val
|
||||
}
|
||||
for i := 0; i < _DEPTH_VALUES; i++ {
|
||||
vr := varPattern.FindString(val)
|
||||
if len(vr) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// Take off leading '%(' and trailing ')s'.
|
||||
noption := strings.TrimLeft(vr, "%(")
|
||||
noption = strings.TrimRight(noption, ")s")
|
||||
|
||||
// Search in the same section.
|
||||
nk, err := k.s.GetKey(noption)
|
||||
if err != nil || k == nk {
|
||||
// Search again in default section.
|
||||
nk, _ = k.s.f.Section("").GetKey(noption)
|
||||
}
|
||||
|
||||
// Substitute by new value and take off leading '%(' and trailing ')s'.
|
||||
val = strings.Replace(val, vr, nk.value, -1)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// String returns string representation of value.
|
||||
func (k *Key) String() string {
|
||||
return k.transformValue(k.value)
|
||||
}
|
||||
|
||||
// Validate accepts a validate function which can
|
||||
// return modifed result as key value.
|
||||
func (k *Key) Validate(fn func(string) string) string {
|
||||
return fn(k.String())
|
||||
}
|
||||
|
||||
// parseBool returns the boolean value represented by the string.
|
||||
//
|
||||
// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On,
|
||||
// 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off.
|
||||
// Any other value returns an error.
|
||||
func parseBool(str string) (value bool, err error) {
|
||||
switch str {
|
||||
case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On":
|
||||
return true, nil
|
||||
case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off":
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("parsing \"%s\": invalid syntax", str)
|
||||
}
|
||||
|
||||
// Bool returns bool type value.
|
||||
func (k *Key) Bool() (bool, error) {
|
||||
return parseBool(k.String())
|
||||
}
|
||||
|
||||
// Float64 returns float64 type value.
|
||||
func (k *Key) Float64() (float64, error) {
|
||||
return strconv.ParseFloat(k.String(), 64)
|
||||
}
|
||||
|
||||
// Int returns int type value.
|
||||
func (k *Key) Int() (int, error) {
|
||||
return strconv.Atoi(k.String())
|
||||
}
|
||||
|
||||
// Int64 returns int64 type value.
|
||||
func (k *Key) Int64() (int64, error) {
|
||||
return strconv.ParseInt(k.String(), 10, 64)
|
||||
}
|
||||
|
||||
// Uint returns uint type valued.
|
||||
func (k *Key) Uint() (uint, error) {
|
||||
u, e := strconv.ParseUint(k.String(), 10, 64)
|
||||
return uint(u), e
|
||||
}
|
||||
|
||||
// Uint64 returns uint64 type value.
|
||||
func (k *Key) Uint64() (uint64, error) {
|
||||
return strconv.ParseUint(k.String(), 10, 64)
|
||||
}
|
||||
|
||||
// Duration returns time.Duration type value.
|
||||
func (k *Key) Duration() (time.Duration, error) {
|
||||
return time.ParseDuration(k.String())
|
||||
}
|
||||
|
||||
// TimeFormat parses with given format and returns time.Time type value.
|
||||
func (k *Key) TimeFormat(format string) (time.Time, error) {
|
||||
return time.Parse(format, k.String())
|
||||
}
|
||||
|
||||
// Time parses with RFC3339 format and returns time.Time type value.
|
||||
func (k *Key) Time() (time.Time, error) {
|
||||
return k.TimeFormat(time.RFC3339)
|
||||
}
|
||||
|
||||
// MustString returns default value if key value is empty.
|
||||
func (k *Key) MustString(defaultVal string) string {
|
||||
val := k.String()
|
||||
if len(val) == 0 {
|
||||
k.value = defaultVal
|
||||
return defaultVal
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustBool always returns value without error,
|
||||
// it returns false if error occurs.
|
||||
func (k *Key) MustBool(defaultVal ...bool) bool {
|
||||
val, err := k.Bool()
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = strconv.FormatBool(defaultVal[0])
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustFloat64 always returns value without error,
|
||||
// it returns 0.0 if error occurs.
|
||||
func (k *Key) MustFloat64(defaultVal ...float64) float64 {
|
||||
val, err := k.Float64()
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64)
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustInt always returns value without error,
|
||||
// it returns 0 if error occurs.
|
||||
func (k *Key) MustInt(defaultVal ...int) int {
|
||||
val, err := k.Int()
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = strconv.FormatInt(int64(defaultVal[0]), 10)
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustInt64 always returns value without error,
|
||||
// it returns 0 if error occurs.
|
||||
func (k *Key) MustInt64(defaultVal ...int64) int64 {
|
||||
val, err := k.Int64()
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = strconv.FormatInt(defaultVal[0], 10)
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustUint always returns value without error,
|
||||
// it returns 0 if error occurs.
|
||||
func (k *Key) MustUint(defaultVal ...uint) uint {
|
||||
val, err := k.Uint()
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = strconv.FormatUint(uint64(defaultVal[0]), 10)
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustUint64 always returns value without error,
|
||||
// it returns 0 if error occurs.
|
||||
func (k *Key) MustUint64(defaultVal ...uint64) uint64 {
|
||||
val, err := k.Uint64()
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = strconv.FormatUint(defaultVal[0], 10)
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustDuration always returns value without error,
|
||||
// it returns zero value if error occurs.
|
||||
func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration {
|
||||
val, err := k.Duration()
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = defaultVal[0].String()
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustTimeFormat always parses with given format and returns value without error,
|
||||
// it returns zero value if error occurs.
|
||||
func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time {
|
||||
val, err := k.TimeFormat(format)
|
||||
if len(defaultVal) > 0 && err != nil {
|
||||
k.value = defaultVal[0].Format(format)
|
||||
return defaultVal[0]
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// MustTime always parses with RFC3339 format and returns value without error,
|
||||
// it returns zero value if error occurs.
|
||||
func (k *Key) MustTime(defaultVal ...time.Time) time.Time {
|
||||
return k.MustTimeFormat(time.RFC3339, defaultVal...)
|
||||
}
|
||||
|
||||
// In always returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) In(defaultVal string, candidates []string) string {
|
||||
val := k.String()
|
||||
for _, cand := range candidates {
|
||||
if val == cand {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// InFloat64 always returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 {
|
||||
val := k.MustFloat64()
|
||||
for _, cand := range candidates {
|
||||
if val == cand {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// InInt always returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) InInt(defaultVal int, candidates []int) int {
|
||||
val := k.MustInt()
|
||||
for _, cand := range candidates {
|
||||
if val == cand {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// InInt64 always returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 {
|
||||
val := k.MustInt64()
|
||||
for _, cand := range candidates {
|
||||
if val == cand {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// InUint always returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) InUint(defaultVal uint, candidates []uint) uint {
|
||||
val := k.MustUint()
|
||||
for _, cand := range candidates {
|
||||
if val == cand {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// InUint64 always returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 {
|
||||
val := k.MustUint64()
|
||||
for _, cand := range candidates {
|
||||
if val == cand {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// InTimeFormat always parses with given format and returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time {
|
||||
val := k.MustTimeFormat(format)
|
||||
for _, cand := range candidates {
|
||||
if val == cand {
|
||||
return val
|
||||
}
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
// InTime always parses with RFC3339 format and returns value without error,
|
||||
// it returns default value if error occurs or doesn't fit into candidates.
|
||||
func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time {
|
||||
return k.InTimeFormat(time.RFC3339, defaultVal, candidates)
|
||||
}
|
||||
|
||||
// RangeFloat64 checks if value is in given range inclusively,
|
||||
// and returns default value if it's not.
|
||||
func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 {
|
||||
val := k.MustFloat64()
|
||||
if val < min || val > max {
|
||||
return defaultVal
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// RangeInt checks if value is in given range inclusively,
|
||||
// and returns default value if it's not.
|
||||
func (k *Key) RangeInt(defaultVal, min, max int) int {
|
||||
val := k.MustInt()
|
||||
if val < min || val > max {
|
||||
return defaultVal
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// RangeInt64 checks if value is in given range inclusively,
|
||||
// and returns default value if it's not.
|
||||
func (k *Key) RangeInt64(defaultVal, min, max int64) int64 {
|
||||
val := k.MustInt64()
|
||||
if val < min || val > max {
|
||||
return defaultVal
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// RangeTimeFormat checks if value with given format is in given range inclusively,
|
||||
// and returns default value if it's not.
|
||||
func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time {
|
||||
val := k.MustTimeFormat(format)
|
||||
if val.Unix() < min.Unix() || val.Unix() > max.Unix() {
|
||||
return defaultVal
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// RangeTime checks if value with RFC3339 format is in given range inclusively,
|
||||
// and returns default value if it's not.
|
||||
func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time {
|
||||
return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max)
|
||||
}
|
||||
|
||||
// Strings returns list of string divided by given delimiter.
|
||||
func (k *Key) Strings(delim string) []string {
|
||||
str := k.String()
|
||||
if len(str) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
runes := []rune(str)
|
||||
vals := make([]string, 0, 2)
|
||||
var buf bytes.Buffer
|
||||
escape := false
|
||||
idx := 0
|
||||
for {
|
||||
if escape {
|
||||
escape = false
|
||||
if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) {
|
||||
buf.WriteRune('\\')
|
||||
}
|
||||
buf.WriteRune(runes[idx])
|
||||
} else {
|
||||
if runes[idx] == '\\' {
|
||||
escape = true
|
||||
} else if strings.HasPrefix(string(runes[idx:]), delim) {
|
||||
idx += len(delim) - 1
|
||||
vals = append(vals, strings.TrimSpace(buf.String()))
|
||||
buf.Reset()
|
||||
} else {
|
||||
buf.WriteRune(runes[idx])
|
||||
}
|
||||
}
|
||||
idx += 1
|
||||
if idx == len(runes) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if buf.Len() > 0 {
|
||||
vals = append(vals, strings.TrimSpace(buf.String()))
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
// StringsWithShadows returns list of string divided by given delimiter.
|
||||
// Shadows will also be appended if any.
|
||||
func (k *Key) StringsWithShadows(delim string) []string {
|
||||
vals := k.ValueWithShadows()
|
||||
results := make([]string, 0, len(vals)*2)
|
||||
for i := range vals {
|
||||
if len(vals) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, strings.Split(vals[i], delim)...)
|
||||
}
|
||||
|
||||
for i := range results {
|
||||
results[i] = k.transformValue(strings.TrimSpace(results[i]))
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// Float64s returns list of float64 divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Float64s(delim string) []float64 {
|
||||
vals, _ := k.parseFloat64s(k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// Ints returns list of int divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Ints(delim string) []int {
|
||||
vals, _ := k.parseInts(k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// Int64s returns list of int64 divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Int64s(delim string) []int64 {
|
||||
vals, _ := k.parseInt64s(k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// Uints returns list of uint divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Uints(delim string) []uint {
|
||||
vals, _ := k.parseUints(k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// Uint64s returns list of uint64 divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Uint64s(delim string) []uint64 {
|
||||
vals, _ := k.parseUint64s(k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// TimesFormat parses with given format and returns list of time.Time divided by given delimiter.
|
||||
// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC).
|
||||
func (k *Key) TimesFormat(format, delim string) []time.Time {
|
||||
vals, _ := k.parseTimesFormat(format, k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// Times parses with RFC3339 format and returns list of time.Time divided by given delimiter.
|
||||
// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC).
|
||||
func (k *Key) Times(delim string) []time.Time {
|
||||
return k.TimesFormat(time.RFC3339, delim)
|
||||
}
|
||||
|
||||
// ValidFloat64s returns list of float64 divided by given delimiter. If some value is not float, then
|
||||
// it will not be included to result list.
|
||||
func (k *Key) ValidFloat64s(delim string) []float64 {
|
||||
vals, _ := k.parseFloat64s(k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// ValidInts returns list of int divided by given delimiter. If some value is not integer, then it will
|
||||
// not be included to result list.
|
||||
func (k *Key) ValidInts(delim string) []int {
|
||||
vals, _ := k.parseInts(k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// ValidInt64s returns list of int64 divided by given delimiter. If some value is not 64-bit integer,
|
||||
// then it will not be included to result list.
|
||||
func (k *Key) ValidInt64s(delim string) []int64 {
|
||||
vals, _ := k.parseInt64s(k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// ValidUints returns list of uint divided by given delimiter. If some value is not unsigned integer,
|
||||
// then it will not be included to result list.
|
||||
func (k *Key) ValidUints(delim string) []uint {
|
||||
vals, _ := k.parseUints(k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// ValidUint64s returns list of uint64 divided by given delimiter. If some value is not 64-bit unsigned
|
||||
// integer, then it will not be included to result list.
|
||||
func (k *Key) ValidUint64s(delim string) []uint64 {
|
||||
vals, _ := k.parseUint64s(k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// ValidTimesFormat parses with given format and returns list of time.Time divided by given delimiter.
|
||||
func (k *Key) ValidTimesFormat(format, delim string) []time.Time {
|
||||
vals, _ := k.parseTimesFormat(format, k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// ValidTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter.
|
||||
func (k *Key) ValidTimes(delim string) []time.Time {
|
||||
return k.ValidTimesFormat(time.RFC3339, delim)
|
||||
}
|
||||
|
||||
// StrictFloat64s returns list of float64 divided by given delimiter or error on first invalid input.
|
||||
func (k *Key) StrictFloat64s(delim string) ([]float64, error) {
|
||||
return k.parseFloat64s(k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictInts returns list of int divided by given delimiter or error on first invalid input.
|
||||
func (k *Key) StrictInts(delim string) ([]int, error) {
|
||||
return k.parseInts(k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictInt64s returns list of int64 divided by given delimiter or error on first invalid input.
|
||||
func (k *Key) StrictInt64s(delim string) ([]int64, error) {
|
||||
return k.parseInt64s(k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictUints returns list of uint divided by given delimiter or error on first invalid input.
|
||||
func (k *Key) StrictUints(delim string) ([]uint, error) {
|
||||
return k.parseUints(k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictUint64s returns list of uint64 divided by given delimiter or error on first invalid input.
|
||||
func (k *Key) StrictUint64s(delim string) ([]uint64, error) {
|
||||
return k.parseUint64s(k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictTimesFormat parses with given format and returns list of time.Time divided by given delimiter
|
||||
// or error on first invalid input.
|
||||
func (k *Key) StrictTimesFormat(format, delim string) ([]time.Time, error) {
|
||||
return k.parseTimesFormat(format, k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter
|
||||
// or error on first invalid input.
|
||||
func (k *Key) StrictTimes(delim string) ([]time.Time, error) {
|
||||
return k.StrictTimesFormat(time.RFC3339, delim)
|
||||
}
|
||||
|
||||
// parseFloat64s transforms strings to float64s.
|
||||
func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]float64, error) {
|
||||
vals := make([]float64, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseFloat(str, 64)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil || addInvalid {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
}
|
||||
return vals, nil
|
||||
}
|
||||
|
||||
// parseInts transforms strings to ints.
|
||||
func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) {
|
||||
vals := make([]int, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.Atoi(str)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil || addInvalid {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
}
|
||||
return vals, nil
|
||||
}
|
||||
|
||||
// parseInt64s transforms strings to int64s.
|
||||
func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) {
|
||||
vals := make([]int64, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseInt(str, 10, 64)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil || addInvalid {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
}
|
||||
return vals, nil
|
||||
}
|
||||
|
||||
// parseUints transforms strings to uints.
|
||||
func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) {
|
||||
vals := make([]uint, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseUint(str, 10, 0)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil || addInvalid {
|
||||
vals = append(vals, uint(val))
|
||||
}
|
||||
}
|
||||
return vals, nil
|
||||
}
|
||||
|
||||
// parseUint64s transforms strings to uint64s.
|
||||
func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) {
|
||||
vals := make([]uint64, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseUint(str, 10, 64)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil || addInvalid {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
}
|
||||
return vals, nil
|
||||
}
|
||||
|
||||
// parseTimesFormat transforms strings to times in given format.
|
||||
func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) {
|
||||
vals := make([]time.Time, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := time.Parse(format, str)
|
||||
if err != nil && returnOnInvalid {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil || addInvalid {
|
||||
vals = append(vals, val)
|
||||
}
|
||||
}
|
||||
return vals, nil
|
||||
}
|
||||
|
||||
// SetValue changes key value.
|
||||
func (k *Key) SetValue(v string) {
|
||||
if k.s.f.BlockMode {
|
||||
k.s.f.lock.Lock()
|
||||
defer k.s.f.lock.Unlock()
|
||||
}
|
||||
|
||||
k.value = v
|
||||
k.s.keysHash[k.name] = v
|
||||
}
|
477
vendor/github.com/go-ini/ini/parser.go
generated
vendored
477
vendor/github.com/go-ini/ini/parser.go
generated
vendored
@ -1,477 +0,0 @@
|
||||
// Copyright 2015 Unknwon
|
||||
//
|
||||
// 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 ini
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var pythonMultiline = regexp.MustCompile("^(\\s+)([^\n]+)")
|
||||
|
||||
type tokenType int
|
||||
|
||||
const (
|
||||
_TOKEN_INVALID tokenType = iota
|
||||
_TOKEN_COMMENT
|
||||
_TOKEN_SECTION
|
||||
_TOKEN_KEY
|
||||
)
|
||||
|
||||
type parser struct {
|
||||
buf *bufio.Reader
|
||||
isEOF bool
|
||||
count int
|
||||
comment *bytes.Buffer
|
||||
}
|
||||
|
||||
func newParser(r io.Reader) *parser {
|
||||
return &parser{
|
||||
buf: bufio.NewReader(r),
|
||||
count: 1,
|
||||
comment: &bytes.Buffer{},
|
||||
}
|
||||
}
|
||||
|
||||
// BOM handles header of UTF-8, UTF-16 LE and UTF-16 BE's BOM format.
|
||||
// http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding
|
||||
func (p *parser) BOM() error {
|
||||
mask, err := p.buf.Peek(2)
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
} else if len(mask) < 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch {
|
||||
case mask[0] == 254 && mask[1] == 255:
|
||||
fallthrough
|
||||
case mask[0] == 255 && mask[1] == 254:
|
||||
p.buf.Read(mask)
|
||||
case mask[0] == 239 && mask[1] == 187:
|
||||
mask, err := p.buf.Peek(3)
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
} else if len(mask) < 3 {
|
||||
return nil
|
||||
}
|
||||
if mask[2] == 191 {
|
||||
p.buf.Read(mask)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *parser) readUntil(delim byte) ([]byte, error) {
|
||||
data, err := p.buf.ReadBytes(delim)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
p.isEOF = true
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func cleanComment(in []byte) ([]byte, bool) {
|
||||
i := bytes.IndexAny(in, "#;")
|
||||
if i == -1 {
|
||||
return nil, false
|
||||
}
|
||||
return in[i:], true
|
||||
}
|
||||
|
||||
func readKeyName(in []byte) (string, int, error) {
|
||||
line := string(in)
|
||||
|
||||
// Check if key name surrounded by quotes.
|
||||
var keyQuote string
|
||||
if line[0] == '"' {
|
||||
if len(line) > 6 && string(line[0:3]) == `"""` {
|
||||
keyQuote = `"""`
|
||||
} else {
|
||||
keyQuote = `"`
|
||||
}
|
||||
} else if line[0] == '`' {
|
||||
keyQuote = "`"
|
||||
}
|
||||
|
||||
// Get out key name
|
||||
endIdx := -1
|
||||
if len(keyQuote) > 0 {
|
||||
startIdx := len(keyQuote)
|
||||
// FIXME: fail case -> """"""name"""=value
|
||||
pos := strings.Index(line[startIdx:], keyQuote)
|
||||
if pos == -1 {
|
||||
return "", -1, fmt.Errorf("missing closing key quote: %s", line)
|
||||
}
|
||||
pos += startIdx
|
||||
|
||||
// Find key-value delimiter
|
||||
i := strings.IndexAny(line[pos+startIdx:], "=:")
|
||||
if i < 0 {
|
||||
return "", -1, ErrDelimiterNotFound{line}
|
||||
}
|
||||
endIdx = pos + i
|
||||
return strings.TrimSpace(line[startIdx:pos]), endIdx + startIdx + 1, nil
|
||||
}
|
||||
|
||||
endIdx = strings.IndexAny(line, "=:")
|
||||
if endIdx < 0 {
|
||||
return "", -1, ErrDelimiterNotFound{line}
|
||||
}
|
||||
return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil
|
||||
}
|
||||
|
||||
func (p *parser) readMultilines(line, val, valQuote string) (string, error) {
|
||||
for {
|
||||
data, err := p.readUntil('\n')
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
next := string(data)
|
||||
|
||||
pos := strings.LastIndex(next, valQuote)
|
||||
if pos > -1 {
|
||||
val += next[:pos]
|
||||
|
||||
comment, has := cleanComment([]byte(next[pos:]))
|
||||
if has {
|
||||
p.comment.Write(bytes.TrimSpace(comment))
|
||||
}
|
||||
break
|
||||
}
|
||||
val += next
|
||||
if p.isEOF {
|
||||
return "", fmt.Errorf("missing closing key quote from '%s' to '%s'", line, next)
|
||||
}
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func (p *parser) readContinuationLines(val string) (string, error) {
|
||||
for {
|
||||
data, err := p.readUntil('\n')
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
next := strings.TrimSpace(string(data))
|
||||
|
||||
if len(next) == 0 {
|
||||
break
|
||||
}
|
||||
val += next
|
||||
if val[len(val)-1] != '\\' {
|
||||
break
|
||||
}
|
||||
val = val[:len(val)-1]
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// hasSurroundedQuote check if and only if the first and last characters
|
||||
// are quotes \" or \'.
|
||||
// It returns false if any other parts also contain same kind of quotes.
|
||||
func hasSurroundedQuote(in string, quote byte) bool {
|
||||
return len(in) >= 2 && in[0] == quote && in[len(in)-1] == quote &&
|
||||
strings.IndexByte(in[1:], quote) == len(in)-2
|
||||
}
|
||||
|
||||
func (p *parser) readValue(in []byte,
|
||||
parserBufferSize int,
|
||||
ignoreContinuation, ignoreInlineComment, unescapeValueDoubleQuotes, unescapeValueCommentSymbols, allowPythonMultilines bool) (string, error) {
|
||||
|
||||
line := strings.TrimLeftFunc(string(in), unicode.IsSpace)
|
||||
if len(line) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
var valQuote string
|
||||
if len(line) > 3 && string(line[0:3]) == `"""` {
|
||||
valQuote = `"""`
|
||||
} else if line[0] == '`' {
|
||||
valQuote = "`"
|
||||
} else if unescapeValueDoubleQuotes && line[0] == '"' {
|
||||
valQuote = `"`
|
||||
}
|
||||
|
||||
if len(valQuote) > 0 {
|
||||
startIdx := len(valQuote)
|
||||
pos := strings.LastIndex(line[startIdx:], valQuote)
|
||||
// Check for multi-line value
|
||||
if pos == -1 {
|
||||
return p.readMultilines(line, line[startIdx:], valQuote)
|
||||
}
|
||||
|
||||
if unescapeValueDoubleQuotes && valQuote == `"` {
|
||||
return strings.Replace(line[startIdx:pos+startIdx], `\"`, `"`, -1), nil
|
||||
}
|
||||
return line[startIdx : pos+startIdx], nil
|
||||
}
|
||||
|
||||
lastChar := line[len(line)-1]
|
||||
// Won't be able to reach here if value only contains whitespace
|
||||
line = strings.TrimSpace(line)
|
||||
trimmedLastChar := line[len(line)-1]
|
||||
|
||||
// Check continuation lines when desired
|
||||
if !ignoreContinuation && trimmedLastChar == '\\' {
|
||||
return p.readContinuationLines(line[:len(line)-1])
|
||||
}
|
||||
|
||||
// Check if ignore inline comment
|
||||
if !ignoreInlineComment {
|
||||
i := strings.IndexAny(line, "#;")
|
||||
if i > -1 {
|
||||
p.comment.WriteString(line[i:])
|
||||
line = strings.TrimSpace(line[:i])
|
||||
}
|
||||
}
|
||||
|
||||
// Trim single and double quotes
|
||||
if hasSurroundedQuote(line, '\'') ||
|
||||
hasSurroundedQuote(line, '"') {
|
||||
line = line[1 : len(line)-1]
|
||||
} else if len(valQuote) == 0 && unescapeValueCommentSymbols {
|
||||
if strings.Contains(line, `\;`) {
|
||||
line = strings.Replace(line, `\;`, ";", -1)
|
||||
}
|
||||
if strings.Contains(line, `\#`) {
|
||||
line = strings.Replace(line, `\#`, "#", -1)
|
||||
}
|
||||
} else if allowPythonMultilines && lastChar == '\n' {
|
||||
parserBufferPeekResult, _ := p.buf.Peek(parserBufferSize)
|
||||
peekBuffer := bytes.NewBuffer(parserBufferPeekResult)
|
||||
|
||||
identSize := -1
|
||||
val := line
|
||||
|
||||
for {
|
||||
peekData, peekErr := peekBuffer.ReadBytes('\n')
|
||||
if peekErr != nil {
|
||||
if peekErr == io.EOF {
|
||||
return val, nil
|
||||
}
|
||||
return "", peekErr
|
||||
}
|
||||
|
||||
peekMatches := pythonMultiline.FindStringSubmatch(string(peekData))
|
||||
if len(peekMatches) != 3 {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
currentIdentSize := len(peekMatches[1])
|
||||
// NOTE: Return if not a python-ini multi-line value.
|
||||
if currentIdentSize < 0 {
|
||||
return val, nil
|
||||
}
|
||||
identSize = currentIdentSize
|
||||
|
||||
// NOTE: Just advance the parser reader (buffer) in-sync with the peek buffer.
|
||||
_, err := p.readUntil('\n')
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
val += fmt.Sprintf("\n%s", peekMatches[2])
|
||||
}
|
||||
|
||||
// NOTE: If it was a Python multi-line value,
|
||||
// return the appended value.
|
||||
if identSize > 0 {
|
||||
return val, nil
|
||||
}
|
||||
}
|
||||
|
||||
return line, nil
|
||||
}
|
||||
|
||||
// parse parses data through an io.Reader.
|
||||
func (f *File) parse(reader io.Reader) (err error) {
|
||||
p := newParser(reader)
|
||||
if err = p.BOM(); err != nil {
|
||||
return fmt.Errorf("BOM: %v", err)
|
||||
}
|
||||
|
||||
// Ignore error because default section name is never empty string.
|
||||
name := DEFAULT_SECTION
|
||||
if f.options.Insensitive {
|
||||
name = strings.ToLower(DEFAULT_SECTION)
|
||||
}
|
||||
section, _ := f.NewSection(name)
|
||||
|
||||
// This "last" is not strictly equivalent to "previous one" if current key is not the first nested key
|
||||
var isLastValueEmpty bool
|
||||
var lastRegularKey *Key
|
||||
|
||||
var line []byte
|
||||
var inUnparseableSection bool
|
||||
|
||||
// NOTE: Iterate and increase `currentPeekSize` until
|
||||
// the size of the parser buffer is found.
|
||||
// TODO: When Golang 1.10 is the lowest version supported,
|
||||
// replace with `parserBufferSize := p.buf.Size()`.
|
||||
parserBufferSize := 0
|
||||
// NOTE: Peek 1kb at a time.
|
||||
currentPeekSize := 1024
|
||||
|
||||
if f.options.AllowPythonMultilineValues {
|
||||
for {
|
||||
peekBytes, _ := p.buf.Peek(currentPeekSize)
|
||||
peekBytesLength := len(peekBytes)
|
||||
|
||||
if parserBufferSize >= peekBytesLength {
|
||||
break
|
||||
}
|
||||
|
||||
currentPeekSize *= 2
|
||||
parserBufferSize = peekBytesLength
|
||||
}
|
||||
}
|
||||
|
||||
for !p.isEOF {
|
||||
line, err = p.readUntil('\n')
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if f.options.AllowNestedValues &&
|
||||
isLastValueEmpty && len(line) > 0 {
|
||||
if line[0] == ' ' || line[0] == '\t' {
|
||||
lastRegularKey.addNestedValue(string(bytes.TrimSpace(line)))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
line = bytes.TrimLeftFunc(line, unicode.IsSpace)
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Comments
|
||||
if line[0] == '#' || line[0] == ';' {
|
||||
// Note: we do not care ending line break,
|
||||
// it is needed for adding second line,
|
||||
// so just clean it once at the end when set to value.
|
||||
p.comment.Write(line)
|
||||
continue
|
||||
}
|
||||
|
||||
// Section
|
||||
if line[0] == '[' {
|
||||
// Read to the next ']' (TODO: support quoted strings)
|
||||
// TODO(unknwon): use LastIndexByte when stop supporting Go1.4
|
||||
closeIdx := bytes.LastIndex(line, []byte("]"))
|
||||
if closeIdx == -1 {
|
||||
return fmt.Errorf("unclosed section: %s", line)
|
||||
}
|
||||
|
||||
name := string(line[1:closeIdx])
|
||||
section, err = f.NewSection(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
comment, has := cleanComment(line[closeIdx+1:])
|
||||
if has {
|
||||
p.comment.Write(comment)
|
||||
}
|
||||
|
||||
section.Comment = strings.TrimSpace(p.comment.String())
|
||||
|
||||
// Reset aotu-counter and comments
|
||||
p.comment.Reset()
|
||||
p.count = 1
|
||||
|
||||
inUnparseableSection = false
|
||||
for i := range f.options.UnparseableSections {
|
||||
if f.options.UnparseableSections[i] == name ||
|
||||
(f.options.Insensitive && strings.ToLower(f.options.UnparseableSections[i]) == strings.ToLower(name)) {
|
||||
inUnparseableSection = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if inUnparseableSection {
|
||||
section.isRawSection = true
|
||||
section.rawBody += string(line)
|
||||
continue
|
||||
}
|
||||
|
||||
kname, offset, err := readKeyName(line)
|
||||
if err != nil {
|
||||
// Treat as boolean key when desired, and whole line is key name.
|
||||
if IsErrDelimiterNotFound(err) && f.options.AllowBooleanKeys {
|
||||
kname, err := p.readValue(line,
|
||||
parserBufferSize,
|
||||
f.options.IgnoreContinuation,
|
||||
f.options.IgnoreInlineComment,
|
||||
f.options.UnescapeValueDoubleQuotes,
|
||||
f.options.UnescapeValueCommentSymbols,
|
||||
f.options.AllowPythonMultilineValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := section.NewBooleanKey(kname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key.Comment = strings.TrimSpace(p.comment.String())
|
||||
p.comment.Reset()
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Auto increment.
|
||||
isAutoIncr := false
|
||||
if kname == "-" {
|
||||
isAutoIncr = true
|
||||
kname = "#" + strconv.Itoa(p.count)
|
||||
p.count++
|
||||
}
|
||||
|
||||
value, err := p.readValue(line[offset:],
|
||||
parserBufferSize,
|
||||
f.options.IgnoreContinuation,
|
||||
f.options.IgnoreInlineComment,
|
||||
f.options.UnescapeValueDoubleQuotes,
|
||||
f.options.UnescapeValueCommentSymbols,
|
||||
f.options.AllowPythonMultilineValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
isLastValueEmpty = len(value) == 0
|
||||
|
||||
key, err := section.NewKey(kname, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key.isAutoIncrement = isAutoIncr
|
||||
key.Comment = strings.TrimSpace(p.comment.String())
|
||||
p.comment.Reset()
|
||||
lastRegularKey = key
|
||||
}
|
||||
return nil
|
||||
}
|
257
vendor/github.com/go-ini/ini/section.go
generated
vendored
257
vendor/github.com/go-ini/ini/section.go
generated
vendored
@ -1,257 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// 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 ini
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Section represents a config section.
|
||||
type Section struct {
|
||||
f *File
|
||||
Comment string
|
||||
name string
|
||||
keys map[string]*Key
|
||||
keyList []string
|
||||
keysHash map[string]string
|
||||
|
||||
isRawSection bool
|
||||
rawBody string
|
||||
}
|
||||
|
||||
func newSection(f *File, name string) *Section {
|
||||
return &Section{
|
||||
f: f,
|
||||
name: name,
|
||||
keys: make(map[string]*Key),
|
||||
keyList: make([]string, 0, 10),
|
||||
keysHash: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns name of Section.
|
||||
func (s *Section) Name() string {
|
||||
return s.name
|
||||
}
|
||||
|
||||
// Body returns rawBody of Section if the section was marked as unparseable.
|
||||
// It still follows the other rules of the INI format surrounding leading/trailing whitespace.
|
||||
func (s *Section) Body() string {
|
||||
return strings.TrimSpace(s.rawBody)
|
||||
}
|
||||
|
||||
// SetBody updates body content only if section is raw.
|
||||
func (s *Section) SetBody(body string) {
|
||||
if !s.isRawSection {
|
||||
return
|
||||
}
|
||||
s.rawBody = body
|
||||
}
|
||||
|
||||
// NewKey creates a new key to given section.
|
||||
func (s *Section) NewKey(name, val string) (*Key, error) {
|
||||
if len(name) == 0 {
|
||||
return nil, errors.New("error creating new key: empty key name")
|
||||
} else if s.f.options.Insensitive {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
|
||||
if s.f.BlockMode {
|
||||
s.f.lock.Lock()
|
||||
defer s.f.lock.Unlock()
|
||||
}
|
||||
|
||||
if inSlice(name, s.keyList) {
|
||||
if s.f.options.AllowShadows {
|
||||
if err := s.keys[name].addShadow(val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
s.keys[name].value = val
|
||||
}
|
||||
return s.keys[name], nil
|
||||
}
|
||||
|
||||
s.keyList = append(s.keyList, name)
|
||||
s.keys[name] = newKey(s, name, val)
|
||||
s.keysHash[name] = val
|
||||
return s.keys[name], nil
|
||||
}
|
||||
|
||||
// NewBooleanKey creates a new boolean type key to given section.
|
||||
func (s *Section) NewBooleanKey(name string) (*Key, error) {
|
||||
key, err := s.NewKey(name, "true")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key.isBooleanType = true
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// GetKey returns key in section by given name.
|
||||
func (s *Section) GetKey(name string) (*Key, error) {
|
||||
// FIXME: change to section level lock?
|
||||
if s.f.BlockMode {
|
||||
s.f.lock.RLock()
|
||||
}
|
||||
if s.f.options.Insensitive {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
key := s.keys[name]
|
||||
if s.f.BlockMode {
|
||||
s.f.lock.RUnlock()
|
||||
}
|
||||
|
||||
if key == nil {
|
||||
// Check if it is a child-section.
|
||||
sname := s.name
|
||||
for {
|
||||
if i := strings.LastIndex(sname, "."); i > -1 {
|
||||
sname = sname[:i]
|
||||
sec, err := s.f.GetSection(sname)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return sec.GetKey(name)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name)
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// HasKey returns true if section contains a key with given name.
|
||||
func (s *Section) HasKey(name string) bool {
|
||||
key, _ := s.GetKey(name)
|
||||
return key != nil
|
||||
}
|
||||
|
||||
// Haskey is a backwards-compatible name for HasKey.
|
||||
// TODO: delete me in v2
|
||||
func (s *Section) Haskey(name string) bool {
|
||||
return s.HasKey(name)
|
||||
}
|
||||
|
||||
// HasValue returns true if section contains given raw value.
|
||||
func (s *Section) HasValue(value string) bool {
|
||||
if s.f.BlockMode {
|
||||
s.f.lock.RLock()
|
||||
defer s.f.lock.RUnlock()
|
||||
}
|
||||
|
||||
for _, k := range s.keys {
|
||||
if value == k.value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Key assumes named Key exists in section and returns a zero-value when not.
|
||||
func (s *Section) Key(name string) *Key {
|
||||
key, err := s.GetKey(name)
|
||||
if err != nil {
|
||||
// It's OK here because the only possible error is empty key name,
|
||||
// but if it's empty, this piece of code won't be executed.
|
||||
key, _ = s.NewKey(name, "")
|
||||
return key
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
// Keys returns list of keys of section.
|
||||
func (s *Section) Keys() []*Key {
|
||||
keys := make([]*Key, len(s.keyList))
|
||||
for i := range s.keyList {
|
||||
keys[i] = s.Key(s.keyList[i])
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// ParentKeys returns list of keys of parent section.
|
||||
func (s *Section) ParentKeys() []*Key {
|
||||
var parentKeys []*Key
|
||||
sname := s.name
|
||||
for {
|
||||
if i := strings.LastIndex(sname, "."); i > -1 {
|
||||
sname = sname[:i]
|
||||
sec, err := s.f.GetSection(sname)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
parentKeys = append(parentKeys, sec.Keys()...)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
return parentKeys
|
||||
}
|
||||
|
||||
// KeyStrings returns list of key names of section.
|
||||
func (s *Section) KeyStrings() []string {
|
||||
list := make([]string, len(s.keyList))
|
||||
copy(list, s.keyList)
|
||||
return list
|
||||
}
|
||||
|
||||
// KeysHash returns keys hash consisting of names and values.
|
||||
func (s *Section) KeysHash() map[string]string {
|
||||
if s.f.BlockMode {
|
||||
s.f.lock.RLock()
|
||||
defer s.f.lock.RUnlock()
|
||||
}
|
||||
|
||||
hash := map[string]string{}
|
||||
for key, value := range s.keysHash {
|
||||
hash[key] = value
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
// DeleteKey deletes a key from section.
|
||||
func (s *Section) DeleteKey(name string) {
|
||||
if s.f.BlockMode {
|
||||
s.f.lock.Lock()
|
||||
defer s.f.lock.Unlock()
|
||||
}
|
||||
|
||||
for i, k := range s.keyList {
|
||||
if k == name {
|
||||
s.keyList = append(s.keyList[:i], s.keyList[i+1:]...)
|
||||
delete(s.keys, name)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ChildSections returns a list of child sections of current section.
|
||||
// For example, "[parent.child1]" and "[parent.child12]" are child sections
|
||||
// of section "[parent]".
|
||||
func (s *Section) ChildSections() []*Section {
|
||||
prefix := s.name + "."
|
||||
children := make([]*Section, 0, 3)
|
||||
for _, name := range s.f.sectionList {
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
children = append(children, s.f.sections[name])
|
||||
}
|
||||
}
|
||||
return children
|
||||
}
|
512
vendor/github.com/go-ini/ini/struct.go
generated
vendored
512
vendor/github.com/go-ini/ini/struct.go
generated
vendored
@ -1,512 +0,0 @@
|
||||
// Copyright 2014 Unknwon
|
||||
//
|
||||
// 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 ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// NameMapper represents a ini tag name mapper.
|
||||
type NameMapper func(string) string
|
||||
|
||||
// Built-in name getters.
|
||||
var (
|
||||
// AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE.
|
||||
AllCapsUnderscore NameMapper = func(raw string) string {
|
||||
newstr := make([]rune, 0, len(raw))
|
||||
for i, chr := range raw {
|
||||
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
|
||||
if i > 0 {
|
||||
newstr = append(newstr, '_')
|
||||
}
|
||||
}
|
||||
newstr = append(newstr, unicode.ToUpper(chr))
|
||||
}
|
||||
return string(newstr)
|
||||
}
|
||||
// TitleUnderscore converts to format title_underscore.
|
||||
TitleUnderscore NameMapper = func(raw string) string {
|
||||
newstr := make([]rune, 0, len(raw))
|
||||
for i, chr := range raw {
|
||||
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
|
||||
if i > 0 {
|
||||
newstr = append(newstr, '_')
|
||||
}
|
||||
chr -= ('A' - 'a')
|
||||
}
|
||||
newstr = append(newstr, chr)
|
||||
}
|
||||
return string(newstr)
|
||||
}
|
||||
)
|
||||
|
||||
func (s *Section) parseFieldName(raw, actual string) string {
|
||||
if len(actual) > 0 {
|
||||
return actual
|
||||
}
|
||||
if s.f.NameMapper != nil {
|
||||
return s.f.NameMapper(raw)
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
func parseDelim(actual string) string {
|
||||
if len(actual) > 0 {
|
||||
return actual
|
||||
}
|
||||
return ","
|
||||
}
|
||||
|
||||
var reflectTime = reflect.TypeOf(time.Now()).Kind()
|
||||
|
||||
// setSliceWithProperType sets proper values to slice based on its type.
|
||||
func setSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error {
|
||||
var strs []string
|
||||
if allowShadow {
|
||||
strs = key.StringsWithShadows(delim)
|
||||
} else {
|
||||
strs = key.Strings(delim)
|
||||
}
|
||||
|
||||
numVals := len(strs)
|
||||
if numVals == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var vals interface{}
|
||||
var err error
|
||||
|
||||
sliceOf := field.Type().Elem().Kind()
|
||||
switch sliceOf {
|
||||
case reflect.String:
|
||||
vals = strs
|
||||
case reflect.Int:
|
||||
vals, err = key.parseInts(strs, true, false)
|
||||
case reflect.Int64:
|
||||
vals, err = key.parseInt64s(strs, true, false)
|
||||
case reflect.Uint:
|
||||
vals, err = key.parseUints(strs, true, false)
|
||||
case reflect.Uint64:
|
||||
vals, err = key.parseUint64s(strs, true, false)
|
||||
case reflect.Float64:
|
||||
vals, err = key.parseFloat64s(strs, true, false)
|
||||
case reflectTime:
|
||||
vals, err = key.parseTimesFormat(time.RFC3339, strs, true, false)
|
||||
default:
|
||||
return fmt.Errorf("unsupported type '[]%s'", sliceOf)
|
||||
}
|
||||
if err != nil && isStrict {
|
||||
return err
|
||||
}
|
||||
|
||||
slice := reflect.MakeSlice(field.Type(), numVals, numVals)
|
||||
for i := 0; i < numVals; i++ {
|
||||
switch sliceOf {
|
||||
case reflect.String:
|
||||
slice.Index(i).Set(reflect.ValueOf(vals.([]string)[i]))
|
||||
case reflect.Int:
|
||||
slice.Index(i).Set(reflect.ValueOf(vals.([]int)[i]))
|
||||
case reflect.Int64:
|
||||
slice.Index(i).Set(reflect.ValueOf(vals.([]int64)[i]))
|
||||
case reflect.Uint:
|
||||
slice.Index(i).Set(reflect.ValueOf(vals.([]uint)[i]))
|
||||
case reflect.Uint64:
|
||||
slice.Index(i).Set(reflect.ValueOf(vals.([]uint64)[i]))
|
||||
case reflect.Float64:
|
||||
slice.Index(i).Set(reflect.ValueOf(vals.([]float64)[i]))
|
||||
case reflectTime:
|
||||
slice.Index(i).Set(reflect.ValueOf(vals.([]time.Time)[i]))
|
||||
}
|
||||
}
|
||||
field.Set(slice)
|
||||
return nil
|
||||
}
|
||||
|
||||
func wrapStrictError(err error, isStrict bool) error {
|
||||
if isStrict {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setWithProperType sets proper value to field based on its type,
|
||||
// but it does not return error for failing parsing,
|
||||
// because we want to use default value that is already assigned to strcut.
|
||||
func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error {
|
||||
switch t.Kind() {
|
||||
case reflect.String:
|
||||
if len(key.String()) == 0 {
|
||||
return nil
|
||||
}
|
||||
field.SetString(key.String())
|
||||
case reflect.Bool:
|
||||
boolVal, err := key.Bool()
|
||||
if err != nil {
|
||||
return wrapStrictError(err, isStrict)
|
||||
}
|
||||
field.SetBool(boolVal)
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
durationVal, err := key.Duration()
|
||||
// Skip zero value
|
||||
if err == nil && int64(durationVal) > 0 {
|
||||
field.Set(reflect.ValueOf(durationVal))
|
||||
return nil
|
||||
}
|
||||
|
||||
intVal, err := key.Int64()
|
||||
if err != nil {
|
||||
return wrapStrictError(err, isStrict)
|
||||
}
|
||||
field.SetInt(intVal)
|
||||
// byte is an alias for uint8, so supporting uint8 breaks support for byte
|
||||
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
durationVal, err := key.Duration()
|
||||
// Skip zero value
|
||||
if err == nil && int(durationVal) > 0 {
|
||||
field.Set(reflect.ValueOf(durationVal))
|
||||
return nil
|
||||
}
|
||||
|
||||
uintVal, err := key.Uint64()
|
||||
if err != nil {
|
||||
return wrapStrictError(err, isStrict)
|
||||
}
|
||||
field.SetUint(uintVal)
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
floatVal, err := key.Float64()
|
||||
if err != nil {
|
||||
return wrapStrictError(err, isStrict)
|
||||
}
|
||||
field.SetFloat(floatVal)
|
||||
case reflectTime:
|
||||
timeVal, err := key.Time()
|
||||
if err != nil {
|
||||
return wrapStrictError(err, isStrict)
|
||||
}
|
||||
field.Set(reflect.ValueOf(timeVal))
|
||||
case reflect.Slice:
|
||||
return setSliceWithProperType(key, field, delim, allowShadow, isStrict)
|
||||
default:
|
||||
return fmt.Errorf("unsupported type '%s'", t)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool) {
|
||||
opts := strings.SplitN(tag, ",", 3)
|
||||
rawName = opts[0]
|
||||
if len(opts) > 1 {
|
||||
omitEmpty = opts[1] == "omitempty"
|
||||
}
|
||||
if len(opts) > 2 {
|
||||
allowShadow = opts[2] == "allowshadow"
|
||||
}
|
||||
return rawName, omitEmpty, allowShadow
|
||||
}
|
||||
|
||||
func (s *Section) mapTo(val reflect.Value, isStrict bool) error {
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val = val.Elem()
|
||||
}
|
||||
typ := val.Type()
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := val.Field(i)
|
||||
tpField := typ.Field(i)
|
||||
|
||||
tag := tpField.Tag.Get("ini")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
rawName, _, allowShadow := parseTagOptions(tag)
|
||||
fieldName := s.parseFieldName(tpField.Name, rawName)
|
||||
if len(fieldName) == 0 || !field.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
|
||||
isStruct := tpField.Type.Kind() == reflect.Struct
|
||||
if isAnonymous {
|
||||
field.Set(reflect.New(tpField.Type.Elem()))
|
||||
}
|
||||
|
||||
if isAnonymous || isStruct {
|
||||
if sec, err := s.f.GetSection(fieldName); err == nil {
|
||||
if err = sec.mapTo(field, isStrict); err != nil {
|
||||
return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if key, err := s.GetKey(fieldName); err == nil {
|
||||
delim := parseDelim(tpField.Tag.Get("delim"))
|
||||
if err = setWithProperType(tpField.Type, key, field, delim, allowShadow, isStrict); err != nil {
|
||||
return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MapTo maps section to given struct.
|
||||
func (s *Section) MapTo(v interface{}) error {
|
||||
typ := reflect.TypeOf(v)
|
||||
val := reflect.ValueOf(v)
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
val = val.Elem()
|
||||
} else {
|
||||
return errors.New("cannot map to non-pointer struct")
|
||||
}
|
||||
|
||||
return s.mapTo(val, false)
|
||||
}
|
||||
|
||||
// MapTo maps section to given struct in strict mode,
|
||||
// which returns all possible error including value parsing error.
|
||||
func (s *Section) StrictMapTo(v interface{}) error {
|
||||
typ := reflect.TypeOf(v)
|
||||
val := reflect.ValueOf(v)
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
val = val.Elem()
|
||||
} else {
|
||||
return errors.New("cannot map to non-pointer struct")
|
||||
}
|
||||
|
||||
return s.mapTo(val, true)
|
||||
}
|
||||
|
||||
// MapTo maps file to given struct.
|
||||
func (f *File) MapTo(v interface{}) error {
|
||||
return f.Section("").MapTo(v)
|
||||
}
|
||||
|
||||
// MapTo maps file to given struct in strict mode,
|
||||
// which returns all possible error including value parsing error.
|
||||
func (f *File) StrictMapTo(v interface{}) error {
|
||||
return f.Section("").StrictMapTo(v)
|
||||
}
|
||||
|
||||
// MapTo maps data sources to given struct with name mapper.
|
||||
func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
|
||||
cfg, err := Load(source, others...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.NameMapper = mapper
|
||||
return cfg.MapTo(v)
|
||||
}
|
||||
|
||||
// StrictMapToWithMapper maps data sources to given struct with name mapper in strict mode,
|
||||
// which returns all possible error including value parsing error.
|
||||
func StrictMapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
|
||||
cfg, err := Load(source, others...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.NameMapper = mapper
|
||||
return cfg.StrictMapTo(v)
|
||||
}
|
||||
|
||||
// MapTo maps data sources to given struct.
|
||||
func MapTo(v, source interface{}, others ...interface{}) error {
|
||||
return MapToWithMapper(v, nil, source, others...)
|
||||
}
|
||||
|
||||
// StrictMapTo maps data sources to given struct in strict mode,
|
||||
// which returns all possible error including value parsing error.
|
||||
func StrictMapTo(v, source interface{}, others ...interface{}) error {
|
||||
return StrictMapToWithMapper(v, nil, source, others...)
|
||||
}
|
||||
|
||||
// reflectSliceWithProperType does the opposite thing as setSliceWithProperType.
|
||||
func reflectSliceWithProperType(key *Key, field reflect.Value, delim string) error {
|
||||
slice := field.Slice(0, field.Len())
|
||||
if field.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
sliceOf := field.Type().Elem().Kind()
|
||||
for i := 0; i < field.Len(); i++ {
|
||||
switch sliceOf {
|
||||
case reflect.String:
|
||||
buf.WriteString(slice.Index(i).String())
|
||||
case reflect.Int, reflect.Int64:
|
||||
buf.WriteString(fmt.Sprint(slice.Index(i).Int()))
|
||||
case reflect.Uint, reflect.Uint64:
|
||||
buf.WriteString(fmt.Sprint(slice.Index(i).Uint()))
|
||||
case reflect.Float64:
|
||||
buf.WriteString(fmt.Sprint(slice.Index(i).Float()))
|
||||
case reflectTime:
|
||||
buf.WriteString(slice.Index(i).Interface().(time.Time).Format(time.RFC3339))
|
||||
default:
|
||||
return fmt.Errorf("unsupported type '[]%s'", sliceOf)
|
||||
}
|
||||
buf.WriteString(delim)
|
||||
}
|
||||
key.SetValue(buf.String()[:buf.Len()-1])
|
||||
return nil
|
||||
}
|
||||
|
||||
// reflectWithProperType does the opposite thing as setWithProperType.
|
||||
func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
|
||||
switch t.Kind() {
|
||||
case reflect.String:
|
||||
key.SetValue(field.String())
|
||||
case reflect.Bool:
|
||||
key.SetValue(fmt.Sprint(field.Bool()))
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
key.SetValue(fmt.Sprint(field.Int()))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
key.SetValue(fmt.Sprint(field.Uint()))
|
||||
case reflect.Float32, reflect.Float64:
|
||||
key.SetValue(fmt.Sprint(field.Float()))
|
||||
case reflectTime:
|
||||
key.SetValue(fmt.Sprint(field.Interface().(time.Time).Format(time.RFC3339)))
|
||||
case reflect.Slice:
|
||||
return reflectSliceWithProperType(key, field, delim)
|
||||
default:
|
||||
return fmt.Errorf("unsupported type '%s'", t)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CR: copied from encoding/json/encode.go with modifications of time.Time support.
|
||||
// TODO: add more test coverage.
|
||||
func isEmptyValue(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v.IsNil()
|
||||
case reflectTime:
|
||||
t, ok := v.Interface().(time.Time)
|
||||
return ok && t.IsZero()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Section) reflectFrom(val reflect.Value) error {
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val = val.Elem()
|
||||
}
|
||||
typ := val.Type()
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := val.Field(i)
|
||||
tpField := typ.Field(i)
|
||||
|
||||
tag := tpField.Tag.Get("ini")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
opts := strings.SplitN(tag, ",", 2)
|
||||
if len(opts) == 2 && opts[1] == "omitempty" && isEmptyValue(field) {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldName := s.parseFieldName(tpField.Name, opts[0])
|
||||
if len(fieldName) == 0 || !field.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) ||
|
||||
(tpField.Type.Kind() == reflect.Struct && tpField.Type.Name() != "Time") {
|
||||
// Note: The only error here is section doesn't exist.
|
||||
sec, err := s.f.GetSection(fieldName)
|
||||
if err != nil {
|
||||
// Note: fieldName can never be empty here, ignore error.
|
||||
sec, _ = s.f.NewSection(fieldName)
|
||||
}
|
||||
|
||||
// Add comment from comment tag
|
||||
if len(sec.Comment) == 0 {
|
||||
sec.Comment = tpField.Tag.Get("comment")
|
||||
}
|
||||
|
||||
if err = sec.reflectFrom(field); err != nil {
|
||||
return fmt.Errorf("error reflecting field (%s): %v", fieldName, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Note: Same reason as secion.
|
||||
key, err := s.GetKey(fieldName)
|
||||
if err != nil {
|
||||
key, _ = s.NewKey(fieldName, "")
|
||||
}
|
||||
|
||||
// Add comment from comment tag
|
||||
if len(key.Comment) == 0 {
|
||||
key.Comment = tpField.Tag.Get("comment")
|
||||
}
|
||||
|
||||
if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
|
||||
return fmt.Errorf("error reflecting field (%s): %v", fieldName, err)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReflectFrom reflects secion from given struct.
|
||||
func (s *Section) ReflectFrom(v interface{}) error {
|
||||
typ := reflect.TypeOf(v)
|
||||
val := reflect.ValueOf(v)
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
val = val.Elem()
|
||||
} else {
|
||||
return errors.New("cannot reflect from non-pointer struct")
|
||||
}
|
||||
|
||||
return s.reflectFrom(val)
|
||||
}
|
||||
|
||||
// ReflectFrom reflects file from given struct.
|
||||
func (f *File) ReflectFrom(v interface{}) error {
|
||||
return f.Section("").ReflectFrom(v)
|
||||
}
|
||||
|
||||
// ReflectFrom reflects data sources from given struct with name mapper.
|
||||
func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error {
|
||||
cfg.NameMapper = mapper
|
||||
return cfg.ReflectFrom(v)
|
||||
}
|
||||
|
||||
// ReflectFrom reflects data sources from given struct.
|
||||
func ReflectFrom(cfg *File, v interface{}) error {
|
||||
return ReflectFromWithMapper(cfg, v, nil)
|
||||
}
|
290
vendor/github.com/go-xorm/builder/builder.go
generated
vendored
290
vendor/github.com/go-xorm/builder/builder.go
generated
vendored
@ -4,6 +4,12 @@
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
sql2 "database/sql"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type optype byte
|
||||
|
||||
const (
|
||||
@ -12,6 +18,15 @@ const (
|
||||
insertType // insert
|
||||
updateType // update
|
||||
deleteType // delete
|
||||
unionType // union
|
||||
)
|
||||
|
||||
const (
|
||||
POSTGRES = "postgres"
|
||||
SQLITE = "sqlite3"
|
||||
MYSQL = "mysql"
|
||||
MSSQL = "mssql"
|
||||
ORACLE = "oracle"
|
||||
)
|
||||
|
||||
type join struct {
|
||||
@ -20,60 +35,115 @@ type join struct {
|
||||
joinCond Cond
|
||||
}
|
||||
|
||||
type union struct {
|
||||
unionType string
|
||||
builder *Builder
|
||||
}
|
||||
|
||||
type limit struct {
|
||||
limitN int
|
||||
offset int
|
||||
}
|
||||
|
||||
// Builder describes a SQL statement
|
||||
type Builder struct {
|
||||
optype
|
||||
tableName string
|
||||
cond Cond
|
||||
selects []string
|
||||
joins []join
|
||||
inserts Eq
|
||||
updates []Eq
|
||||
dialect string
|
||||
isNested bool
|
||||
into string
|
||||
from string
|
||||
subQuery *Builder
|
||||
cond Cond
|
||||
selects []string
|
||||
joins []join
|
||||
unions []union
|
||||
limitation *limit
|
||||
insertCols []string
|
||||
insertVals []interface{}
|
||||
updates []Eq
|
||||
orderBy string
|
||||
groupBy string
|
||||
having string
|
||||
}
|
||||
|
||||
// Select creates a select Builder
|
||||
func Select(cols ...string) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Select(cols...)
|
||||
// Dialect sets the db dialect of Builder.
|
||||
func Dialect(dialect string) *Builder {
|
||||
builder := &Builder{cond: NewCond(), dialect: dialect}
|
||||
return builder
|
||||
}
|
||||
|
||||
// Insert creates an insert Builder
|
||||
func Insert(eq Eq) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Insert(eq)
|
||||
// MySQL is shortcut of Dialect(MySQL)
|
||||
func MySQL() *Builder {
|
||||
return Dialect(MYSQL)
|
||||
}
|
||||
|
||||
// Update creates an update Builder
|
||||
func Update(updates ...Eq) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Update(updates...)
|
||||
// MsSQL is shortcut of Dialect(MsSQL)
|
||||
func MsSQL() *Builder {
|
||||
return Dialect(MSSQL)
|
||||
}
|
||||
|
||||
// Delete creates a delete Builder
|
||||
func Delete(conds ...Cond) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Delete(conds...)
|
||||
// Oracle is shortcut of Dialect(Oracle)
|
||||
func Oracle() *Builder {
|
||||
return Dialect(ORACLE)
|
||||
}
|
||||
|
||||
// Postgres is shortcut of Dialect(Postgres)
|
||||
func Postgres() *Builder {
|
||||
return Dialect(POSTGRES)
|
||||
}
|
||||
|
||||
// SQLite is shortcut of Dialect(SQLITE)
|
||||
func SQLite() *Builder {
|
||||
return Dialect(SQLITE)
|
||||
}
|
||||
|
||||
// Where sets where SQL
|
||||
func (b *Builder) Where(cond Cond) *Builder {
|
||||
b.cond = b.cond.And(cond)
|
||||
if b.cond.IsValid() {
|
||||
b.cond = b.cond.And(cond)
|
||||
} else {
|
||||
b.cond = cond
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// From sets the table name
|
||||
func (b *Builder) From(tableName string) *Builder {
|
||||
b.tableName = tableName
|
||||
// From sets from subject(can be a table name in string or a builder pointer) and its alias
|
||||
func (b *Builder) From(subject interface{}, alias ...string) *Builder {
|
||||
switch subject.(type) {
|
||||
case *Builder:
|
||||
b.subQuery = subject.(*Builder)
|
||||
|
||||
if len(alias) > 0 {
|
||||
b.from = alias[0]
|
||||
} else {
|
||||
b.isNested = true
|
||||
}
|
||||
case string:
|
||||
b.from = subject.(string)
|
||||
|
||||
if len(alias) > 0 {
|
||||
b.from = b.from + " " + alias[0]
|
||||
}
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// TableName returns the table name
|
||||
func (b *Builder) TableName() string {
|
||||
if b.optype == insertType {
|
||||
return b.into
|
||||
}
|
||||
return b.from
|
||||
}
|
||||
|
||||
// Into sets insert table name
|
||||
func (b *Builder) Into(tableName string) *Builder {
|
||||
b.tableName = tableName
|
||||
b.into = tableName
|
||||
return b
|
||||
}
|
||||
|
||||
// Join sets join table and contions
|
||||
// Join sets join table and conditions
|
||||
func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builder {
|
||||
switch joinCond.(type) {
|
||||
case Cond:
|
||||
@ -85,6 +155,50 @@ func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builde
|
||||
return b
|
||||
}
|
||||
|
||||
// Union sets union conditions
|
||||
func (b *Builder) Union(unionTp string, unionCond *Builder) *Builder {
|
||||
var builder *Builder
|
||||
if b.optype != unionType {
|
||||
builder = &Builder{cond: NewCond()}
|
||||
builder.optype = unionType
|
||||
builder.dialect = b.dialect
|
||||
builder.selects = b.selects
|
||||
|
||||
currentUnions := b.unions
|
||||
// erase sub unions (actually append to new Builder.unions)
|
||||
b.unions = nil
|
||||
|
||||
for e := range currentUnions {
|
||||
currentUnions[e].builder.dialect = b.dialect
|
||||
}
|
||||
|
||||
builder.unions = append(append(builder.unions, union{"", b}), currentUnions...)
|
||||
} else {
|
||||
builder = b
|
||||
}
|
||||
|
||||
if unionCond != nil {
|
||||
if unionCond.dialect == "" && builder.dialect != "" {
|
||||
unionCond.dialect = builder.dialect
|
||||
}
|
||||
|
||||
builder.unions = append(builder.unions, union{unionTp, unionCond})
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
// Limit sets limitN condition
|
||||
func (b *Builder) Limit(limitN int, offset ...int) *Builder {
|
||||
b.limitation = &limit{limitN: limitN}
|
||||
|
||||
if len(offset) > 0 {
|
||||
b.limitation.offset = offset[0]
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// InnerJoin sets inner join
|
||||
func (b *Builder) InnerJoin(joinTable string, joinCond interface{}) *Builder {
|
||||
return b.Join("INNER", joinTable, joinCond)
|
||||
@ -113,7 +227,9 @@ func (b *Builder) FullJoin(joinTable string, joinCond interface{}) *Builder {
|
||||
// Select sets select SQL
|
||||
func (b *Builder) Select(cols ...string) *Builder {
|
||||
b.selects = cols
|
||||
b.optype = selectType
|
||||
if b.optype == condType {
|
||||
b.optype = selectType
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
@ -129,16 +245,70 @@ func (b *Builder) Or(cond Cond) *Builder {
|
||||
return b
|
||||
}
|
||||
|
||||
type insertColsSorter struct {
|
||||
cols []string
|
||||
vals []interface{}
|
||||
}
|
||||
|
||||
func (s insertColsSorter) Len() int {
|
||||
return len(s.cols)
|
||||
}
|
||||
func (s insertColsSorter) Swap(i, j int) {
|
||||
s.cols[i], s.cols[j] = s.cols[j], s.cols[i]
|
||||
s.vals[i], s.vals[j] = s.vals[j], s.vals[i]
|
||||
}
|
||||
|
||||
func (s insertColsSorter) Less(i, j int) bool {
|
||||
return s.cols[i] < s.cols[j]
|
||||
}
|
||||
|
||||
// Insert sets insert SQL
|
||||
func (b *Builder) Insert(eq Eq) *Builder {
|
||||
b.inserts = eq
|
||||
func (b *Builder) Insert(eq ...interface{}) *Builder {
|
||||
if len(eq) > 0 {
|
||||
var paramType = -1
|
||||
for _, e := range eq {
|
||||
switch t := e.(type) {
|
||||
case Eq:
|
||||
if paramType == -1 {
|
||||
paramType = 0
|
||||
}
|
||||
if paramType != 0 {
|
||||
break
|
||||
}
|
||||
for k, v := range t {
|
||||
b.insertCols = append(b.insertCols, k)
|
||||
b.insertVals = append(b.insertVals, v)
|
||||
}
|
||||
case string:
|
||||
if paramType == -1 {
|
||||
paramType = 1
|
||||
}
|
||||
if paramType != 1 {
|
||||
break
|
||||
}
|
||||
b.insertCols = append(b.insertCols, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(b.insertCols) == len(b.insertVals) {
|
||||
sort.Sort(insertColsSorter{
|
||||
cols: b.insertCols,
|
||||
vals: b.insertVals,
|
||||
})
|
||||
}
|
||||
b.optype = insertType
|
||||
return b
|
||||
}
|
||||
|
||||
// Update sets update SQL
|
||||
func (b *Builder) Update(updates ...Eq) *Builder {
|
||||
b.updates = updates
|
||||
b.updates = make([]Eq, 0, len(updates))
|
||||
for _, update := range updates {
|
||||
if update.IsValid() {
|
||||
b.updates = append(b.updates, update)
|
||||
}
|
||||
}
|
||||
b.optype = updateType
|
||||
return b
|
||||
}
|
||||
@ -153,8 +323,8 @@ func (b *Builder) Delete(conds ...Cond) *Builder {
|
||||
// WriteTo implements Writer interface
|
||||
func (b *Builder) WriteTo(w Writer) error {
|
||||
switch b.optype {
|
||||
case condType:
|
||||
return b.cond.WriteTo(w)
|
||||
/*case condType:
|
||||
return b.cond.WriteTo(w)*/
|
||||
case selectType:
|
||||
return b.selectWriteTo(w)
|
||||
case insertType:
|
||||
@ -163,6 +333,8 @@ func (b *Builder) WriteTo(w Writer) error {
|
||||
return b.updateWriteTo(w)
|
||||
case deleteType:
|
||||
return b.deleteWriteTo(w)
|
||||
case unionType:
|
||||
return b.unionWriteTo(w)
|
||||
}
|
||||
|
||||
return ErrNotSupportType
|
||||
@ -175,16 +347,48 @@ func (b *Builder) ToSQL() (string, []interface{}, error) {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return w.writer.String(), w.args, nil
|
||||
// in case of sql.NamedArg in args
|
||||
for e := range w.args {
|
||||
if namedArg, ok := w.args[e].(sql2.NamedArg); ok {
|
||||
w.args[e] = namedArg.Value
|
||||
}
|
||||
}
|
||||
|
||||
var sql = w.writer.String()
|
||||
var err error
|
||||
|
||||
switch b.dialect {
|
||||
case ORACLE, MSSQL:
|
||||
// This is for compatibility with different sql drivers
|
||||
for e := range w.args {
|
||||
w.args[e] = sql2.Named(fmt.Sprintf("p%d", e+1), w.args[e])
|
||||
}
|
||||
|
||||
var prefix string
|
||||
if b.dialect == ORACLE {
|
||||
prefix = ":p"
|
||||
} else {
|
||||
prefix = "@p"
|
||||
}
|
||||
|
||||
if sql, err = ConvertPlaceholder(sql, prefix); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
case POSTGRES:
|
||||
if sql, err = ConvertPlaceholder(sql, "$"); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return sql, w.args, nil
|
||||
}
|
||||
|
||||
// ToSQL convert a builder or condtions to SQL and args
|
||||
func ToSQL(cond interface{}) (string, []interface{}, error) {
|
||||
switch cond.(type) {
|
||||
case Cond:
|
||||
return condToSQL(cond.(Cond))
|
||||
case *Builder:
|
||||
return cond.(*Builder).ToSQL()
|
||||
// ToBoundSQL
|
||||
func (b *Builder) ToBoundSQL() (string, error) {
|
||||
w := NewWriter()
|
||||
if err := b.WriteTo(w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", nil, ErrNotSupportType
|
||||
|
||||
return ConvertToBoundSQL(w.writer.String(), w.args)
|
||||
}
|
||||
|
13
vendor/github.com/go-xorm/builder/builder_delete.go
generated
vendored
13
vendor/github.com/go-xorm/builder/builder_delete.go
generated
vendored
@ -5,16 +5,21 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Delete creates a delete Builder
|
||||
func Delete(conds ...Cond) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Delete(conds...)
|
||||
}
|
||||
|
||||
func (b *Builder) deleteWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
if len(b.from) <= 0 {
|
||||
return ErrNoTableName
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "DELETE FROM %s WHERE ", b.tableName); err != nil {
|
||||
if _, err := fmt.Fprintf(w, "DELETE FROM %s WHERE ", b.from); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
51
vendor/github.com/go-xorm/builder/builder_insert.go
generated
vendored
51
vendor/github.com/go-xorm/builder/builder_insert.go
generated
vendored
@ -6,39 +6,63 @@ package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (b *Builder) insertWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
}
|
||||
if len(b.inserts) <= 0 {
|
||||
return errors.New("no column to be insert")
|
||||
// Insert creates an insert Builder
|
||||
func Insert(eq ...interface{}) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Insert(eq...)
|
||||
}
|
||||
|
||||
func (b *Builder) insertSelectWriteTo(w Writer) error {
|
||||
if _, err := fmt.Fprintf(w, "INSERT INTO %s ", b.into); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "INSERT INTO %s (", b.tableName); err != nil {
|
||||
if len(b.insertCols) > 0 {
|
||||
fmt.Fprintf(w, "(")
|
||||
for _, col := range b.insertCols {
|
||||
fmt.Fprintf(w, col)
|
||||
}
|
||||
fmt.Fprintf(w, ") ")
|
||||
}
|
||||
|
||||
return b.selectWriteTo(w)
|
||||
}
|
||||
|
||||
func (b *Builder) insertWriteTo(w Writer) error {
|
||||
if len(b.into) <= 0 {
|
||||
return ErrNoTableName
|
||||
}
|
||||
if len(b.insertCols) <= 0 && b.from == "" {
|
||||
return ErrNoColumnToInsert
|
||||
}
|
||||
|
||||
if b.into != "" && b.from != "" {
|
||||
return b.insertSelectWriteTo(w)
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "INSERT INTO %s (", b.into); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var args = make([]interface{}, 0)
|
||||
var bs []byte
|
||||
var valBuffer = bytes.NewBuffer(bs)
|
||||
var i = 0
|
||||
|
||||
for _, col := range b.inserts.sortedKeys() {
|
||||
value := b.inserts[col]
|
||||
for i, col := range b.insertCols {
|
||||
value := b.insertVals[i]
|
||||
fmt.Fprint(w, col)
|
||||
if e, ok := value.(expr); ok {
|
||||
fmt.Fprint(valBuffer, e.sql)
|
||||
fmt.Fprintf(valBuffer, "(%s)", e.sql)
|
||||
args = append(args, e.args...)
|
||||
} else {
|
||||
fmt.Fprint(valBuffer, "?")
|
||||
args = append(args, value)
|
||||
}
|
||||
|
||||
if i != len(b.inserts)-1 {
|
||||
if i != len(b.insertCols)-1 {
|
||||
if _, err := fmt.Fprint(w, ","); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -46,7 +70,6 @@ func (b *Builder) insertWriteTo(w Writer) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, ") Values ("); err != nil {
|
||||
|
100
vendor/github.com/go-xorm/builder/builder_limit.go
generated
vendored
Normal file
100
vendor/github.com/go-xorm/builder/builder_limit.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (b *Builder) limitWriteTo(w Writer) error {
|
||||
if strings.TrimSpace(b.dialect) == "" {
|
||||
return ErrDialectNotSetUp
|
||||
}
|
||||
|
||||
if b.limitation != nil {
|
||||
limit := b.limitation
|
||||
if limit.offset < 0 || limit.limitN <= 0 {
|
||||
return ErrInvalidLimitation
|
||||
}
|
||||
// erase limit condition
|
||||
b.limitation = nil
|
||||
ow := w.(*BytesWriter)
|
||||
|
||||
switch strings.ToLower(strings.TrimSpace(b.dialect)) {
|
||||
case ORACLE:
|
||||
if len(b.selects) == 0 {
|
||||
b.selects = append(b.selects, "*")
|
||||
}
|
||||
|
||||
var final *Builder
|
||||
selects := b.selects
|
||||
b.selects = append(selects, "ROWNUM RN")
|
||||
|
||||
var wb *Builder
|
||||
if b.optype == unionType {
|
||||
wb = Dialect(b.dialect).Select("at.*", "ROWNUM RN").
|
||||
From(b, "at")
|
||||
} else {
|
||||
wb = b
|
||||
}
|
||||
|
||||
if limit.offset == 0 {
|
||||
final = Dialect(b.dialect).Select(selects...).From(wb, "at").
|
||||
Where(Lte{"at.RN": limit.limitN})
|
||||
} else {
|
||||
sub := Dialect(b.dialect).Select("*").
|
||||
From(b, "at").Where(Lte{"at.RN": limit.offset + limit.limitN})
|
||||
|
||||
final = Dialect(b.dialect).Select(selects...).From(sub, "att").
|
||||
Where(Gt{"att.RN": limit.offset})
|
||||
}
|
||||
|
||||
return final.WriteTo(ow)
|
||||
case SQLITE, MYSQL, POSTGRES:
|
||||
// if type UNION, we need to write previous content back to current writer
|
||||
if b.optype == unionType {
|
||||
if err := b.WriteTo(ow); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if limit.offset == 0 {
|
||||
fmt.Fprint(ow, " LIMIT ", limit.limitN)
|
||||
} else {
|
||||
fmt.Fprintf(ow, " LIMIT %v OFFSET %v", limit.limitN, limit.offset)
|
||||
}
|
||||
case MSSQL:
|
||||
if len(b.selects) == 0 {
|
||||
b.selects = append(b.selects, "*")
|
||||
}
|
||||
|
||||
var final *Builder
|
||||
selects := b.selects
|
||||
b.selects = append(append([]string{fmt.Sprintf("TOP %d %v", limit.limitN+limit.offset, b.selects[0])},
|
||||
b.selects[1:]...), "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN")
|
||||
|
||||
var wb *Builder
|
||||
if b.optype == unionType {
|
||||
wb = Dialect(b.dialect).Select("*", "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN").
|
||||
From(b, "at")
|
||||
} else {
|
||||
wb = b
|
||||
}
|
||||
|
||||
if limit.offset == 0 {
|
||||
final = Dialect(b.dialect).Select(selects...).From(wb, "at")
|
||||
} else {
|
||||
final = Dialect(b.dialect).Select(selects...).From(wb, "at").Where(Gt{"at.RN": limit.offset})
|
||||
}
|
||||
|
||||
return final.WriteTo(ow)
|
||||
default:
|
||||
return ErrNotSupportType
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
110
vendor/github.com/go-xorm/builder/builder_select.go
generated
vendored
110
vendor/github.com/go-xorm/builder/builder_select.go
generated
vendored
@ -5,13 +5,24 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Select creates a select Builder
|
||||
func Select(cols ...string) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Select(cols...)
|
||||
}
|
||||
|
||||
func (b *Builder) selectWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
if len(b.from) <= 0 && !b.isNested {
|
||||
return ErrNoTableName
|
||||
}
|
||||
|
||||
// perform limit before writing to writer when b.dialect between ORACLE and MSSQL
|
||||
// this avoid a duplicate writing problem in simple limit query
|
||||
if b.limitation != nil && (b.dialect == ORACLE || b.dialect == MSSQL) {
|
||||
return b.limitWriteTo(w)
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, "SELECT "); err != nil {
|
||||
@ -34,24 +45,101 @@ func (b *Builder) selectWriteTo(w Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, " FROM %s", b.tableName); err != nil {
|
||||
return err
|
||||
if b.subQuery == nil {
|
||||
if _, err := fmt.Fprint(w, " FROM ", b.from); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if b.cond.IsValid() && len(b.from) <= 0 {
|
||||
return ErrUnnamedDerivedTable
|
||||
}
|
||||
if b.subQuery.dialect != "" && b.dialect != b.subQuery.dialect {
|
||||
return ErrInconsistentDialect
|
||||
}
|
||||
|
||||
// dialect of sub-query will inherit from the main one (if not set up)
|
||||
if b.dialect != "" && b.subQuery.dialect == "" {
|
||||
b.subQuery.dialect = b.dialect
|
||||
}
|
||||
|
||||
switch b.subQuery.optype {
|
||||
case selectType, unionType:
|
||||
fmt.Fprint(w, " FROM (")
|
||||
if err := b.subQuery.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(b.from) == 0 {
|
||||
fmt.Fprintf(w, ")")
|
||||
} else {
|
||||
fmt.Fprintf(w, ") %v", b.from)
|
||||
}
|
||||
default:
|
||||
return ErrUnexpectedSubQuery
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range b.joins {
|
||||
fmt.Fprintf(w, " %s JOIN %s ON ", v.joinType, v.joinTable)
|
||||
if _, err := fmt.Fprintf(w, " %s JOIN %s ON ", v.joinType, v.joinTable); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := v.joinCond.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !b.cond.IsValid() {
|
||||
return nil
|
||||
if b.cond.IsValid() {
|
||||
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.cond.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
|
||||
return err
|
||||
if len(b.groupBy) > 0 {
|
||||
if _, err := fmt.Fprint(w, " GROUP BY ", b.groupBy); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return b.cond.WriteTo(w)
|
||||
if len(b.having) > 0 {
|
||||
if _, err := fmt.Fprint(w, " HAVING ", b.having); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(b.orderBy) > 0 {
|
||||
if _, err := fmt.Fprint(w, " ORDER BY ", b.orderBy); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if b.limitation != nil {
|
||||
if err := b.limitWriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OrderBy orderBy SQL
|
||||
func (b *Builder) OrderBy(orderBy string) *Builder {
|
||||
b.orderBy = orderBy
|
||||
return b
|
||||
}
|
||||
|
||||
// GroupBy groupby SQL
|
||||
func (b *Builder) GroupBy(groupby string) *Builder {
|
||||
b.groupBy = groupby
|
||||
return b
|
||||
}
|
||||
|
||||
// Having having SQL
|
||||
func (b *Builder) Having(having string) *Builder {
|
||||
b.having = having
|
||||
return b
|
||||
}
|
||||
|
47
vendor/github.com/go-xorm/builder/builder_union.go
generated
vendored
Normal file
47
vendor/github.com/go-xorm/builder/builder_union.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (b *Builder) unionWriteTo(w Writer) error {
|
||||
if b.limitation != nil || b.cond.IsValid() ||
|
||||
b.orderBy != "" || b.having != "" || b.groupBy != "" {
|
||||
return ErrNotUnexpectedUnionConditions
|
||||
}
|
||||
|
||||
for idx, u := range b.unions {
|
||||
current := u.builder
|
||||
if current.optype != selectType {
|
||||
return ErrUnsupportedUnionMembers
|
||||
}
|
||||
|
||||
if len(b.unions) == 1 {
|
||||
if err := current.selectWriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if b.dialect != "" && b.dialect != current.dialect {
|
||||
return ErrInconsistentDialect
|
||||
}
|
||||
|
||||
if idx != 0 {
|
||||
fmt.Fprint(w, fmt.Sprintf(" UNION %v ", strings.ToUpper(u.unionType)))
|
||||
}
|
||||
fmt.Fprint(w, "(")
|
||||
|
||||
if err := current.selectWriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprint(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
15
vendor/github.com/go-xorm/builder/builder_update.go
generated
vendored
15
vendor/github.com/go-xorm/builder/builder_update.go
generated
vendored
@ -5,19 +5,24 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Update creates an update Builder
|
||||
func Update(updates ...Eq) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Update(updates...)
|
||||
}
|
||||
|
||||
func (b *Builder) updateWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
if len(b.from) <= 0 {
|
||||
return ErrNoTableName
|
||||
}
|
||||
if len(b.updates) <= 0 {
|
||||
return errors.New("no column to be update")
|
||||
return ErrNoColumnToUpdate
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "UPDATE %s SET ", b.tableName); err != nil {
|
||||
if _, err := fmt.Fprintf(w, "UPDATE %s SET ", b.from); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
21
vendor/github.com/go-xorm/builder/cond.go
generated
vendored
21
vendor/github.com/go-xorm/builder/cond.go
generated
vendored
@ -5,7 +5,6 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
)
|
||||
|
||||
@ -19,15 +18,15 @@ var _ Writer = NewWriter()
|
||||
|
||||
// BytesWriter implments Writer and save SQL in bytes.Buffer
|
||||
type BytesWriter struct {
|
||||
writer *bytes.Buffer
|
||||
buffer []byte
|
||||
writer *StringBuilder
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
// NewWriter creates a new string writer
|
||||
func NewWriter() *BytesWriter {
|
||||
w := &BytesWriter{}
|
||||
w.writer = bytes.NewBuffer(w.buffer)
|
||||
w := &BytesWriter{
|
||||
writer: &StringBuilder{},
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
@ -73,15 +72,3 @@ func (condEmpty) Or(conds ...Cond) Cond {
|
||||
func (condEmpty) IsValid() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func condToSQL(cond Cond) (string, []interface{}, error) {
|
||||
if cond == nil || !cond.IsValid() {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
w := NewWriter()
|
||||
if err := cond.WriteTo(w); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return w.writer.String(), w.args, nil
|
||||
}
|
||||
|
29
vendor/github.com/go-xorm/builder/cond_between.go
generated
vendored
29
vendor/github.com/go-xorm/builder/cond_between.go
generated
vendored
@ -17,10 +17,35 @@ var _ Cond = Between{}
|
||||
|
||||
// WriteTo write data to Writer
|
||||
func (between Between) WriteTo(w Writer) error {
|
||||
if _, err := fmt.Fprintf(w, "%s BETWEEN ? AND ?", between.Col); err != nil {
|
||||
if _, err := fmt.Fprintf(w, "%s BETWEEN ", between.Col); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Append(between.LessVal, between.MoreVal)
|
||||
if lv, ok := between.LessVal.(expr); ok {
|
||||
if err := lv.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(w, "?"); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Append(between.LessVal)
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, " AND "); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mv, ok := between.MoreVal.(expr); ok {
|
||||
if err := mv.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(w, "?"); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Append(between.MoreVal)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
4
vendor/github.com/go-xorm/builder/cond_or.go
generated
vendored
4
vendor/github.com/go-xorm/builder/cond_or.go
generated
vendored
@ -27,10 +27,12 @@ func (o condOr) WriteTo(w Writer) error {
|
||||
for i, cond := range o {
|
||||
var needQuote bool
|
||||
switch cond.(type) {
|
||||
case condAnd:
|
||||
case condAnd, expr:
|
||||
needQuote = true
|
||||
case Eq:
|
||||
needQuote = (len(cond.(Eq)) > 1)
|
||||
case Neq:
|
||||
needQuote = (len(cond.(Neq)) > 1)
|
||||
}
|
||||
|
||||
if needQuote {
|
||||
|
26
vendor/github.com/go-xorm/builder/error.go
generated
vendored
26
vendor/github.com/go-xorm/builder/error.go
generated
vendored
@ -8,9 +8,33 @@ import "errors"
|
||||
|
||||
var (
|
||||
// ErrNotSupportType not supported SQL type error
|
||||
ErrNotSupportType = errors.New("not supported SQL type")
|
||||
ErrNotSupportType = errors.New("Not supported SQL type")
|
||||
// ErrNoNotInConditions no NOT IN params error
|
||||
ErrNoNotInConditions = errors.New("No NOT IN conditions")
|
||||
// ErrNoInConditions no IN params error
|
||||
ErrNoInConditions = errors.New("No IN conditions")
|
||||
// ErrNeedMoreArguments need more arguments
|
||||
ErrNeedMoreArguments = errors.New("Need more sql arguments")
|
||||
// ErrNoTableName no table name
|
||||
ErrNoTableName = errors.New("No table indicated")
|
||||
// ErrNoColumnToInsert no column to update
|
||||
ErrNoColumnToUpdate = errors.New("No column(s) to update")
|
||||
// ErrNoColumnToInsert no column to update
|
||||
ErrNoColumnToInsert = errors.New("No column(s) to insert")
|
||||
// ErrNotSupportDialectType not supported dialect type error
|
||||
ErrNotSupportDialectType = errors.New("Not supported dialect type")
|
||||
// ErrNotUnexpectedUnionConditions using union in a wrong way
|
||||
ErrNotUnexpectedUnionConditions = errors.New("Unexpected conditional fields in UNION query")
|
||||
// ErrUnsupportedUnionMembers unexpected members in UNION query
|
||||
ErrUnsupportedUnionMembers = errors.New("Unexpected members in UNION query")
|
||||
// ErrUnexpectedSubQuery Unexpected sub-query in SELECT query
|
||||
ErrUnexpectedSubQuery = errors.New("Unexpected sub-query in SELECT query")
|
||||
// ErrDialectNotSetUp dialect is not setup yet
|
||||
ErrDialectNotSetUp = errors.New("Dialect is not setup yet, try to use `Dialect(dbType)` at first")
|
||||
// ErrInvalidLimitation offset or limit is not correct
|
||||
ErrInvalidLimitation = errors.New("Offset or limit is not correct")
|
||||
// ErrUnnamedDerivedTable Every derived table must have its own alias
|
||||
ErrUnnamedDerivedTable = errors.New("Every derived table must have its own alias")
|
||||
// ErrInconsistentDialect Inconsistent dialect in same builder
|
||||
ErrInconsistentDialect = errors.New("Inconsistent dialect in same builder")
|
||||
)
|
||||
|
156
vendor/github.com/go-xorm/builder/sql.go
generated
vendored
Normal file
156
vendor/github.com/go-xorm/builder/sql.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
sql2 "database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func condToSQL(cond Cond) (string, []interface{}, error) {
|
||||
if cond == nil || !cond.IsValid() {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
w := NewWriter()
|
||||
if err := cond.WriteTo(w); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return w.writer.String(), w.args, nil
|
||||
}
|
||||
|
||||
func condToBoundSQL(cond Cond) (string, error) {
|
||||
if cond == nil || !cond.IsValid() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
w := NewWriter()
|
||||
if err := cond.WriteTo(w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ConvertToBoundSQL(w.writer.String(), w.args)
|
||||
}
|
||||
|
||||
// ToSQL convert a builder or conditions to SQL and args
|
||||
func ToSQL(cond interface{}) (string, []interface{}, error) {
|
||||
switch cond.(type) {
|
||||
case Cond:
|
||||
return condToSQL(cond.(Cond))
|
||||
case *Builder:
|
||||
return cond.(*Builder).ToSQL()
|
||||
}
|
||||
return "", nil, ErrNotSupportType
|
||||
}
|
||||
|
||||
// ToBoundSQL convert a builder or conditions to parameters bound SQL
|
||||
func ToBoundSQL(cond interface{}) (string, error) {
|
||||
switch cond.(type) {
|
||||
case Cond:
|
||||
return condToBoundSQL(cond.(Cond))
|
||||
case *Builder:
|
||||
return cond.(*Builder).ToBoundSQL()
|
||||
}
|
||||
return "", ErrNotSupportType
|
||||
}
|
||||
|
||||
func noSQLQuoteNeeded(a interface{}) bool {
|
||||
switch a.(type) {
|
||||
case int, int8, int16, int32, int64:
|
||||
return true
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
return true
|
||||
case float32, float64:
|
||||
return true
|
||||
case bool:
|
||||
return true
|
||||
case string:
|
||||
return false
|
||||
case time.Time, *time.Time:
|
||||
return false
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(a)
|
||||
switch t.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return true
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return true
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return true
|
||||
case reflect.Bool:
|
||||
return true
|
||||
case reflect.String:
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ConvertToBoundSQL will convert SQL and args to a bound SQL
|
||||
func ConvertToBoundSQL(sql string, args []interface{}) (string, error) {
|
||||
buf := StringBuilder{}
|
||||
var i, j, start int
|
||||
for ; i < len(sql); i++ {
|
||||
if sql[i] == '?' {
|
||||
_, err := buf.WriteString(sql[start:i])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
start = i + 1
|
||||
|
||||
if len(args) == j {
|
||||
return "", ErrNeedMoreArguments
|
||||
}
|
||||
|
||||
arg := args[j]
|
||||
if namedArg, ok := arg.(sql2.NamedArg); ok {
|
||||
arg = namedArg.Value
|
||||
}
|
||||
|
||||
if noSQLQuoteNeeded(arg) {
|
||||
_, err = fmt.Fprint(&buf, arg)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(&buf, "'%v'", arg)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
}
|
||||
_, err := buf.WriteString(sql[start:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// ConvertPlaceholder replaces ? to $1, $2 ... or :1, :2 ... according prefix
|
||||
func ConvertPlaceholder(sql, prefix string) (string, error) {
|
||||
buf := StringBuilder{}
|
||||
var i, j, start int
|
||||
for ; i < len(sql); i++ {
|
||||
if sql[i] == '?' {
|
||||
if _, err := buf.WriteString(sql[start:i]); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
start = i + 1
|
||||
j = j + 1
|
||||
|
||||
if _, err := buf.WriteString(fmt.Sprintf("%v%d", prefix, j)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := buf.WriteString(sql[start:]); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
119
vendor/github.com/go-xorm/builder/string_builder.go
generated
vendored
Normal file
119
vendor/github.com/go-xorm/builder/string_builder.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// A StringBuilder is used to efficiently build a string using Write methods.
|
||||
// It minimizes memory copying. The zero value is ready to use.
|
||||
// Do not copy a non-zero Builder.
|
||||
type StringBuilder struct {
|
||||
addr *StringBuilder // of receiver, to detect copies by value
|
||||
buf []byte
|
||||
}
|
||||
|
||||
// noescape hides a pointer from escape analysis. noescape is
|
||||
// the identity function but escape analysis doesn't think the
|
||||
// output depends on the input. noescape is inlined and currently
|
||||
// compiles down to zero instructions.
|
||||
// USE CAREFULLY!
|
||||
// This was copied from the runtime; see issues 23382 and 7921.
|
||||
//go:nosplit
|
||||
func noescape(p unsafe.Pointer) unsafe.Pointer {
|
||||
x := uintptr(p)
|
||||
return unsafe.Pointer(x ^ 0)
|
||||
}
|
||||
|
||||
func (b *StringBuilder) copyCheck() {
|
||||
if b.addr == nil {
|
||||
// This hack works around a failing of Go's escape analysis
|
||||
// that was causing b to escape and be heap allocated.
|
||||
// See issue 23382.
|
||||
// TODO: once issue 7921 is fixed, this should be reverted to
|
||||
// just "b.addr = b".
|
||||
b.addr = (*StringBuilder)(noescape(unsafe.Pointer(b)))
|
||||
} else if b.addr != b {
|
||||
panic("strings: illegal use of non-zero Builder copied by value")
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the accumulated string.
|
||||
func (b *StringBuilder) String() string {
|
||||
return *(*string)(unsafe.Pointer(&b.buf))
|
||||
}
|
||||
|
||||
// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
|
||||
func (b *StringBuilder) Len() int { return len(b.buf) }
|
||||
|
||||
// Reset resets the Builder to be empty.
|
||||
func (b *StringBuilder) Reset() {
|
||||
b.addr = nil
|
||||
b.buf = nil
|
||||
}
|
||||
|
||||
// grow copies the buffer to a new, larger buffer so that there are at least n
|
||||
// bytes of capacity beyond len(b.buf).
|
||||
func (b *StringBuilder) grow(n int) {
|
||||
buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)
|
||||
copy(buf, b.buf)
|
||||
b.buf = buf
|
||||
}
|
||||
|
||||
// Grow grows b's capacity, if necessary, to guarantee space for
|
||||
// another n bytes. After Grow(n), at least n bytes can be written to b
|
||||
// without another allocation. If n is negative, Grow panics.
|
||||
func (b *StringBuilder) Grow(n int) {
|
||||
b.copyCheck()
|
||||
if n < 0 {
|
||||
panic("strings.Builder.Grow: negative count")
|
||||
}
|
||||
if cap(b.buf)-len(b.buf) < n {
|
||||
b.grow(n)
|
||||
}
|
||||
}
|
||||
|
||||
// Write appends the contents of p to b's buffer.
|
||||
// Write always returns len(p), nil.
|
||||
func (b *StringBuilder) Write(p []byte) (int, error) {
|
||||
b.copyCheck()
|
||||
b.buf = append(b.buf, p...)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// WriteByte appends the byte c to b's buffer.
|
||||
// The returned error is always nil.
|
||||
func (b *StringBuilder) WriteByte(c byte) error {
|
||||
b.copyCheck()
|
||||
b.buf = append(b.buf, c)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
|
||||
// It returns the length of r and a nil error.
|
||||
func (b *StringBuilder) WriteRune(r rune) (int, error) {
|
||||
b.copyCheck()
|
||||
if r < utf8.RuneSelf {
|
||||
b.buf = append(b.buf, byte(r))
|
||||
return 1, nil
|
||||
}
|
||||
l := len(b.buf)
|
||||
if cap(b.buf)-l < utf8.UTFMax {
|
||||
b.grow(utf8.UTFMax)
|
||||
}
|
||||
n := utf8.EncodeRune(b.buf[l:l+utf8.UTFMax], r)
|
||||
b.buf = b.buf[:l+n]
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// WriteString appends the contents of s to b's buffer.
|
||||
// It returns the length of s and a nil error.
|
||||
func (b *StringBuilder) WriteString(s string) (int, error) {
|
||||
b.copyCheck()
|
||||
b.buf = append(b.buf, s...)
|
||||
return len(s), nil
|
||||
}
|
14
vendor/github.com/go-xorm/core/cache.go
generated
vendored
14
vendor/github.com/go-xorm/core/cache.go
generated
vendored
@ -1,11 +1,16 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -55,11 +60,10 @@ func encodeIds(ids []PK) (string, error) {
|
||||
return buf.String(), err
|
||||
}
|
||||
|
||||
|
||||
func decodeIds(s string) ([]PK, error) {
|
||||
pks := make([]PK, 0)
|
||||
|
||||
dec := gob.NewDecoder(bytes.NewBufferString(s))
|
||||
dec := gob.NewDecoder(strings.NewReader(s))
|
||||
err := dec.Decode(&pks)
|
||||
|
||||
return pks, err
|
||||
|
31
vendor/github.com/go-xorm/core/column.go
generated
vendored
31
vendor/github.com/go-xorm/core/column.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
@ -41,6 +45,7 @@ type Column struct {
|
||||
Comment string
|
||||
}
|
||||
|
||||
// NewColumn creates a new column
|
||||
func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
|
||||
return &Column{
|
||||
Name: name,
|
||||
@ -66,7 +71,7 @@ func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable
|
||||
}
|
||||
}
|
||||
|
||||
// generate column description string according dialect
|
||||
// String generate column description string according dialect
|
||||
func (col *Column) String(d Dialect) string {
|
||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||
|
||||
@ -79,6 +84,10 @@ func (col *Column) String(d Dialect) string {
|
||||
}
|
||||
}
|
||||
|
||||
if col.Default != "" {
|
||||
sql += "DEFAULT " + col.Default + " "
|
||||
}
|
||||
|
||||
if d.ShowCreateNull() {
|
||||
if col.Nullable {
|
||||
sql += "NULL "
|
||||
@ -87,18 +96,19 @@ func (col *Column) String(d Dialect) string {
|
||||
}
|
||||
}
|
||||
|
||||
if col.Default != "" {
|
||||
sql += "DEFAULT " + col.Default + " "
|
||||
}
|
||||
|
||||
return sql
|
||||
}
|
||||
|
||||
// StringNoPk generate column description string according dialect without primary keys
|
||||
func (col *Column) StringNoPk(d Dialect) string {
|
||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||
|
||||
sql += d.SqlType(col) + " "
|
||||
|
||||
if col.Default != "" {
|
||||
sql += "DEFAULT " + col.Default + " "
|
||||
}
|
||||
|
||||
if d.ShowCreateNull() {
|
||||
if col.Nullable {
|
||||
sql += "NULL "
|
||||
@ -107,19 +117,16 @@ func (col *Column) StringNoPk(d Dialect) string {
|
||||
}
|
||||
}
|
||||
|
||||
if col.Default != "" {
|
||||
sql += "DEFAULT " + col.Default + " "
|
||||
}
|
||||
|
||||
return sql
|
||||
}
|
||||
|
||||
// return col's filed of struct's value
|
||||
// ValueOf returns column's filed of struct's value
|
||||
func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
|
||||
dataStruct := reflect.Indirect(reflect.ValueOf(bean))
|
||||
return col.ValueOfV(&dataStruct)
|
||||
}
|
||||
|
||||
// ValueOfV returns column's filed of struct's value accept reflevt value
|
||||
func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
||||
var fieldValue reflect.Value
|
||||
fieldPath := strings.Split(col.FieldName, ".")
|
||||
@ -147,12 +154,12 @@ func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
||||
}
|
||||
fieldValue = fieldValue.Elem().FieldByName(fieldPath[i+1])
|
||||
} else {
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
}
|
||||
}
|
||||
|
||||
if !fieldValue.IsValid() {
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
}
|
||||
|
||||
return &fieldValue, nil
|
||||
|
4
vendor/github.com/go-xorm/core/converstion.go
generated
vendored
4
vendor/github.com/go-xorm/core/converstion.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
// Conversion is an interface. A type implements Conversion will according
|
||||
|
341
vendor/github.com/go-xorm/core/db.go
generated
vendored
341
vendor/github.com/go-xorm/core/db.go
generated
vendored
@ -1,12 +1,21 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultCacheSize = 200
|
||||
)
|
||||
|
||||
func MapToSlice(query string, mp interface{}) (string, []interface{}, error) {
|
||||
@ -58,189 +67,129 @@ func StructToSlice(query string, st interface{}) (string, []interface{}, error)
|
||||
return query, args, nil
|
||||
}
|
||||
|
||||
type DB struct {
|
||||
*sql.DB
|
||||
Mapper IMapper
|
||||
type cacheStruct struct {
|
||||
value reflect.Value
|
||||
idx int
|
||||
}
|
||||
|
||||
// DB is a wrap of sql.DB with extra contents
|
||||
type DB struct {
|
||||
*sql.DB
|
||||
Mapper IMapper
|
||||
reflectCache map[reflect.Type]*cacheStruct
|
||||
reflectCacheMutex sync.RWMutex
|
||||
}
|
||||
|
||||
// Open opens a database
|
||||
func Open(driverName, dataSourceName string) (*DB, error) {
|
||||
db, err := sql.Open(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &DB{db, NewCacheMapper(&SnakeMapper{})}, nil
|
||||
return &DB{
|
||||
DB: db,
|
||||
Mapper: NewCacheMapper(&SnakeMapper{}),
|
||||
reflectCache: make(map[reflect.Type]*cacheStruct),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FromDB creates a DB from a sql.DB
|
||||
func FromDB(db *sql.DB) *DB {
|
||||
return &DB{db, NewCacheMapper(&SnakeMapper{})}
|
||||
return &DB{
|
||||
DB: db,
|
||||
Mapper: NewCacheMapper(&SnakeMapper{}),
|
||||
reflectCache: make(map[reflect.Type]*cacheStruct),
|
||||
}
|
||||
}
|
||||
|
||||
func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
|
||||
rows, err := db.DB.Query(query, args...)
|
||||
func (db *DB) reflectNew(typ reflect.Type) reflect.Value {
|
||||
db.reflectCacheMutex.Lock()
|
||||
defer db.reflectCacheMutex.Unlock()
|
||||
cs, ok := db.reflectCache[typ]
|
||||
if !ok || cs.idx+1 > DefaultCacheSize-1 {
|
||||
cs = &cacheStruct{reflect.MakeSlice(reflect.SliceOf(typ), DefaultCacheSize, DefaultCacheSize), 0}
|
||||
db.reflectCache[typ] = cs
|
||||
} else {
|
||||
cs.idx = cs.idx + 1
|
||||
}
|
||||
return cs.value.Index(cs.idx).Addr()
|
||||
}
|
||||
|
||||
// QueryContext overwrites sql.DB.QueryContext
|
||||
func (db *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||
rows, err := db.DB.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
if rows != nil {
|
||||
rows.Close()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{rows, db.Mapper}, nil
|
||||
return &Rows{rows, db}, nil
|
||||
}
|
||||
|
||||
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||
// Query overwrites sql.DB.Query
|
||||
func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
|
||||
return db.QueryContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db.Query(query, args...)
|
||||
return db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||
return db.QueryMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
func (db *DB) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db.Query(query, args...)
|
||||
return db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) QueryRow(query string, args ...interface{}) *Row {
|
||||
rows, err := db.Query(query, args...)
|
||||
func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
return db.QueryStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
||||
func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := db.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return &Row{rows, nil}
|
||||
}
|
||||
|
||||
func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
|
||||
func (db *DB) QueryRow(query string, args ...interface{}) *Row {
|
||||
return db.QueryRowContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return db.QueryRow(query, args...)
|
||||
return db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
|
||||
func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
|
||||
return db.QueryRowMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
func (db *DB) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return db.QueryRow(query, args...)
|
||||
return db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
type Stmt struct {
|
||||
*sql.Stmt
|
||||
Mapper IMapper
|
||||
names map[string]int
|
||||
}
|
||||
|
||||
func (db *DB) Prepare(query string) (*Stmt, error) {
|
||||
names := make(map[string]int)
|
||||
var i int
|
||||
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
||||
names[src[1:]] = i
|
||||
i += 1
|
||||
return "?"
|
||||
})
|
||||
|
||||
stmt, err := db.DB.Prepare(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Stmt{stmt, db.Mapper, names}, nil
|
||||
}
|
||||
|
||||
func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||
}
|
||||
return s.Stmt.Exec(args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||
}
|
||||
return s.Stmt.Exec(args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
|
||||
rows, err := s.Stmt.Query(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{rows, s.Mapper}, nil
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||
}
|
||||
|
||||
return s.Query(args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||
}
|
||||
|
||||
return s.Query(args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRow(args ...interface{}) *Row {
|
||||
rows, err := s.Query(args...)
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRowMap(mp interface{}) *Row {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return &Row{nil, errors.New("mp should be a map's pointer")}
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||
}
|
||||
|
||||
return s.QueryRow(args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRowStruct(st interface{}) *Row {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return &Row{nil, errors.New("st should be a struct's pointer")}
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||
}
|
||||
|
||||
return s.QueryRow(args...)
|
||||
func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
|
||||
return db.QueryRowStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
||||
var (
|
||||
@ -249,120 +198,26 @@ var (
|
||||
|
||||
// insert into (name) values (?)
|
||||
// insert into (name) values (?name)
|
||||
func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||
func (db *DB) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db.DB.Exec(query, args...)
|
||||
return db.DB.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||
return db.ExecMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
func (db *DB) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db.DB.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (db *DB) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db.DB.Exec(query, args...)
|
||||
}
|
||||
|
||||
type EmptyScanner struct {
|
||||
}
|
||||
|
||||
func (EmptyScanner) Scan(src interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Tx struct {
|
||||
*sql.Tx
|
||||
Mapper IMapper
|
||||
}
|
||||
|
||||
func (db *DB) Begin() (*Tx, error) {
|
||||
tx, err := db.DB.Begin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Tx{tx, db.Mapper}, nil
|
||||
}
|
||||
|
||||
func (tx *Tx) Prepare(query string) (*Stmt, error) {
|
||||
names := make(map[string]int)
|
||||
var i int
|
||||
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
||||
names[src[1:]] = i
|
||||
i += 1
|
||||
return "?"
|
||||
})
|
||||
|
||||
stmt, err := tx.Tx.Prepare(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Stmt{stmt, tx.Mapper, names}, nil
|
||||
}
|
||||
|
||||
func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
|
||||
// TODO:
|
||||
return stmt
|
||||
}
|
||||
|
||||
func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.Tx.Exec(query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.Tx.Exec(query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
|
||||
rows, err := tx.Tx.Query(query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{rows, tx.Mapper}, nil
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.Query(query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.Query(query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
|
||||
rows, err := tx.Query(query, args...)
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return tx.QueryRow(query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return tx.QueryRow(query, args...)
|
||||
return db.ExecStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
11
vendor/github.com/go-xorm/core/dialect.go
generated
vendored
11
vendor/github.com/go-xorm/core/dialect.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
@ -74,6 +78,7 @@ type Dialect interface {
|
||||
GetIndexes(tableName string) (map[string]*Index, error)
|
||||
|
||||
Filters() []Filter
|
||||
SetParams(params map[string]string)
|
||||
}
|
||||
|
||||
func OpenDialect(dialect Dialect) (*DB, error) {
|
||||
@ -148,7 +153,8 @@ func (db *Base) SupportDropIfExists() bool {
|
||||
}
|
||||
|
||||
func (db *Base) DropTableSql(tableName string) string {
|
||||
return fmt.Sprintf("DROP TABLE IF EXISTS `%s`", tableName)
|
||||
quote := db.dialect.Quote
|
||||
return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName))
|
||||
}
|
||||
|
||||
func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
|
||||
@ -289,6 +295,9 @@ func (b *Base) LogSQL(sql string, args []interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Base) SetParams(params map[string]string) {
|
||||
}
|
||||
|
||||
var (
|
||||
dialects = map[string]func() Dialect{}
|
||||
)
|
||||
|
4
vendor/github.com/go-xorm/core/driver.go
generated
vendored
4
vendor/github.com/go-xorm/core/driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
type Driver interface {
|
||||
|
4
vendor/github.com/go-xorm/core/error.go
generated
vendored
4
vendor/github.com/go-xorm/core/error.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import "errors"
|
||||
|
10
vendor/github.com/go-xorm/core/filter.go
generated
vendored
10
vendor/github.com/go-xorm/core/filter.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
@ -37,9 +41,9 @@ func (q *Quoter) Quote(content string) string {
|
||||
func (i *IdFilter) Do(sql string, dialect Dialect, table *Table) string {
|
||||
quoter := NewQuoter(dialect)
|
||||
if table != nil && len(table.PrimaryKeys) == 1 {
|
||||
sql = strings.Replace(sql, "`(id)`", quoter.Quote(table.PrimaryKeys[0]), -1)
|
||||
sql = strings.Replace(sql, quoter.Quote("(id)"), quoter.Quote(table.PrimaryKeys[0]), -1)
|
||||
return strings.Replace(sql, "(id)", quoter.Quote(table.PrimaryKeys[0]), -1)
|
||||
sql = strings.Replace(sql, " `(id)` ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
|
||||
sql = strings.Replace(sql, " "+quoter.Quote("(id)")+" ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
|
||||
return strings.Replace(sql, " (id) ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
|
||||
}
|
||||
return sql
|
||||
}
|
||||
|
4
vendor/github.com/go-xorm/core/ilogger.go
generated
vendored
4
vendor/github.com/go-xorm/core/ilogger.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
type LogLevel int
|
||||
|
18
vendor/github.com/go-xorm/core/index.go
generated
vendored
18
vendor/github.com/go-xorm/core/index.go
generated
vendored
@ -1,8 +1,11 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -22,6 +25,8 @@ type Index struct {
|
||||
func (index *Index) XName(tableName string) string {
|
||||
if !strings.HasPrefix(index.Name, "UQE_") &&
|
||||
!strings.HasPrefix(index.Name, "IDX_") {
|
||||
tableName = strings.Replace(tableName, `"`, "", -1)
|
||||
tableName = strings.Replace(tableName, `.`, "_", -1)
|
||||
if index.Type == UniqueType {
|
||||
return fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
||||
}
|
||||
@ -44,11 +49,16 @@ func (index *Index) Equal(dst *Index) bool {
|
||||
if len(index.Cols) != len(dst.Cols) {
|
||||
return false
|
||||
}
|
||||
sort.StringSlice(index.Cols).Sort()
|
||||
sort.StringSlice(dst.Cols).Sort()
|
||||
|
||||
for i := 0; i < len(index.Cols); i++ {
|
||||
if index.Cols[i] != dst.Cols[i] {
|
||||
var found bool
|
||||
for j := 0; j < len(dst.Cols); j++ {
|
||||
if index.Cols[i] == dst.Cols[j] {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
4
vendor/github.com/go-xorm/core/mapper.go
generated
vendored
4
vendor/github.com/go-xorm/core/mapper.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
|
4
vendor/github.com/go-xorm/core/pk.go
generated
vendored
4
vendor/github.com/go-xorm/core/pk.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
|
68
vendor/github.com/go-xorm/core/rows.go
generated
vendored
68
vendor/github.com/go-xorm/core/rows.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
@ -9,7 +13,7 @@ import (
|
||||
|
||||
type Rows struct {
|
||||
*sql.Rows
|
||||
Mapper IMapper
|
||||
db *DB
|
||||
}
|
||||
|
||||
func (rs *Rows) ToMapString() ([]map[string]string, error) {
|
||||
@ -105,7 +109,7 @@ func (rs *Rows) ScanStructByName(dest interface{}) error {
|
||||
newDest := make([]interface{}, len(cols))
|
||||
var v EmptyScanner
|
||||
for j, name := range cols {
|
||||
f := fieldByName(vv.Elem(), rs.Mapper.Table2Obj(name))
|
||||
f := fieldByName(vv.Elem(), rs.db.Mapper.Table2Obj(name))
|
||||
if f.IsValid() {
|
||||
newDest[j] = f.Addr().Interface()
|
||||
} else {
|
||||
@ -116,36 +120,6 @@ func (rs *Rows) ScanStructByName(dest interface{}) error {
|
||||
return rs.Rows.Scan(newDest...)
|
||||
}
|
||||
|
||||
type cacheStruct struct {
|
||||
value reflect.Value
|
||||
idx int
|
||||
}
|
||||
|
||||
var (
|
||||
reflectCache = make(map[reflect.Type]*cacheStruct)
|
||||
reflectCacheMutex sync.RWMutex
|
||||
)
|
||||
|
||||
func ReflectNew(typ reflect.Type) reflect.Value {
|
||||
reflectCacheMutex.RLock()
|
||||
cs, ok := reflectCache[typ]
|
||||
reflectCacheMutex.RUnlock()
|
||||
|
||||
const newSize = 200
|
||||
|
||||
if !ok || cs.idx+1 > newSize-1 {
|
||||
cs = &cacheStruct{reflect.MakeSlice(reflect.SliceOf(typ), newSize, newSize), 0}
|
||||
reflectCacheMutex.Lock()
|
||||
reflectCache[typ] = cs
|
||||
reflectCacheMutex.Unlock()
|
||||
} else {
|
||||
reflectCacheMutex.Lock()
|
||||
cs.idx = cs.idx + 1
|
||||
reflectCacheMutex.Unlock()
|
||||
}
|
||||
return cs.value.Index(cs.idx).Addr()
|
||||
}
|
||||
|
||||
// scan data to a slice's pointer, slice's length should equal to columns' number
|
||||
func (rs *Rows) ScanSlice(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
@ -197,9 +171,7 @@ func (rs *Rows) ScanMap(dest interface{}) error {
|
||||
vvv := vv.Elem()
|
||||
|
||||
for i, _ := range cols {
|
||||
newDest[i] = ReflectNew(vvv.Type().Elem()).Interface()
|
||||
//v := reflect.New(vvv.Type().Elem())
|
||||
//newDest[i] = v.Interface()
|
||||
newDest[i] = rs.db.reflectNew(vvv.Type().Elem()).Interface()
|
||||
}
|
||||
|
||||
err = rs.Rows.Scan(newDest...)
|
||||
@ -215,32 +187,6 @@ func (rs *Rows) ScanMap(dest interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*func (rs *Rows) ScanMap(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return errors.New("dest should be a map's pointer")
|
||||
}
|
||||
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newDest := make([]interface{}, len(cols))
|
||||
err = rs.ScanSlice(newDest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vvv := vv.Elem()
|
||||
|
||||
for i, name := range cols {
|
||||
vname := reflect.ValueOf(name)
|
||||
vvv.SetMapIndex(vname, reflect.ValueOf(newDest[i]).Elem())
|
||||
}
|
||||
|
||||
return nil
|
||||
}*/
|
||||
type Row struct {
|
||||
rows *Rows
|
||||
// One of these two will be non-nil:
|
||||
|
14
vendor/github.com/go-xorm/core/scan.go
generated
vendored
14
vendor/github.com/go-xorm/core/scan.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
@ -44,9 +48,19 @@ func convertTime(dest *NullTime, src interface{}) error {
|
||||
}
|
||||
*dest = NullTime(t)
|
||||
return nil
|
||||
case time.Time:
|
||||
*dest = NullTime(s)
|
||||
return nil
|
||||
case nil:
|
||||
default:
|
||||
return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EmptyScanner struct {
|
||||
}
|
||||
|
||||
func (EmptyScanner) Scan(src interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
165
vendor/github.com/go-xorm/core/stmt.go
generated
vendored
Normal file
165
vendor/github.com/go-xorm/core/stmt.go
generated
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type Stmt struct {
|
||||
*sql.Stmt
|
||||
db *DB
|
||||
names map[string]int
|
||||
}
|
||||
|
||||
func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
||||
names := make(map[string]int)
|
||||
var i int
|
||||
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
||||
names[src[1:]] = i
|
||||
i += 1
|
||||
return "?"
|
||||
})
|
||||
|
||||
stmt, err := db.DB.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Stmt{stmt, db, names}, nil
|
||||
}
|
||||
|
||||
func (db *DB) Prepare(query string) (*Stmt, error) {
|
||||
return db.PrepareContext(context.Background(), query)
|
||||
}
|
||||
|
||||
func (s *Stmt) ExecMapContext(ctx context.Context, mp interface{}) (sql.Result, error) {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||
}
|
||||
return s.Stmt.ExecContext(ctx, args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) {
|
||||
return s.ExecMapContext(context.Background(), mp)
|
||||
}
|
||||
|
||||
func (s *Stmt) ExecStructContext(ctx context.Context, st interface{}) (sql.Result, error) {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||
}
|
||||
return s.Stmt.ExecContext(ctx, args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) {
|
||||
return s.ExecStructContext(context.Background(), st)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, error) {
|
||||
rows, err := s.Stmt.QueryContext(ctx, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{rows, s.db}, nil
|
||||
}
|
||||
|
||||
func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
|
||||
return s.QueryContext(context.Background(), args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryMapContext(ctx context.Context, mp interface{}) (*Rows, error) {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||
}
|
||||
|
||||
return s.QueryContext(ctx, args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) {
|
||||
return s.QueryMapContext(context.Background(), mp)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryStructContext(ctx context.Context, st interface{}) (*Rows, error) {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return nil, errors.New("mp should be a map's pointer")
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||
}
|
||||
|
||||
return s.Query(args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
|
||||
return s.QueryStructContext(context.Background(), st)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRowContext(ctx context.Context, args ...interface{}) *Row {
|
||||
rows, err := s.QueryContext(ctx, args...)
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRow(args ...interface{}) *Row {
|
||||
return s.QueryRowContext(context.Background(), args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRowMapContext(ctx context.Context, mp interface{}) *Row {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
return &Row{nil, errors.New("mp should be a map's pointer")}
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||
}
|
||||
|
||||
return s.QueryRowContext(ctx, args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRowMap(mp interface{}) *Row {
|
||||
return s.QueryRowMapContext(context.Background(), mp)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRowStructContext(ctx context.Context, st interface{}) *Row {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return &Row{nil, errors.New("st should be a struct's pointer")}
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
for k, i := range s.names {
|
||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||
}
|
||||
|
||||
return s.QueryRowContext(ctx, args...)
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRowStruct(st interface{}) *Row {
|
||||
return s.QueryRowStructContext(context.Background(), st)
|
||||
}
|
6
vendor/github.com/go-xorm/core/table.go
generated
vendored
6
vendor/github.com/go-xorm/core/table.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
@ -49,7 +53,6 @@ func NewTable(name string, t reflect.Type) *Table {
|
||||
}
|
||||
|
||||
func (table *Table) columnsByName(name string) []*Column {
|
||||
|
||||
n := len(name)
|
||||
|
||||
for k := range table.columnsMap {
|
||||
@ -75,7 +78,6 @@ func (table *Table) GetColumn(name string) *Column {
|
||||
}
|
||||
|
||||
func (table *Table) GetColumnIdx(name string, idx int) *Column {
|
||||
|
||||
cols := table.columnsByName(name)
|
||||
|
||||
if cols != nil && idx < len(cols) {
|
||||
|
153
vendor/github.com/go-xorm/core/tx.go
generated
vendored
Normal file
153
vendor/github.com/go-xorm/core/tx.go
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
type Tx struct {
|
||||
*sql.Tx
|
||||
db *DB
|
||||
}
|
||||
|
||||
func (db *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
||||
tx, err := db.DB.BeginTx(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Tx{tx, db}, nil
|
||||
}
|
||||
|
||||
func (db *DB) Begin() (*Tx, error) {
|
||||
tx, err := db.DB.Begin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Tx{tx, db}, nil
|
||||
}
|
||||
|
||||
func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
||||
names := make(map[string]int)
|
||||
var i int
|
||||
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
||||
names[src[1:]] = i
|
||||
i += 1
|
||||
return "?"
|
||||
})
|
||||
|
||||
stmt, err := tx.Tx.PrepareContext(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Stmt{stmt, tx.db, names}, nil
|
||||
}
|
||||
|
||||
func (tx *Tx) Prepare(query string) (*Stmt, error) {
|
||||
return tx.PrepareContext(context.Background(), query)
|
||||
}
|
||||
|
||||
func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
|
||||
stmt.Stmt = tx.Tx.StmtContext(ctx, stmt.Stmt)
|
||||
return stmt
|
||||
}
|
||||
|
||||
func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
|
||||
return tx.StmtContext(context.Background(), stmt)
|
||||
}
|
||||
|
||||
func (tx *Tx) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.Tx.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||
return tx.ExecMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
func (tx *Tx) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.Tx.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
||||
return tx.ExecStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||
rows, err := tx.Tx.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{rows, tx.db}, nil
|
||||
}
|
||||
|
||||
func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
|
||||
return tx.QueryContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||
return tx.QueryMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
return tx.QueryStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := tx.QueryContext(ctx, query, args...)
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
|
||||
return tx.QueryRowContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return tx.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
|
||||
return tx.QueryRowMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return tx.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
|
||||
return tx.QueryRowStructContext(context.Background(), query, st)
|
||||
}
|
54
vendor/github.com/go-xorm/core/type.go
generated
vendored
54
vendor/github.com/go-xorm/core/type.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
@ -69,24 +73,31 @@ var (
|
||||
Enum = "ENUM"
|
||||
Set = "SET"
|
||||
|
||||
Char = "CHAR"
|
||||
Varchar = "VARCHAR"
|
||||
NVarchar = "NVARCHAR"
|
||||
TinyText = "TINYTEXT"
|
||||
Text = "TEXT"
|
||||
Clob = "CLOB"
|
||||
MediumText = "MEDIUMTEXT"
|
||||
LongText = "LONGTEXT"
|
||||
Uuid = "UUID"
|
||||
Char = "CHAR"
|
||||
Varchar = "VARCHAR"
|
||||
NChar = "NCHAR"
|
||||
NVarchar = "NVARCHAR"
|
||||
TinyText = "TINYTEXT"
|
||||
Text = "TEXT"
|
||||
NText = "NTEXT"
|
||||
Clob = "CLOB"
|
||||
MediumText = "MEDIUMTEXT"
|
||||
LongText = "LONGTEXT"
|
||||
Uuid = "UUID"
|
||||
UniqueIdentifier = "UNIQUEIDENTIFIER"
|
||||
SysName = "SYSNAME"
|
||||
|
||||
Date = "DATE"
|
||||
DateTime = "DATETIME"
|
||||
SmallDateTime = "SMALLDATETIME"
|
||||
Time = "TIME"
|
||||
TimeStamp = "TIMESTAMP"
|
||||
TimeStampz = "TIMESTAMPZ"
|
||||
|
||||
Decimal = "DECIMAL"
|
||||
Numeric = "NUMERIC"
|
||||
Money = "MONEY"
|
||||
SmallMoney = "SMALLMONEY"
|
||||
|
||||
Real = "REAL"
|
||||
Float = "FLOAT"
|
||||
@ -124,35 +135,42 @@ var (
|
||||
Jsonb: TEXT_TYPE,
|
||||
|
||||
Char: TEXT_TYPE,
|
||||
NChar: TEXT_TYPE,
|
||||
Varchar: TEXT_TYPE,
|
||||
NVarchar: TEXT_TYPE,
|
||||
TinyText: TEXT_TYPE,
|
||||
Text: TEXT_TYPE,
|
||||
NText: TEXT_TYPE,
|
||||
MediumText: TEXT_TYPE,
|
||||
LongText: TEXT_TYPE,
|
||||
Uuid: TEXT_TYPE,
|
||||
Clob: TEXT_TYPE,
|
||||
SysName: TEXT_TYPE,
|
||||
|
||||
Date: TIME_TYPE,
|
||||
DateTime: TIME_TYPE,
|
||||
Time: TIME_TYPE,
|
||||
TimeStamp: TIME_TYPE,
|
||||
TimeStampz: TIME_TYPE,
|
||||
SmallDateTime: TIME_TYPE,
|
||||
|
||||
Decimal: NUMERIC_TYPE,
|
||||
Numeric: NUMERIC_TYPE,
|
||||
Real: NUMERIC_TYPE,
|
||||
Float: NUMERIC_TYPE,
|
||||
Double: NUMERIC_TYPE,
|
||||
Money: NUMERIC_TYPE,
|
||||
SmallMoney: NUMERIC_TYPE,
|
||||
|
||||
Binary: BLOB_TYPE,
|
||||
VarBinary: BLOB_TYPE,
|
||||
|
||||
TinyBlob: BLOB_TYPE,
|
||||
Blob: BLOB_TYPE,
|
||||
MediumBlob: BLOB_TYPE,
|
||||
LongBlob: BLOB_TYPE,
|
||||
Bytea: BLOB_TYPE,
|
||||
TinyBlob: BLOB_TYPE,
|
||||
Blob: BLOB_TYPE,
|
||||
MediumBlob: BLOB_TYPE,
|
||||
LongBlob: BLOB_TYPE,
|
||||
Bytea: BLOB_TYPE,
|
||||
UniqueIdentifier: BLOB_TYPE,
|
||||
|
||||
Bool: NUMERIC_TYPE,
|
||||
|
||||
@ -289,15 +307,15 @@ func SQLType2Type(st SQLType) reflect.Type {
|
||||
return reflect.TypeOf(float32(1))
|
||||
case Double:
|
||||
return reflect.TypeOf(float64(1))
|
||||
case Char, Varchar, NVarchar, TinyText, Text, MediumText, LongText, Enum, Set, Uuid, Clob:
|
||||
case Char, NChar, Varchar, NVarchar, TinyText, Text, NText, MediumText, LongText, Enum, Set, Uuid, Clob, SysName:
|
||||
return reflect.TypeOf("")
|
||||
case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary:
|
||||
case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary, UniqueIdentifier:
|
||||
return reflect.TypeOf([]byte{})
|
||||
case Bool:
|
||||
return reflect.TypeOf(true)
|
||||
case DateTime, Date, Time, TimeStamp, TimeStampz:
|
||||
case DateTime, Date, Time, TimeStamp, TimeStampz, SmallDateTime:
|
||||
return reflect.TypeOf(c_TIME_DEFAULT)
|
||||
case Decimal, Numeric:
|
||||
case Decimal, Numeric, Money, SmallMoney:
|
||||
return reflect.TypeOf("")
|
||||
default:
|
||||
return reflect.TypeOf("")
|
||||
|
30
vendor/github.com/go-xorm/xorm/context_cache.go
generated
vendored
Normal file
30
vendor/github.com/go-xorm/xorm/context_cache.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
// ContextCache is the interface that operates the cache data.
|
||||
type ContextCache interface {
|
||||
// Put puts value into cache with key.
|
||||
Put(key string, val interface{})
|
||||
// Get gets cached value by given key.
|
||||
Get(key string) interface{}
|
||||
}
|
||||
|
||||
type memoryContextCache map[string]interface{}
|
||||
|
||||
// NewMemoryContextCache return memoryContextCache
|
||||
func NewMemoryContextCache() memoryContextCache {
|
||||
return make(map[string]interface{})
|
||||
}
|
||||
|
||||
// Put puts value into cache with key.
|
||||
func (m memoryContextCache) Put(key string, val interface{}) {
|
||||
m[key] = val
|
||||
}
|
||||
|
||||
// Get gets cached value by given key.
|
||||
func (m memoryContextCache) Get(key string) interface{} {
|
||||
return m[key]
|
||||
}
|
77
vendor/github.com/go-xorm/xorm/dialect_mysql.go
generated
vendored
77
vendor/github.com/go-xorm/xorm/dialect_mysql.go
generated
vendored
@ -172,12 +172,33 @@ type mysql struct {
|
||||
allowAllFiles bool
|
||||
allowOldPasswords bool
|
||||
clientFoundRows bool
|
||||
rowFormat string
|
||||
}
|
||||
|
||||
func (db *mysql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
|
||||
return db.Base.Init(d, db, uri, drivername, dataSourceName)
|
||||
}
|
||||
|
||||
func (db *mysql) SetParams(params map[string]string) {
|
||||
rowFormat, ok := params["rowFormat"]
|
||||
if ok {
|
||||
var t = strings.ToUpper(rowFormat)
|
||||
switch t {
|
||||
case "COMPACT":
|
||||
fallthrough
|
||||
case "REDUNDANT":
|
||||
fallthrough
|
||||
case "DYNAMIC":
|
||||
fallthrough
|
||||
case "COMPRESSED":
|
||||
db.rowFormat = t
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (db *mysql) SqlType(c *core.Column) string {
|
||||
var res string
|
||||
switch t := c.SQLType.Name; t {
|
||||
@ -487,6 +508,62 @@ func (db *mysql) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
return indexes, nil
|
||||
}
|
||||
|
||||
func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string {
|
||||
var sql string
|
||||
sql = "CREATE TABLE IF NOT EXISTS "
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
sql += db.Quote(tableName)
|
||||
sql += " ("
|
||||
|
||||
if len(table.ColumnsSeq()) > 0 {
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
if col.IsPrimaryKey && len(pkList) == 1 {
|
||||
sql += col.String(db)
|
||||
} else {
|
||||
sql += col.StringNoPk(db)
|
||||
}
|
||||
sql = strings.TrimSpace(sql)
|
||||
if len(col.Comment) > 0 {
|
||||
sql += " COMMENT '" + col.Comment + "'"
|
||||
}
|
||||
sql += ", "
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += db.Quote(strings.Join(pkList, db.Quote(",")))
|
||||
sql += " ), "
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2]
|
||||
}
|
||||
sql += ")"
|
||||
|
||||
if storeEngine != "" {
|
||||
sql += " ENGINE=" + storeEngine
|
||||
}
|
||||
|
||||
if len(charset) == 0 {
|
||||
charset = db.URI().Charset
|
||||
}
|
||||
if len(charset) != 0 {
|
||||
sql += " DEFAULT CHARSET " + charset
|
||||
}
|
||||
|
||||
|
||||
|
||||
if db.rowFormat != "" {
|
||||
sql += " ROW_FORMAT=" + db.rowFormat
|
||||
}
|
||||
return sql
|
||||
}
|
||||
|
||||
func (db *mysql) Filters() []core.Filter {
|
||||
return []core.Filter{&core.IdFilter{}}
|
||||
}
|
||||
|
108
vendor/github.com/go-xorm/xorm/dialect_postgres.go
generated
vendored
108
vendor/github.com/go-xorm/xorm/dialect_postgres.go
generated
vendored
@ -764,14 +764,26 @@ var (
|
||||
"YES": true,
|
||||
"ZONE": true,
|
||||
}
|
||||
|
||||
// DefaultPostgresSchema default postgres schema
|
||||
DefaultPostgresSchema = "public"
|
||||
)
|
||||
|
||||
const postgresPublicSchema = "public"
|
||||
|
||||
type postgres struct {
|
||||
core.Base
|
||||
}
|
||||
|
||||
func (db *postgres) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
|
||||
return db.Base.Init(d, db, uri, drivername, dataSourceName)
|
||||
err := db.Base.Init(d, db, uri, drivername, dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if db.Schema == "" {
|
||||
db.Schema = DefaultPostgresSchema
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *postgres) SqlType(c *core.Column) string {
|
||||
@ -868,32 +880,42 @@ func (db *postgres) IndexOnTable() bool {
|
||||
}
|
||||
|
||||
func (db *postgres) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, idxName}
|
||||
if len(db.Schema) == 0 {
|
||||
args := []interface{}{tableName, idxName}
|
||||
return `SELECT indexname FROM pg_indexes WHERE tablename = ? AND indexname = ?`, args
|
||||
}
|
||||
|
||||
args := []interface{}{db.Schema, tableName, idxName}
|
||||
return `SELECT indexname FROM pg_indexes ` +
|
||||
`WHERE tablename = ? AND indexname = ?`, args
|
||||
`WHERE schemaname = ? AND tablename = ? AND indexname = ?`, args
|
||||
}
|
||||
|
||||
func (db *postgres) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName}
|
||||
return `SELECT tablename FROM pg_tables WHERE tablename = ?`, args
|
||||
if len(db.Schema) == 0 {
|
||||
args := []interface{}{tableName}
|
||||
return `SELECT tablename FROM pg_tables WHERE tablename = ?`, args
|
||||
}
|
||||
|
||||
args := []interface{}{db.Schema, tableName}
|
||||
return `SELECT tablename FROM pg_tables WHERE schemaname = ? AND tablename = ?`, args
|
||||
}
|
||||
|
||||
/*func (db *postgres) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, colName}
|
||||
return "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = ?" +
|
||||
" AND column_name = ?", args
|
||||
}*/
|
||||
|
||||
func (db *postgres) ModifyColumnSql(tableName string, col *core.Column) string {
|
||||
return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s",
|
||||
tableName, col.Name, db.SqlType(col))
|
||||
if len(db.Schema) == 0 {
|
||||
return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s",
|
||||
tableName, col.Name, db.SqlType(col))
|
||||
}
|
||||
return fmt.Sprintf("alter table %s.%s ALTER COLUMN %s TYPE %s",
|
||||
db.Schema, tableName, col.Name, db.SqlType(col))
|
||||
}
|
||||
|
||||
func (db *postgres) DropIndexSql(tableName string, index *core.Index) string {
|
||||
//var unique string
|
||||
quote := db.Quote
|
||||
idxName := index.Name
|
||||
|
||||
tableName = strings.Replace(tableName, `"`, "", -1)
|
||||
tableName = strings.Replace(tableName, `.`, "_", -1)
|
||||
|
||||
if !strings.HasPrefix(idxName, "UQE_") &&
|
||||
!strings.HasPrefix(idxName, "IDX_") {
|
||||
if index.Type == core.UniqueType {
|
||||
@ -902,13 +924,21 @@ func (db *postgres) DropIndexSql(tableName string, index *core.Index) string {
|
||||
idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
||||
}
|
||||
}
|
||||
if db.Uri.Schema != "" {
|
||||
idxName = db.Uri.Schema + "." + idxName
|
||||
}
|
||||
return fmt.Sprintf("DROP INDEX %v", quote(idxName))
|
||||
}
|
||||
|
||||
func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
args := []interface{}{tableName, colName}
|
||||
query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" +
|
||||
" AND column_name = $2"
|
||||
args := []interface{}{db.Schema, tableName, colName}
|
||||
query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = $1 AND table_name = $2" +
|
||||
" AND column_name = $3"
|
||||
if len(db.Schema) == 0 {
|
||||
args = []interface{}{tableName, colName}
|
||||
query = "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" +
|
||||
" AND column_name = $2"
|
||||
}
|
||||
db.LogSQL(query, args)
|
||||
|
||||
rows, err := db.DB().Query(query, args...)
|
||||
@ -921,8 +951,7 @@ func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
}
|
||||
|
||||
func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
||||
// FIXME: the schema should be replaced by user custom's
|
||||
args := []interface{}{tableName, "public"}
|
||||
args := []interface{}{tableName}
|
||||
s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_precision_radix ,
|
||||
CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey,
|
||||
CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey
|
||||
@ -933,7 +962,15 @@ FROM pg_attribute f
|
||||
LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
|
||||
LEFT JOIN pg_class AS g ON p.confrelid = g.oid
|
||||
LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name
|
||||
WHERE c.relkind = 'r'::char AND c.relname = $1 AND s.table_schema = $2 AND f.attnum > 0 ORDER BY f.attnum;`
|
||||
WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.attnum;`
|
||||
|
||||
var f string
|
||||
if len(db.Schema) != 0 {
|
||||
args = append(args, db.Schema)
|
||||
f = " AND s.table_schema = $2"
|
||||
}
|
||||
s = fmt.Sprintf(s, f)
|
||||
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
@ -1023,9 +1060,13 @@ WHERE c.relkind = 'r'::char AND c.relname = $1 AND s.table_schema = $2 AND f.att
|
||||
}
|
||||
|
||||
func (db *postgres) GetTables() ([]*core.Table, error) {
|
||||
// FIXME: replace public to user customrize schema
|
||||
args := []interface{}{"public"}
|
||||
s := fmt.Sprintf("SELECT tablename FROM pg_tables WHERE schemaname = $1")
|
||||
args := []interface{}{}
|
||||
s := "SELECT tablename FROM pg_tables"
|
||||
if len(db.Schema) != 0 {
|
||||
args = append(args, db.Schema)
|
||||
s = s + " WHERE schemaname = $1"
|
||||
}
|
||||
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
@ -1049,9 +1090,12 @@ func (db *postgres) GetTables() ([]*core.Table, error) {
|
||||
}
|
||||
|
||||
func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
// FIXME: replace the public schema to user specify schema
|
||||
args := []interface{}{"public", tableName}
|
||||
s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE schemaname=$1 AND tablename=$2")
|
||||
args := []interface{}{tableName}
|
||||
s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1")
|
||||
if len(db.Schema) != 0 {
|
||||
args = append(args, db.Schema)
|
||||
s = s + " AND schemaname=$2"
|
||||
}
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
@ -1179,3 +1223,15 @@ func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
type pqDriverPgx struct {
|
||||
pqDriver
|
||||
}
|
||||
|
||||
func (pgx *pqDriverPgx) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
// Remove the leading characters for driver to work
|
||||
if len(dataSourceName) >= 9 && dataSourceName[0] == 0 {
|
||||
dataSourceName = dataSourceName[9:]
|
||||
}
|
||||
return pgx.pqDriver.Parse(driverName, dataSourceName)
|
||||
}
|
||||
|
6
vendor/github.com/go-xorm/xorm/dialect_sqlite3.go
generated
vendored
6
vendor/github.com/go-xorm/xorm/dialect_sqlite3.go
generated
vendored
@ -233,7 +233,7 @@ func (db *sqlite3) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
}
|
||||
|
||||
func (db *sqlite3) DropIndexSql(tableName string, index *core.Index) string {
|
||||
//var unique string
|
||||
// var unique string
|
||||
quote := db.Quote
|
||||
idxName := index.Name
|
||||
|
||||
@ -452,5 +452,9 @@ type sqlite3Driver struct {
|
||||
}
|
||||
|
||||
func (p *sqlite3Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
if strings.Contains(dataSourceName, "?") {
|
||||
dataSourceName = dataSourceName[:strings.Index(dataSourceName, "?")]
|
||||
}
|
||||
|
||||
return &core.Uri{DbType: core.SQLITE, DbName: dataSourceName}, nil
|
||||
}
|
||||
|
209
vendor/github.com/go-xorm/xorm/engine.go
generated
vendored
209
vendor/github.com/go-xorm/xorm/engine.go
generated
vendored
@ -49,6 +49,35 @@ type Engine struct {
|
||||
tagHandlers map[string]tagHandler
|
||||
|
||||
engineGroup *EngineGroup
|
||||
|
||||
cachers map[string]core.Cacher
|
||||
cacherLock sync.RWMutex
|
||||
}
|
||||
|
||||
func (engine *Engine) setCacher(tableName string, cacher core.Cacher) {
|
||||
engine.cacherLock.Lock()
|
||||
engine.cachers[tableName] = cacher
|
||||
engine.cacherLock.Unlock()
|
||||
}
|
||||
|
||||
func (engine *Engine) SetCacher(tableName string, cacher core.Cacher) {
|
||||
engine.setCacher(tableName, cacher)
|
||||
}
|
||||
|
||||
func (engine *Engine) getCacher(tableName string) core.Cacher {
|
||||
var cacher core.Cacher
|
||||
var ok bool
|
||||
engine.cacherLock.RLock()
|
||||
cacher, ok = engine.cachers[tableName]
|
||||
engine.cacherLock.RUnlock()
|
||||
if !ok && !engine.disableGlobalCache {
|
||||
cacher = engine.Cacher
|
||||
}
|
||||
return cacher
|
||||
}
|
||||
|
||||
func (engine *Engine) GetCacher(tableName string) core.Cacher {
|
||||
return engine.getCacher(tableName)
|
||||
}
|
||||
|
||||
// BufferSize sets buffer size for iterate
|
||||
@ -148,6 +177,14 @@ func (engine *Engine) QuoteStr() string {
|
||||
return engine.dialect.QuoteStr()
|
||||
}
|
||||
|
||||
func (engine *Engine) quoteColumns(columnStr string) string {
|
||||
columns := strings.Split(columnStr, ",")
|
||||
for i := 0; i < len(columns); i++ {
|
||||
columns[i] = engine.Quote(strings.TrimSpace(columns[i]))
|
||||
}
|
||||
return strings.Join(columns, ",")
|
||||
}
|
||||
|
||||
// Quote Use QuoteStr quote the string sql
|
||||
func (engine *Engine) Quote(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
@ -165,7 +202,7 @@ func (engine *Engine) Quote(value string) string {
|
||||
}
|
||||
|
||||
// QuoteTo quotes string and writes into the buffer
|
||||
func (engine *Engine) QuoteTo(buf *bytes.Buffer, value string) {
|
||||
func (engine *Engine) QuoteTo(buf *builder.StringBuilder, value string) {
|
||||
if buf == nil {
|
||||
return
|
||||
}
|
||||
@ -208,6 +245,11 @@ func (engine *Engine) AutoIncrStr() string {
|
||||
return engine.dialect.AutoIncrStr()
|
||||
}
|
||||
|
||||
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
|
||||
func (engine *Engine) SetConnMaxLifetime(d time.Duration) {
|
||||
engine.db.SetConnMaxLifetime(d)
|
||||
}
|
||||
|
||||
// SetMaxOpenConns is only available for go 1.2+
|
||||
func (engine *Engine) SetMaxOpenConns(conns int) {
|
||||
engine.db.SetMaxOpenConns(conns)
|
||||
@ -245,13 +287,7 @@ func (engine *Engine) NoCascade() *Session {
|
||||
|
||||
// MapCacher Set a table use a special cacher
|
||||
func (engine *Engine) MapCacher(bean interface{}, cacher core.Cacher) error {
|
||||
v := rValue(bean)
|
||||
tb, err := engine.autoMapType(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tb.Cacher = cacher
|
||||
engine.setCacher(engine.TableName(bean, true), cacher)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -536,33 +572,6 @@ func (engine *Engine) dumpTables(tables []*core.Table, w io.Writer, tp ...core.D
|
||||
return nil
|
||||
}
|
||||
|
||||
func (engine *Engine) tableName(beanOrTableName interface{}) (string, error) {
|
||||
v := rValue(beanOrTableName)
|
||||
if v.Type().Kind() == reflect.String {
|
||||
return beanOrTableName.(string), nil
|
||||
} else if v.Type().Kind() == reflect.Struct {
|
||||
return engine.tbName(v), nil
|
||||
}
|
||||
return "", errors.New("bean should be a struct or struct's point")
|
||||
}
|
||||
|
||||
func (engine *Engine) tbName(v reflect.Value) string {
|
||||
if tb, ok := v.Interface().(TableName); ok {
|
||||
return tb.TableName()
|
||||
}
|
||||
|
||||
if v.Type().Kind() == reflect.Ptr {
|
||||
if tb, ok := reflect.Indirect(v).Interface().(TableName); ok {
|
||||
return tb.TableName()
|
||||
}
|
||||
} else if v.CanAddr() {
|
||||
if tb, ok := v.Addr().Interface().(TableName); ok {
|
||||
return tb.TableName()
|
||||
}
|
||||
}
|
||||
return engine.TableMapper.Obj2Table(reflect.Indirect(v).Type().Name())
|
||||
}
|
||||
|
||||
// Cascade use cascade or not
|
||||
func (engine *Engine) Cascade(trueOrFalse ...bool) *Session {
|
||||
session := engine.NewSession()
|
||||
@ -846,7 +855,7 @@ func (engine *Engine) TableInfo(bean interface{}) *Table {
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
}
|
||||
return &Table{tb, engine.tbName(v)}
|
||||
return &Table{tb, engine.TableName(bean)}
|
||||
}
|
||||
|
||||
func addIndex(indexName string, table *core.Table, col *core.Column, indexType int) {
|
||||
@ -861,15 +870,6 @@ func addIndex(indexName string, table *core.Table, col *core.Column, indexType i
|
||||
}
|
||||
}
|
||||
|
||||
func (engine *Engine) newTable() *core.Table {
|
||||
table := core.NewEmptyTable()
|
||||
|
||||
if !engine.disableGlobalCache {
|
||||
table.Cacher = engine.Cacher
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
// TableName table name interface to define customerize table name
|
||||
type TableName interface {
|
||||
TableName() string
|
||||
@ -881,21 +881,9 @@ var (
|
||||
|
||||
func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) {
|
||||
t := v.Type()
|
||||
table := engine.newTable()
|
||||
if tb, ok := v.Interface().(TableName); ok {
|
||||
table.Name = tb.TableName()
|
||||
} else {
|
||||
if v.CanAddr() {
|
||||
if tb, ok = v.Addr().Interface().(TableName); ok {
|
||||
table.Name = tb.TableName()
|
||||
}
|
||||
}
|
||||
if table.Name == "" {
|
||||
table.Name = engine.TableMapper.Obj2Table(t.Name())
|
||||
}
|
||||
}
|
||||
|
||||
table := core.NewEmptyTable()
|
||||
table.Type = t
|
||||
table.Name = engine.tbNameForMap(v)
|
||||
|
||||
var idFieldColName string
|
||||
var hasCacheTag, hasNoCacheTag bool
|
||||
@ -1049,15 +1037,15 @@ func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) {
|
||||
if hasCacheTag {
|
||||
if engine.Cacher != nil { // !nash! use engine's cacher if provided
|
||||
engine.logger.Info("enable cache on table:", table.Name)
|
||||
table.Cacher = engine.Cacher
|
||||
engine.setCacher(table.Name, engine.Cacher)
|
||||
} else {
|
||||
engine.logger.Info("enable LRU cache on table:", table.Name)
|
||||
table.Cacher = NewLRUCacher2(NewMemoryStore(), time.Hour, 10000) // !nashtsai! HACK use LRU cacher for now
|
||||
engine.setCacher(table.Name, NewLRUCacher2(NewMemoryStore(), time.Hour, 10000))
|
||||
}
|
||||
}
|
||||
if hasNoCacheTag {
|
||||
engine.logger.Info("no cache on table:", table.Name)
|
||||
table.Cacher = nil
|
||||
engine.logger.Info("disable cache on table:", table.Name)
|
||||
engine.setCacher(table.Name, nil)
|
||||
}
|
||||
|
||||
return table, nil
|
||||
@ -1116,7 +1104,25 @@ func (engine *Engine) idOfV(rv reflect.Value) (core.PK, error) {
|
||||
pk := make([]interface{}, len(table.PrimaryKeys))
|
||||
for i, col := range table.PKColumns() {
|
||||
var err error
|
||||
pkField := v.FieldByName(col.FieldName)
|
||||
|
||||
fieldName := col.FieldName
|
||||
for {
|
||||
parts := strings.SplitN(fieldName, ".", 2)
|
||||
if len(parts) == 1 {
|
||||
break
|
||||
}
|
||||
|
||||
v = v.FieldByName(parts[0])
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil, ErrUnSupportedType
|
||||
}
|
||||
fieldName = parts[1]
|
||||
}
|
||||
|
||||
pkField := v.FieldByName(fieldName)
|
||||
switch pkField.Kind() {
|
||||
case reflect.String:
|
||||
pk[i], err = engine.idTypeAssertion(col, pkField.String())
|
||||
@ -1162,26 +1168,10 @@ func (engine *Engine) CreateUniques(bean interface{}) error {
|
||||
return session.CreateUniques(bean)
|
||||
}
|
||||
|
||||
func (engine *Engine) getCacher2(table *core.Table) core.Cacher {
|
||||
return table.Cacher
|
||||
}
|
||||
|
||||
// ClearCacheBean if enabled cache, clear the cache bean
|
||||
func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
|
||||
v := rValue(bean)
|
||||
t := v.Type()
|
||||
if t.Kind() != reflect.Struct {
|
||||
return errors.New("error params")
|
||||
}
|
||||
tableName := engine.tbName(v)
|
||||
table, err := engine.autoMapType(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacher := table.Cacher
|
||||
if cacher == nil {
|
||||
cacher = engine.Cacher
|
||||
}
|
||||
tableName := engine.TableName(bean)
|
||||
cacher := engine.getCacher(tableName)
|
||||
if cacher != nil {
|
||||
cacher.ClearIds(tableName)
|
||||
cacher.DelBean(tableName, id)
|
||||
@ -1192,21 +1182,8 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
|
||||
// ClearCache if enabled cache, clear some tables' cache
|
||||
func (engine *Engine) ClearCache(beans ...interface{}) error {
|
||||
for _, bean := range beans {
|
||||
v := rValue(bean)
|
||||
t := v.Type()
|
||||
if t.Kind() != reflect.Struct {
|
||||
return errors.New("error params")
|
||||
}
|
||||
tableName := engine.tbName(v)
|
||||
table, err := engine.autoMapType(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cacher := table.Cacher
|
||||
if cacher == nil {
|
||||
cacher = engine.Cacher
|
||||
}
|
||||
tableName := engine.TableName(bean)
|
||||
cacher := engine.getCacher(tableName)
|
||||
if cacher != nil {
|
||||
cacher.ClearIds(tableName)
|
||||
cacher.ClearBeans(tableName)
|
||||
@ -1224,13 +1201,13 @@ func (engine *Engine) Sync(beans ...interface{}) error {
|
||||
|
||||
for _, bean := range beans {
|
||||
v := rValue(bean)
|
||||
tableName := engine.tbName(v)
|
||||
tableNameNoSchema := engine.TableName(bean)
|
||||
table, err := engine.autoMapType(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isExist, err := session.Table(bean).isTableExist(tableName)
|
||||
isExist, err := session.Table(bean).isTableExist(tableNameNoSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1256,12 +1233,12 @@ func (engine *Engine) Sync(beans ...interface{}) error {
|
||||
}
|
||||
} else {
|
||||
for _, col := range table.Columns() {
|
||||
isExist, err := engine.dialect.IsColumnExist(tableName, col.Name)
|
||||
isExist, err := engine.dialect.IsColumnExist(tableNameNoSchema, col.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isExist {
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
err = session.addColumn(col.Name)
|
||||
@ -1272,35 +1249,35 @@ func (engine *Engine) Sync(beans ...interface{}) error {
|
||||
}
|
||||
|
||||
for name, index := range table.Indexes {
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
if index.Type == core.UniqueType {
|
||||
isExist, err := session.isIndexExist2(tableName, index.Cols, true)
|
||||
isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isExist {
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = session.addUnique(tableName, name)
|
||||
err = session.addUnique(tableNameNoSchema, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if index.Type == core.IndexType {
|
||||
isExist, err := session.isIndexExist2(tableName, index.Cols, false)
|
||||
isExist, err := session.isIndexExist2(tableNameNoSchema, index.Cols, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isExist {
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = session.addIndex(tableName, name)
|
||||
err = session.addIndex(tableNameNoSchema, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1369,10 +1346,10 @@ func (engine *Engine) DropIndexes(bean interface{}) error {
|
||||
}
|
||||
|
||||
// Exec raw sql
|
||||
func (engine *Engine) Exec(sql string, args ...interface{}) (sql.Result, error) {
|
||||
func (engine *Engine) Exec(sqlorArgs ...interface{}) (sql.Result, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Exec(sql, args...)
|
||||
return session.Exec(sqlorArgs...)
|
||||
}
|
||||
|
||||
// Query a raw sql and return records as []map[string][]byte
|
||||
@ -1453,6 +1430,13 @@ func (engine *Engine) Find(beans interface{}, condiBeans ...interface{}) error {
|
||||
return session.Find(beans, condiBeans...)
|
||||
}
|
||||
|
||||
// FindAndCount find the results and also return the counts
|
||||
func (engine *Engine) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.FindAndCount(rowsSlicePtr, condiBean...)
|
||||
}
|
||||
|
||||
// Iterate record by record handle records from table, bean's non-empty fields
|
||||
// are conditions.
|
||||
func (engine *Engine) Iterate(bean interface{}, fun IterFunc) error {
|
||||
@ -1629,6 +1613,11 @@ func (engine *Engine) SetTZDatabase(tz *time.Location) {
|
||||
engine.DatabaseTZ = tz
|
||||
}
|
||||
|
||||
// SetSchema sets the schema of database
|
||||
func (engine *Engine) SetSchema(schema string) {
|
||||
engine.dialect.URI().Schema = schema
|
||||
}
|
||||
|
||||
// Unscoped always disable struct tag "deleted"
|
||||
func (engine *Engine) Unscoped() *Session {
|
||||
session := engine.NewSession()
|
||||
|
5
vendor/github.com/go-xorm/xorm/engine_cond.go
generated
vendored
5
vendor/github.com/go-xorm/xorm/engine_cond.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
@ -51,7 +52,9 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{},
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
if !strings.Contains(err.Error(), "is not valid") {
|
||||
engine.logger.Warn(err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
10
vendor/github.com/go-xorm/xorm/engine_group.go
generated
vendored
10
vendor/github.com/go-xorm/xorm/engine_group.go
generated
vendored
@ -5,6 +5,8 @@
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
@ -99,6 +101,14 @@ func (eg *EngineGroup) SetColumnMapper(mapper core.IMapper) {
|
||||
}
|
||||
}
|
||||
|
||||
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
|
||||
func (eg *EngineGroup) SetConnMaxLifetime(d time.Duration) {
|
||||
eg.Engine.SetConnMaxLifetime(d)
|
||||
for i := 0; i < len(eg.slaves); i++ {
|
||||
eg.slaves[i].SetConnMaxLifetime(d)
|
||||
}
|
||||
}
|
||||
|
||||
// SetDefaultCacher set the default cacher
|
||||
func (eg *EngineGroup) SetDefaultCacher(cacher core.Cacher) {
|
||||
eg.Engine.SetDefaultCacher(cacher)
|
||||
|
22
vendor/github.com/go-xorm/xorm/engine_maxlife.go
generated
vendored
22
vendor/github.com/go-xorm/xorm/engine_maxlife.go
generated
vendored
@ -1,22 +0,0 @@
|
||||
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.6
|
||||
|
||||
package xorm
|
||||
|
||||
import "time"
|
||||
|
||||
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
|
||||
func (engine *Engine) SetConnMaxLifetime(d time.Duration) {
|
||||
engine.db.SetConnMaxLifetime(d)
|
||||
}
|
||||
|
||||
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
|
||||
func (eg *EngineGroup) SetConnMaxLifetime(d time.Duration) {
|
||||
eg.Engine.SetConnMaxLifetime(d)
|
||||
for i := 0; i < len(eg.slaves); i++ {
|
||||
eg.slaves[i].SetConnMaxLifetime(d)
|
||||
}
|
||||
}
|
113
vendor/github.com/go-xorm/xorm/engine_table.go
generated
vendored
Normal file
113
vendor/github.com/go-xorm/xorm/engine_table.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// TableNameWithSchema will automatically add schema prefix on table name
|
||||
func (engine *Engine) tbNameWithSchema(v string) string {
|
||||
// Add schema name as prefix of table name.
|
||||
// Only for postgres database.
|
||||
if engine.dialect.DBType() == core.POSTGRES &&
|
||||
engine.dialect.URI().Schema != "" &&
|
||||
engine.dialect.URI().Schema != postgresPublicSchema &&
|
||||
strings.Index(v, ".") == -1 {
|
||||
return engine.dialect.URI().Schema + "." + v
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// TableName returns table name with schema prefix if has
|
||||
func (engine *Engine) TableName(bean interface{}, includeSchema ...bool) string {
|
||||
tbName := engine.tbNameNoSchema(bean)
|
||||
if len(includeSchema) > 0 && includeSchema[0] {
|
||||
tbName = engine.tbNameWithSchema(tbName)
|
||||
}
|
||||
|
||||
return tbName
|
||||
}
|
||||
|
||||
// tbName get some table's table name
|
||||
func (session *Session) tbNameNoSchema(table *core.Table) string {
|
||||
if len(session.statement.AltTableName) > 0 {
|
||||
return session.statement.AltTableName
|
||||
}
|
||||
|
||||
return table.Name
|
||||
}
|
||||
|
||||
func (engine *Engine) tbNameForMap(v reflect.Value) string {
|
||||
if v.Type().Implements(tpTableName) {
|
||||
return v.Interface().(TableName).TableName()
|
||||
}
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
if v.Type().Implements(tpTableName) {
|
||||
return v.Interface().(TableName).TableName()
|
||||
}
|
||||
}
|
||||
|
||||
return engine.TableMapper.Obj2Table(v.Type().Name())
|
||||
}
|
||||
|
||||
func (engine *Engine) tbNameNoSchema(tablename interface{}) string {
|
||||
switch tablename.(type) {
|
||||
case []string:
|
||||
t := tablename.([]string)
|
||||
if len(t) > 1 {
|
||||
return fmt.Sprintf("%v AS %v", engine.Quote(t[0]), engine.Quote(t[1]))
|
||||
} else if len(t) == 1 {
|
||||
return engine.Quote(t[0])
|
||||
}
|
||||
case []interface{}:
|
||||
t := tablename.([]interface{})
|
||||
l := len(t)
|
||||
var table string
|
||||
if l > 0 {
|
||||
f := t[0]
|
||||
switch f.(type) {
|
||||
case string:
|
||||
table = f.(string)
|
||||
case TableName:
|
||||
table = f.(TableName).TableName()
|
||||
default:
|
||||
v := rValue(f)
|
||||
t := v.Type()
|
||||
if t.Kind() == reflect.Struct {
|
||||
table = engine.tbNameForMap(v)
|
||||
} else {
|
||||
table = engine.Quote(fmt.Sprintf("%v", f))
|
||||
}
|
||||
}
|
||||
}
|
||||
if l > 1 {
|
||||
return fmt.Sprintf("%v AS %v", engine.Quote(table),
|
||||
engine.Quote(fmt.Sprintf("%v", t[1])))
|
||||
} else if l == 1 {
|
||||
return engine.Quote(table)
|
||||
}
|
||||
case TableName:
|
||||
return tablename.(TableName).TableName()
|
||||
case string:
|
||||
return tablename.(string)
|
||||
case reflect.Value:
|
||||
v := tablename.(reflect.Value)
|
||||
return engine.tbNameForMap(v)
|
||||
default:
|
||||
v := rValue(tablename)
|
||||
t := v.Type()
|
||||
if t.Kind() == reflect.Struct {
|
||||
return engine.tbNameForMap(v)
|
||||
}
|
||||
return engine.Quote(fmt.Sprintf("%v", tablename))
|
||||
}
|
||||
return ""
|
||||
}
|
31
vendor/github.com/go-xorm/xorm/error.go
generated
vendored
31
vendor/github.com/go-xorm/xorm/error.go
generated
vendored
@ -6,23 +6,44 @@ package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrParamsType params error
|
||||
ErrParamsType = errors.New("Params type error")
|
||||
// ErrTableNotFound table not found error
|
||||
ErrTableNotFound = errors.New("Not found table")
|
||||
ErrTableNotFound = errors.New("Table not found")
|
||||
// ErrUnSupportedType unsupported error
|
||||
ErrUnSupportedType = errors.New("Unsupported type error")
|
||||
// ErrNotExist record is not exist error
|
||||
ErrNotExist = errors.New("Not exist error")
|
||||
// ErrNotExist record does not exist error
|
||||
ErrNotExist = errors.New("Record does not exist")
|
||||
// ErrCacheFailed cache failed error
|
||||
ErrCacheFailed = errors.New("Cache failed")
|
||||
// ErrNeedDeletedCond delete needs less one condition error
|
||||
ErrNeedDeletedCond = errors.New("Delete need at least one condition")
|
||||
ErrNeedDeletedCond = errors.New("Delete action needs at least one condition")
|
||||
// ErrNotImplemented not implemented
|
||||
ErrNotImplemented = errors.New("Not implemented")
|
||||
// ErrConditionType condition type unsupported
|
||||
ErrConditionType = errors.New("Unsupported conditon type")
|
||||
ErrConditionType = errors.New("Unsupported condition type")
|
||||
)
|
||||
|
||||
// ErrFieldIsNotExist columns does not exist
|
||||
type ErrFieldIsNotExist struct {
|
||||
FieldName string
|
||||
TableName string
|
||||
}
|
||||
|
||||
func (e ErrFieldIsNotExist) Error() string {
|
||||
return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName)
|
||||
}
|
||||
|
||||
// ErrFieldIsNotValid is not valid
|
||||
type ErrFieldIsNotValid struct {
|
||||
FieldName string
|
||||
TableName string
|
||||
}
|
||||
|
||||
func (e ErrFieldIsNotValid) Error() string {
|
||||
return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName)
|
||||
}
|
||||
|
162
vendor/github.com/go-xorm/xorm/helpers.go
generated
vendored
162
vendor/github.com/go-xorm/xorm/helpers.go
generated
vendored
@ -11,7 +11,6 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
@ -293,19 +292,6 @@ func structName(v reflect.Type) string {
|
||||
return v.Name()
|
||||
}
|
||||
|
||||
func col2NewCols(columns ...string) []string {
|
||||
newColumns := make([]string, 0, len(columns))
|
||||
for _, col := range columns {
|
||||
col = strings.Replace(col, "`", "", -1)
|
||||
col = strings.Replace(col, `"`, "", -1)
|
||||
ccols := strings.Split(col, ",")
|
||||
for _, c := range ccols {
|
||||
newColumns = append(newColumns, strings.TrimSpace(c))
|
||||
}
|
||||
}
|
||||
return newColumns
|
||||
}
|
||||
|
||||
func sliceEq(left, right []string) bool {
|
||||
if len(left) != len(right) {
|
||||
return false
|
||||
@ -320,154 +306,6 @@ func sliceEq(left, right []string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func setColumnInt(bean interface{}, col *core.Column, t int64) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v.CanSet() {
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||
v.SetInt(t)
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
||||
v.SetUint(uint64(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setColumnTime(bean interface{}, col *core.Column, t time.Time) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v.CanSet() {
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Struct:
|
||||
v.Set(reflect.ValueOf(t).Convert(v.Type()))
|
||||
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||
v.SetInt(t.Unix())
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
||||
v.SetUint(uint64(t.Unix()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, includeQuote bool) ([]string, []interface{}, error) {
|
||||
colNames := make([]string, 0, len(table.ColumnsSeq()))
|
||||
args := make([]interface{}, 0, len(table.ColumnsSeq()))
|
||||
|
||||
for _, col := range table.Columns() {
|
||||
if useCol && !col.IsVersion && !col.IsCreated && !col.IsUpdated {
|
||||
if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if col.MapType == core.ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fieldValue := *fieldValuePtr
|
||||
|
||||
if col.IsAutoIncrement {
|
||||
switch fieldValue.Type().Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
|
||||
if fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
|
||||
if fieldValue.Uint() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.String:
|
||||
if len(fieldValue.String()) == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if fieldValue.Pointer() == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if col.IsDeleted {
|
||||
continue
|
||||
}
|
||||
|
||||
if session.statement.ColumnStr != "" {
|
||||
if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok {
|
||||
continue
|
||||
} else if _, ok := session.statement.incrColumns[col.Name]; ok {
|
||||
continue
|
||||
} else if _, ok := session.statement.decrColumns[col.Name]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if session.statement.OmitStr != "" {
|
||||
if _, ok := getFlagForColumn(session.statement.columnMap, col); ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok {
|
||||
if col.Nullable && isZero(fieldValue.Interface()) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
}
|
||||
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||
// if time is non-empty, then set to auto time
|
||||
val, t := session.engine.nowTime(col)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
session.afterClosures = append(session.afterClosures, func(bean interface{}) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.statement.checkVersion {
|
||||
args = append(args, 1)
|
||||
} else {
|
||||
arg, err := session.value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return colNames, args, err
|
||||
}
|
||||
args = append(args, arg)
|
||||
}
|
||||
|
||||
if includeQuote {
|
||||
colNames = append(colNames, session.engine.Quote(col.Name)+" = ?")
|
||||
} else {
|
||||
colNames = append(colNames, col.Name)
|
||||
}
|
||||
}
|
||||
return colNames, args, nil
|
||||
}
|
||||
|
||||
func indexName(tableName, idxName string) string {
|
||||
return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
|
||||
}
|
||||
|
||||
func getFlagForColumn(m map[string]bool, col *core.Column) (val bool, has bool) {
|
||||
if len(m) == 0 {
|
||||
return false, false
|
||||
}
|
||||
|
||||
n := len(col.Name)
|
||||
|
||||
for mk := range m {
|
||||
if len(mk) != n {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(mk, col.Name) {
|
||||
return m[mk], true
|
||||
}
|
||||
}
|
||||
|
||||
return false, false
|
||||
}
|
||||
|
15
vendor/github.com/go-xorm/xorm/interface.go
generated
vendored
15
vendor/github.com/go-xorm/xorm/interface.go
generated
vendored
@ -27,9 +27,10 @@ type Interface interface {
|
||||
Delete(interface{}) (int64, error)
|
||||
Distinct(columns ...string) *Session
|
||||
DropIndexes(bean interface{}) error
|
||||
Exec(string, ...interface{}) (sql.Result, error)
|
||||
Exec(sqlOrAgrs ...interface{}) (sql.Result, error)
|
||||
Exist(bean ...interface{}) (bool, error)
|
||||
Find(interface{}, ...interface{}) error
|
||||
FindAndCount(interface{}, ...interface{}) (int64, error)
|
||||
Get(interface{}) (bool, error)
|
||||
GroupBy(keys string) *Session
|
||||
ID(interface{}) *Session
|
||||
@ -41,6 +42,7 @@ type Interface interface {
|
||||
IsTableExist(beanOrTableName interface{}) (bool, error)
|
||||
Iterate(interface{}, IterFunc) error
|
||||
Limit(int, ...int) *Session
|
||||
MustCols(columns ...string) *Session
|
||||
NoAutoCondition(...bool) *Session
|
||||
NotIn(string, ...interface{}) *Session
|
||||
Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session
|
||||
@ -70,29 +72,40 @@ type EngineInterface interface {
|
||||
|
||||
Before(func(interface{})) *Session
|
||||
Charset(charset string) *Session
|
||||
ClearCache(...interface{}) error
|
||||
CreateTables(...interface{}) error
|
||||
DBMetas() ([]*core.Table, error)
|
||||
Dialect() core.Dialect
|
||||
DropTables(...interface{}) error
|
||||
DumpAllToFile(fp string, tp ...core.DbType) error
|
||||
GetCacher(string) core.Cacher
|
||||
GetColumnMapper() core.IMapper
|
||||
GetDefaultCacher() core.Cacher
|
||||
GetTableMapper() core.IMapper
|
||||
GetTZDatabase() *time.Location
|
||||
GetTZLocation() *time.Location
|
||||
MapCacher(interface{}, core.Cacher) error
|
||||
NewSession() *Session
|
||||
NoAutoTime() *Session
|
||||
Quote(string) string
|
||||
SetCacher(string, core.Cacher)
|
||||
SetConnMaxLifetime(time.Duration)
|
||||
SetDefaultCacher(core.Cacher)
|
||||
SetLogger(logger core.ILogger)
|
||||
SetLogLevel(core.LogLevel)
|
||||
SetMapper(core.IMapper)
|
||||
SetMaxOpenConns(int)
|
||||
SetMaxIdleConns(int)
|
||||
SetSchema(string)
|
||||
SetTZDatabase(tz *time.Location)
|
||||
SetTZLocation(tz *time.Location)
|
||||
ShowExecTime(...bool)
|
||||
ShowSQL(show ...bool)
|
||||
Sync(...interface{}) error
|
||||
Sync2(...interface{}) error
|
||||
StoreEngine(storeEngine string) *Session
|
||||
TableInfo(bean interface{}) *Table
|
||||
TableName(interface{}, ...bool) string
|
||||
UnMapType(reflect.Type)
|
||||
}
|
||||
|
||||
|
6
vendor/github.com/go-xorm/xorm/rows.go
generated
vendored
6
vendor/github.com/go-xorm/xorm/rows.go
generated
vendored
@ -32,7 +32,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||
var args []interface{}
|
||||
var err error
|
||||
|
||||
if err = rows.session.statement.setRefValue(rValue(bean)); err != nil {
|
||||
if err = rows.session.statement.setRefBean(bean); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -94,8 +94,7 @@ func (rows *Rows) Scan(bean interface{}) error {
|
||||
return fmt.Errorf("scan arg is incompatible type to [%v]", rows.beanType)
|
||||
}
|
||||
|
||||
dataStruct := rValue(bean)
|
||||
if err := rows.session.statement.setRefValue(dataStruct); err != nil {
|
||||
if err := rows.session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -104,6 +103,7 @@ func (rows *Rows) Scan(bean interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
dataStruct := rValue(bean)
|
||||
_, err = rows.session.slice2Bean(scanResults, rows.fields, bean, &dataStruct, rows.session.statement.RefTable)
|
||||
if err != nil {
|
||||
return err
|
||||
|
767
vendor/github.com/go-xorm/xorm/session.go
generated
vendored
767
vendor/github.com/go-xorm/xorm/session.go
generated
vendored
@ -102,6 +102,12 @@ func (session *Session) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
// ContextCache enable context cache or not
|
||||
func (session *Session) ContextCache(context ContextCache) *Session {
|
||||
session.statement.context = context
|
||||
return session
|
||||
}
|
||||
|
||||
// IsClosed returns if session is closed
|
||||
func (session *Session) IsClosed() bool {
|
||||
return session.db == nil
|
||||
@ -278,24 +284,22 @@ func (session *Session) doPrepare(db *core.DB, sqlStr string) (stmt *core.Stmt,
|
||||
return
|
||||
}
|
||||
|
||||
func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) *reflect.Value {
|
||||
func (session *Session) getField(dataStruct *reflect.Value, key string, table *core.Table, idx int) (*reflect.Value, error) {
|
||||
var col *core.Column
|
||||
if col = table.GetColumnIdx(key, idx); col == nil {
|
||||
//session.engine.logger.Warnf("table %v has no column %v. %v", table.Name, key, table.ColumnsSeq())
|
||||
return nil
|
||||
return nil, ErrFieldIsNotExist{key, table.Name}
|
||||
}
|
||||
|
||||
fieldValue, err := col.ValueOfV(dataStruct)
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !fieldValue.IsValid() || !fieldValue.CanSet() {
|
||||
session.engine.logger.Warnf("table %v's column %v is not valid or cannot set", table.Name, key)
|
||||
return nil
|
||||
return nil, ErrFieldIsNotValid{key, table.Name}
|
||||
}
|
||||
return fieldValue
|
||||
|
||||
return fieldValue, nil
|
||||
}
|
||||
|
||||
// Cell cell is a result of one column field
|
||||
@ -407,409 +411,417 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
||||
}
|
||||
tempMap[lKey] = idx
|
||||
|
||||
if fieldValue := session.getField(dataStruct, key, table, idx); fieldValue != nil {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
|
||||
|
||||
// if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
continue
|
||||
fieldValue, err := session.getField(dataStruct, key, table, idx)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "is not valid") {
|
||||
session.engine.logger.Warn(err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if fieldValue == nil {
|
||||
continue
|
||||
}
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
|
||||
|
||||
if fieldValue.CanAddr() {
|
||||
if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
if err := structConvert.FromDB(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if fieldValue.CanAddr() {
|
||||
if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
if err := structConvert.FromDB(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := fieldValue.Interface().(core.Conversion); ok {
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
|
||||
fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
|
||||
}
|
||||
fieldValue.Interface().(core.Conversion).FromDB(data)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
rawValueType := reflect.TypeOf(rawValue.Interface())
|
||||
vv := reflect.ValueOf(rawValue.Interface())
|
||||
col := table.GetColumnIdx(key, idx)
|
||||
if col.IsPrimaryKey {
|
||||
pk = append(pk, rawValue.Interface())
|
||||
if _, ok := fieldValue.Interface().(core.Conversion); ok {
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
|
||||
fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
|
||||
}
|
||||
fieldValue.Interface().(core.Conversion).FromDB(data)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
fieldType := fieldValue.Type()
|
||||
hasAssigned := false
|
||||
continue
|
||||
}
|
||||
|
||||
if col.SQLType.IsJson() {
|
||||
var bs []byte
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
bs = []byte(vv.String())
|
||||
} else if rawValueType.ConvertibleTo(core.BytesType) {
|
||||
bs = vv.Bytes()
|
||||
rawValueType := reflect.TypeOf(rawValue.Interface())
|
||||
vv := reflect.ValueOf(rawValue.Interface())
|
||||
col := table.GetColumnIdx(key, idx)
|
||||
if col.IsPrimaryKey {
|
||||
pk = append(pk, rawValue.Interface())
|
||||
}
|
||||
fieldType := fieldValue.Type()
|
||||
hasAssigned := false
|
||||
|
||||
if col.SQLType.IsJson() {
|
||||
var bs []byte
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
bs = []byte(vv.String())
|
||||
} else if rawValueType.ConvertibleTo(core.BytesType) {
|
||||
bs = vv.Bytes()
|
||||
} else {
|
||||
return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind())
|
||||
}
|
||||
|
||||
hasAssigned = true
|
||||
|
||||
if len(bs) > 0 {
|
||||
if fieldType.Kind() == reflect.String {
|
||||
fieldValue.SetString(string(bs))
|
||||
continue
|
||||
}
|
||||
if fieldValue.CanAddr() {
|
||||
err := json.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind())
|
||||
}
|
||||
|
||||
hasAssigned = true
|
||||
|
||||
if len(bs) > 0 {
|
||||
if fieldType.Kind() == reflect.String {
|
||||
fieldValue.SetString(string(bs))
|
||||
continue
|
||||
}
|
||||
if fieldValue.CanAddr() {
|
||||
err := json.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(bs, x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(bs, x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
switch fieldType.Kind() {
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
// TODO: reimplement this
|
||||
var bs []byte
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
bs = []byte(vv.String())
|
||||
} else if rawValueType.ConvertibleTo(core.BytesType) {
|
||||
bs = vv.Bytes()
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
hasAssigned = true
|
||||
if len(bs) > 0 {
|
||||
if fieldValue.CanAddr() {
|
||||
err := json.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(bs, x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
switch fieldType.Kind() {
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
// TODO: reimplement this
|
||||
var bs []byte
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
bs = []byte(vv.String())
|
||||
} else if rawValueType.ConvertibleTo(core.BytesType) {
|
||||
bs = vv.Bytes()
|
||||
}
|
||||
|
||||
hasAssigned = true
|
||||
if len(bs) > 0 {
|
||||
if fieldValue.CanAddr() {
|
||||
err := json.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(bs, x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
}
|
||||
}
|
||||
case reflect.Slice, reflect.Array:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
switch rawValueType.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
if fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
hasAssigned = true
|
||||
if col.SQLType.IsText() {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(vv.Bytes(), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
} else {
|
||||
if fieldValue.Len() > 0 {
|
||||
for i := 0; i < fieldValue.Len(); i++ {
|
||||
if i < vv.Len() {
|
||||
fieldValue.Index(i).Set(vv.Index(i))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < vv.Len(); i++ {
|
||||
fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
hasAssigned = true
|
||||
fieldValue.SetString(vv.String())
|
||||
}
|
||||
case reflect.Bool:
|
||||
if rawValueType.Kind() == reflect.Bool {
|
||||
hasAssigned = true
|
||||
fieldValue.SetBool(vv.Bool())
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
hasAssigned = true
|
||||
fieldValue.SetInt(vv.Int())
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Float32, reflect.Float64:
|
||||
hasAssigned = true
|
||||
fieldValue.SetFloat(vv.Float())
|
||||
}
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
hasAssigned = true
|
||||
fieldValue.SetUint(vv.Uint())
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
hasAssigned = true
|
||||
fieldValue.SetUint(uint64(vv.Int()))
|
||||
}
|
||||
case reflect.Struct:
|
||||
if fieldType.ConvertibleTo(core.TimeType) {
|
||||
dbTZ := session.engine.DatabaseTZ
|
||||
if col.TimeZone != nil {
|
||||
dbTZ = col.TimeZone
|
||||
}
|
||||
|
||||
if rawValueType == core.TimeType {
|
||||
switch rawValueType.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
if fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
hasAssigned = true
|
||||
|
||||
t := vv.Convert(core.TimeType).Interface().(time.Time)
|
||||
|
||||
z, _ := t.Zone()
|
||||
// set new location if database don't save timezone or give an incorrect timezone
|
||||
if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location
|
||||
session.engine.logger.Debugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location())
|
||||
t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
|
||||
t.Minute(), t.Second(), t.Nanosecond(), dbTZ)
|
||||
}
|
||||
|
||||
t = t.In(session.engine.TZLocation)
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
} else if rawValueType == core.IntType || rawValueType == core.Int64Type ||
|
||||
rawValueType == core.Int32Type {
|
||||
hasAssigned = true
|
||||
|
||||
t := time.Unix(vv.Int(), 0).In(session.engine.TZLocation)
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
} else {
|
||||
if d, ok := vv.Interface().([]uint8); ok {
|
||||
hasAssigned = true
|
||||
t, err := session.byte2Time(col, d)
|
||||
if err != nil {
|
||||
session.engine.logger.Error("byte2Time error:", err.Error())
|
||||
hasAssigned = false
|
||||
} else {
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
}
|
||||
} else if d, ok := vv.Interface().(string); ok {
|
||||
hasAssigned = true
|
||||
t, err := session.str2Time(col, d)
|
||||
if err != nil {
|
||||
session.engine.logger.Error("byte2Time error:", err.Error())
|
||||
hasAssigned = false
|
||||
} else {
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("rawValueType is %v, value is %v", rawValueType, vv.Interface())
|
||||
}
|
||||
}
|
||||
} else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
|
||||
// !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
|
||||
hasAssigned = true
|
||||
if err := nulVal.Scan(vv.Interface()); err != nil {
|
||||
session.engine.logger.Error("sql.Sanner error:", err.Error())
|
||||
hasAssigned = false
|
||||
}
|
||||
} else if col.SQLType.IsJson() {
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
hasAssigned = true
|
||||
x := reflect.New(fieldType)
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
}
|
||||
} else if rawValueType.Kind() == reflect.Slice {
|
||||
hasAssigned = true
|
||||
x := reflect.New(fieldType)
|
||||
if len(vv.Bytes()) > 0 {
|
||||
if col.SQLType.IsText() {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(vv.Bytes(), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
}
|
||||
}
|
||||
} else if session.statement.UseCascade {
|
||||
table, err := session.engine.autoMapType(*fieldValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasAssigned = true
|
||||
if len(table.PrimaryKeys) != 1 {
|
||||
return nil, errors.New("unsupported non or composited primary key cascade")
|
||||
}
|
||||
var pk = make(core.PK, len(table.PrimaryKeys))
|
||||
pk[0], err = asKind(vv, rawValueType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isPKZero(pk) {
|
||||
// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
|
||||
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||
// property to be fetched lazily
|
||||
structInter := reflect.New(fieldValue.Type())
|
||||
has, err := session.ID(pk).NoCascade().get(structInter.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if has {
|
||||
fieldValue.Set(structInter.Elem())
|
||||
} else {
|
||||
return nil, errors.New("cascade obj is not exist")
|
||||
if fieldValue.Len() > 0 {
|
||||
for i := 0; i < fieldValue.Len(); i++ {
|
||||
if i < vv.Len() {
|
||||
fieldValue.Index(i).Set(vv.Index(i))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < vv.Len(); i++ {
|
||||
fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Ptr:
|
||||
// !nashtsai! TODO merge duplicated codes above
|
||||
switch fieldType {
|
||||
// following types case matching ptr's native type, therefore assign ptr directly
|
||||
case core.PtrStringType:
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
x := vv.String()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrBoolType:
|
||||
if rawValueType.Kind() == reflect.Bool {
|
||||
x := vv.Bool()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrTimeType:
|
||||
if rawValueType == core.PtrTimeType {
|
||||
hasAssigned = true
|
||||
var x = rawValue.Interface().(time.Time)
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrFloat64Type:
|
||||
if rawValueType.Kind() == reflect.Float64 {
|
||||
x := vv.Float()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrUint64Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint64(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt64Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
x := vv.Int()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrFloat32Type:
|
||||
if rawValueType.Kind() == reflect.Float64 {
|
||||
var x = float32(vv.Float())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrIntType:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt32Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int32(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt8Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int8(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt16Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int16(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrUintType:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrUint32Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint32(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.Uint8Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint8(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.Uint16Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint16(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.Complex64Type:
|
||||
var x complex64
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), &x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
hasAssigned = true
|
||||
case core.Complex128Type:
|
||||
var x complex128
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), &x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
hasAssigned = true
|
||||
} // switch fieldType
|
||||
} // switch fieldType.Kind()
|
||||
}
|
||||
case reflect.String:
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
hasAssigned = true
|
||||
fieldValue.SetString(vv.String())
|
||||
}
|
||||
case reflect.Bool:
|
||||
if rawValueType.Kind() == reflect.Bool {
|
||||
hasAssigned = true
|
||||
fieldValue.SetBool(vv.Bool())
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
hasAssigned = true
|
||||
fieldValue.SetInt(vv.Int())
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Float32, reflect.Float64:
|
||||
hasAssigned = true
|
||||
fieldValue.SetFloat(vv.Float())
|
||||
}
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
switch rawValueType.Kind() {
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
hasAssigned = true
|
||||
fieldValue.SetUint(vv.Uint())
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
hasAssigned = true
|
||||
fieldValue.SetUint(uint64(vv.Int()))
|
||||
}
|
||||
case reflect.Struct:
|
||||
if fieldType.ConvertibleTo(core.TimeType) {
|
||||
dbTZ := session.engine.DatabaseTZ
|
||||
if col.TimeZone != nil {
|
||||
dbTZ = col.TimeZone
|
||||
}
|
||||
|
||||
// !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value
|
||||
if !hasAssigned {
|
||||
data, err := value2Bytes(&rawValue)
|
||||
if rawValueType == core.TimeType {
|
||||
hasAssigned = true
|
||||
|
||||
t := vv.Convert(core.TimeType).Interface().(time.Time)
|
||||
|
||||
z, _ := t.Zone()
|
||||
// set new location if database don't save timezone or give an incorrect timezone
|
||||
if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location
|
||||
session.engine.logger.Debugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location())
|
||||
t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
|
||||
t.Minute(), t.Second(), t.Nanosecond(), dbTZ)
|
||||
}
|
||||
|
||||
t = t.In(session.engine.TZLocation)
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
} else if rawValueType == core.IntType || rawValueType == core.Int64Type ||
|
||||
rawValueType == core.Int32Type {
|
||||
hasAssigned = true
|
||||
|
||||
t := time.Unix(vv.Int(), 0).In(session.engine.TZLocation)
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
} else {
|
||||
if d, ok := vv.Interface().([]uint8); ok {
|
||||
hasAssigned = true
|
||||
t, err := session.byte2Time(col, d)
|
||||
if err != nil {
|
||||
session.engine.logger.Error("byte2Time error:", err.Error())
|
||||
hasAssigned = false
|
||||
} else {
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
}
|
||||
} else if d, ok := vv.Interface().(string); ok {
|
||||
hasAssigned = true
|
||||
t, err := session.str2Time(col, d)
|
||||
if err != nil {
|
||||
session.engine.logger.Error("byte2Time error:", err.Error())
|
||||
hasAssigned = false
|
||||
} else {
|
||||
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("rawValueType is %v, value is %v", rawValueType, vv.Interface())
|
||||
}
|
||||
}
|
||||
} else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
|
||||
// !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
|
||||
hasAssigned = true
|
||||
if err := nulVal.Scan(vv.Interface()); err != nil {
|
||||
session.engine.logger.Error("sql.Sanner error:", err.Error())
|
||||
hasAssigned = false
|
||||
}
|
||||
} else if col.SQLType.IsJson() {
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
hasAssigned = true
|
||||
x := reflect.New(fieldType)
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
}
|
||||
} else if rawValueType.Kind() == reflect.Slice {
|
||||
hasAssigned = true
|
||||
x := reflect.New(fieldType)
|
||||
if len(vv.Bytes()) > 0 {
|
||||
err := json.Unmarshal(vv.Bytes(), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(x.Elem())
|
||||
}
|
||||
}
|
||||
} else if session.statement.UseCascade {
|
||||
table, err := session.engine.autoMapType(*fieldValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = session.bytes2Value(col, fieldValue, data); err != nil {
|
||||
hasAssigned = true
|
||||
if len(table.PrimaryKeys) != 1 {
|
||||
return nil, errors.New("unsupported non or composited primary key cascade")
|
||||
}
|
||||
var pk = make(core.PK, len(table.PrimaryKeys))
|
||||
pk[0], err = asKind(vv, rawValueType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isPKZero(pk) {
|
||||
// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
|
||||
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||
// property to be fetched lazily
|
||||
structInter := reflect.New(fieldValue.Type())
|
||||
has, err := session.ID(pk).NoCascade().get(structInter.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if has {
|
||||
fieldValue.Set(structInter.Elem())
|
||||
} else {
|
||||
return nil, errors.New("cascade obj is not exist")
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Ptr:
|
||||
// !nashtsai! TODO merge duplicated codes above
|
||||
switch fieldType {
|
||||
// following types case matching ptr's native type, therefore assign ptr directly
|
||||
case core.PtrStringType:
|
||||
if rawValueType.Kind() == reflect.String {
|
||||
x := vv.String()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrBoolType:
|
||||
if rawValueType.Kind() == reflect.Bool {
|
||||
x := vv.Bool()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrTimeType:
|
||||
if rawValueType == core.PtrTimeType {
|
||||
hasAssigned = true
|
||||
var x = rawValue.Interface().(time.Time)
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrFloat64Type:
|
||||
if rawValueType.Kind() == reflect.Float64 {
|
||||
x := vv.Float()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrUint64Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint64(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt64Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
x := vv.Int()
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrFloat32Type:
|
||||
if rawValueType.Kind() == reflect.Float64 {
|
||||
var x = float32(vv.Float())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrIntType:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt32Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int32(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt8Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int8(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrInt16Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = int16(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrUintType:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.PtrUint32Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint32(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.Uint8Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint8(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.Uint16Type:
|
||||
if rawValueType.Kind() == reflect.Int64 {
|
||||
var x = uint16(vv.Int())
|
||||
hasAssigned = true
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
case core.Complex64Type:
|
||||
var x complex64
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), &x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
hasAssigned = true
|
||||
case core.Complex128Type:
|
||||
var x complex128
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), &x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldValue.Set(reflect.ValueOf(&x))
|
||||
}
|
||||
hasAssigned = true
|
||||
} // switch fieldType
|
||||
} // switch fieldType.Kind()
|
||||
|
||||
// !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value
|
||||
if !hasAssigned {
|
||||
data, err := value2Bytes(&rawValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = session.bytes2Value(col, fieldValue, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -828,15 +840,6 @@ func (session *Session) LastSQL() (string, []interface{}) {
|
||||
return session.lastSQL, session.lastSQLArgs
|
||||
}
|
||||
|
||||
// tbName get some table's table name
|
||||
func (session *Session) tbNameNoSchema(table *core.Table) string {
|
||||
if len(session.statement.AltTableName) > 0 {
|
||||
return session.statement.AltTableName
|
||||
}
|
||||
|
||||
return table.Name
|
||||
}
|
||||
|
||||
// Unscoped always disable struct tag "deleted"
|
||||
func (session *Session) Unscoped() *Session {
|
||||
session.statement.Unscoped()
|
||||
|
115
vendor/github.com/go-xorm/xorm/session_cols.go
generated
vendored
115
vendor/github.com/go-xorm/xorm/session_cols.go
generated
vendored
@ -4,6 +4,121 @@
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type incrParam struct {
|
||||
colName string
|
||||
arg interface{}
|
||||
}
|
||||
|
||||
type decrParam struct {
|
||||
colName string
|
||||
arg interface{}
|
||||
}
|
||||
|
||||
type exprParam struct {
|
||||
colName string
|
||||
expr string
|
||||
}
|
||||
|
||||
type columnMap []string
|
||||
|
||||
func (m columnMap) contain(colName string) bool {
|
||||
if len(m) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
n := len(colName)
|
||||
for _, mk := range m {
|
||||
if len(mk) != n {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(mk, colName) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *columnMap) add(colName string) bool {
|
||||
if m.contain(colName) {
|
||||
return false
|
||||
}
|
||||
*m = append(*m, colName)
|
||||
return true
|
||||
}
|
||||
|
||||
func setColumnInt(bean interface{}, col *core.Column, t int64) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v.CanSet() {
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||
v.SetInt(t)
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
||||
v.SetUint(uint64(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setColumnTime(bean interface{}, col *core.Column, t time.Time) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v.CanSet() {
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Struct:
|
||||
v.Set(reflect.ValueOf(t).Convert(v.Type()))
|
||||
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||
v.SetInt(t.Unix())
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
||||
v.SetUint(uint64(t.Unix()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getFlagForColumn(m map[string]bool, col *core.Column) (val bool, has bool) {
|
||||
if len(m) == 0 {
|
||||
return false, false
|
||||
}
|
||||
|
||||
n := len(col.Name)
|
||||
|
||||
for mk := range m {
|
||||
if len(mk) != n {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(mk, col.Name) {
|
||||
return m[mk], true
|
||||
}
|
||||
}
|
||||
|
||||
return false, false
|
||||
}
|
||||
|
||||
func col2NewCols(columns ...string) []string {
|
||||
newColumns := make([]string, 0, len(columns))
|
||||
for _, col := range columns {
|
||||
col = strings.Replace(col, "`", "", -1)
|
||||
col = strings.Replace(col, `"`, "", -1)
|
||||
ccols := strings.Split(col, ",")
|
||||
for _, c := range ccols {
|
||||
newColumns = append(newColumns, strings.TrimSpace(c))
|
||||
}
|
||||
}
|
||||
return newColumns
|
||||
}
|
||||
|
||||
// Incr provides a query string like "count = count + 1"
|
||||
func (session *Session) Incr(column string, arg ...interface{}) *Session {
|
||||
session.statement.Incr(column, arg...)
|
||||
|
6
vendor/github.com/go-xorm/xorm/session_delete.go
generated
vendored
6
vendor/github.com/go-xorm/xorm/session_delete.go
generated
vendored
@ -27,7 +27,7 @@ func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string,
|
||||
return ErrCacheFailed
|
||||
}
|
||||
|
||||
cacher := session.engine.getCacher2(table)
|
||||
cacher := session.engine.getCacher(tableName)
|
||||
pkColumns := table.PKColumns()
|
||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||
if err != nil {
|
||||
@ -79,7 +79,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
if err := session.statement.setRefValue(rValue(bean)); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||
})
|
||||
}
|
||||
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||
if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache {
|
||||
session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...)
|
||||
}
|
||||
|
||||
|
15
vendor/github.com/go-xorm/xorm/session_exist.go
generated
vendored
15
vendor/github.com/go-xorm/xorm/session_exist.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
||||
"reflect"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// Exist returns true if the record exist otherwise return false
|
||||
@ -35,10 +36,18 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
|
||||
if session.engine.dialect.DBType() == core.MSSQL {
|
||||
sqlStr = fmt.Sprintf("SELECT top 1 * FROM %s WHERE %s", tableName, condSQL)
|
||||
} else {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
|
||||
}
|
||||
args = condArgs
|
||||
} else {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
|
||||
if session.engine.dialect.DBType() == core.MSSQL {
|
||||
sqlStr = fmt.Sprintf("SELECT top 1 * FROM %s", tableName)
|
||||
} else {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
|
||||
}
|
||||
args = []interface{}{}
|
||||
}
|
||||
} else {
|
||||
@ -48,7 +57,7 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
||||
}
|
||||
|
||||
if beanValue.Elem().Kind() == reflect.Struct {
|
||||
if err := session.statement.setRefValue(beanValue.Elem()); err != nil {
|
||||
if err := session.statement.setRefBean(bean[0]); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
53
vendor/github.com/go-xorm/xorm/session_find.go
generated
vendored
53
vendor/github.com/go-xorm/xorm/session_find.go
generated
vendored
@ -29,6 +29,39 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
return session.find(rowsSlicePtr, condiBean...)
|
||||
}
|
||||
|
||||
// FindAndCount find the results and also return the counts
|
||||
func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...interface{}) (int64, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
session.autoResetStatement = false
|
||||
err := session.find(rowsSlicePtr, condiBean...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
||||
if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map {
|
||||
return 0, errors.New("needs a pointer to a slice or a map")
|
||||
}
|
||||
|
||||
sliceElementType := sliceValue.Type().Elem()
|
||||
if sliceElementType.Kind() == reflect.Ptr {
|
||||
sliceElementType = sliceElementType.Elem()
|
||||
}
|
||||
session.autoResetStatement = true
|
||||
|
||||
if session.statement.selectStr != "" {
|
||||
session.statement.selectStr = ""
|
||||
}
|
||||
if session.statement.OrderStr != "" {
|
||||
session.statement.OrderStr = ""
|
||||
}
|
||||
|
||||
return session.Count(reflect.New(sliceElementType).Interface())
|
||||
}
|
||||
|
||||
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
||||
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
||||
if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map {
|
||||
@ -42,7 +75,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
if sliceElementType.Kind() == reflect.Ptr {
|
||||
if sliceElementType.Elem().Kind() == reflect.Struct {
|
||||
pv := reflect.New(sliceElementType.Elem())
|
||||
if err := session.statement.setRefValue(pv.Elem()); err != nil {
|
||||
if err := session.statement.setRefValue(pv); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@ -50,7 +83,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
}
|
||||
} else if sliceElementType.Kind() == reflect.Struct {
|
||||
pv := reflect.New(sliceElementType)
|
||||
if err := session.statement.setRefValue(pv.Elem()); err != nil {
|
||||
if err := session.statement.setRefValue(pv); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@ -102,7 +135,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
if session.statement.JoinStr == "" {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = session.statement.genColumnStr()
|
||||
}
|
||||
@ -110,7 +143,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
} else {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = "*"
|
||||
}
|
||||
@ -128,7 +161,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
}
|
||||
|
||||
args = append(session.statement.joinArgs, condArgs...)
|
||||
sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL)
|
||||
sqlStr, err = session.statement.genSelectSQL(columnStr, condSQL, true, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -143,7 +176,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
}
|
||||
|
||||
if session.canCache() {
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil &&
|
||||
if cacher := session.engine.getCacher(table.Name); cacher != nil &&
|
||||
!session.statement.IsDistinct &&
|
||||
!session.statement.unscoped {
|
||||
err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...)
|
||||
@ -288,6 +321,12 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||
return ErrCacheFailed
|
||||
}
|
||||
|
||||
tableName := session.statement.TableName()
|
||||
cacher := session.engine.getCacher(tableName)
|
||||
if cacher == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, filter := range session.engine.dialect.Filters() {
|
||||
sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable)
|
||||
}
|
||||
@ -297,9 +336,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||
return ErrCacheFailed
|
||||
}
|
||||
|
||||
tableName := session.statement.TableName()
|
||||
table := session.statement.RefTable
|
||||
cacher := session.engine.getCacher2(table)
|
||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||
if err != nil {
|
||||
rows, err := session.queryRows(newsql, args...)
|
||||
|
42
vendor/github.com/go-xorm/xorm/session_get.go
generated
vendored
42
vendor/github.com/go-xorm/xorm/session_get.go
generated
vendored
@ -5,7 +5,9 @@
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
@ -30,7 +32,7 @@ func (session *Session) get(bean interface{}) (bool, error) {
|
||||
}
|
||||
|
||||
if beanValue.Elem().Kind() == reflect.Struct {
|
||||
if err := session.statement.setRefValue(beanValue.Elem()); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
@ -56,7 +58,7 @@ func (session *Session) get(bean interface{}) (bool, error) {
|
||||
table := session.statement.RefTable
|
||||
|
||||
if session.canCache() && beanValue.Elem().Kind() == reflect.Struct {
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil &&
|
||||
if cacher := session.engine.getCacher(table.Name); cacher != nil &&
|
||||
!session.statement.unscoped {
|
||||
has, err := session.cacheGet(bean, sqlStr, args...)
|
||||
if err != ErrCacheFailed {
|
||||
@ -65,7 +67,28 @@ func (session *Session) get(bean interface{}) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return session.nocacheGet(beanValue.Elem().Kind(), table, bean, sqlStr, args...)
|
||||
context := session.statement.context
|
||||
if context != nil {
|
||||
res := context.Get(fmt.Sprintf("%v-%v", sqlStr, args))
|
||||
if res != nil {
|
||||
structValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||
structValue.Set(reflect.Indirect(reflect.ValueOf(res)))
|
||||
session.lastSQL = ""
|
||||
session.lastSQLArgs = nil
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
has, err := session.nocacheGet(beanValue.Elem().Kind(), table, bean, sqlStr, args...)
|
||||
if err != nil || !has {
|
||||
return has, err
|
||||
}
|
||||
|
||||
if context != nil {
|
||||
context.Put(fmt.Sprintf("%v-%v", sqlStr, args), bean)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bean interface{}, sqlStr string, args ...interface{}) (bool, error) {
|
||||
@ -76,9 +99,19 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
||||
defer rows.Close()
|
||||
|
||||
if !rows.Next() {
|
||||
if rows.Err() != nil {
|
||||
return false, rows.Err()
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
switch bean.(type) {
|
||||
case sql.NullInt64, sql.NullBool, sql.NullFloat64, sql.NullString:
|
||||
return true, rows.Scan(&bean)
|
||||
case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString:
|
||||
return true, rows.Scan(bean)
|
||||
}
|
||||
|
||||
switch beanKind {
|
||||
case reflect.Struct:
|
||||
fields, err := rows.Columns()
|
||||
@ -126,8 +159,9 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||
return false, ErrCacheFailed
|
||||
}
|
||||
|
||||
cacher := session.engine.getCacher2(session.statement.RefTable)
|
||||
tableName := session.statement.TableName()
|
||||
cacher := session.engine.getCacher(tableName)
|
||||
|
||||
session.engine.logger.Debug("[cacheGet] find sql:", newsql, args)
|
||||
table := session.statement.RefTable
|
||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||
|
168
vendor/github.com/go-xorm/xorm/session_insert.go
generated
vendored
168
vendor/github.com/go-xorm/xorm/session_insert.go
generated
vendored
@ -66,11 +66,12 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||
return 0, errors.New("could not insert a empty slice")
|
||||
}
|
||||
|
||||
if err := session.statement.setRefValue(reflect.ValueOf(sliceValue.Index(0).Interface())); err != nil {
|
||||
if err := session.statement.setRefBean(sliceValue.Index(0).Interface()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(session.statement.TableName()) <= 0 {
|
||||
tableName := session.statement.TableName()
|
||||
if len(tableName) <= 0 {
|
||||
return 0, ErrTableNotFound
|
||||
}
|
||||
|
||||
@ -115,15 +116,11 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||
if col.IsDeleted {
|
||||
continue
|
||||
}
|
||||
if session.statement.ColumnStr != "" {
|
||||
if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok {
|
||||
continue
|
||||
}
|
||||
if session.statement.omitColumnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
if session.statement.OmitStr != "" {
|
||||
if _, ok := getFlagForColumn(session.statement.columnMap, col); ok {
|
||||
continue
|
||||
}
|
||||
if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
|
||||
val, t := session.engine.nowTime(col)
|
||||
@ -170,15 +167,11 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||
if col.IsDeleted {
|
||||
continue
|
||||
}
|
||||
if session.statement.ColumnStr != "" {
|
||||
if _, ok := getFlagForColumn(session.statement.columnMap, col); !ok {
|
||||
continue
|
||||
}
|
||||
if session.statement.omitColumnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
if session.statement.OmitStr != "" {
|
||||
if _, ok := getFlagForColumn(session.statement.columnMap, col); ok {
|
||||
continue
|
||||
}
|
||||
if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
|
||||
val, t := session.engine.nowTime(col)
|
||||
@ -211,38 +204,33 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||
}
|
||||
cleanupProcessorsClosures(&session.beforeClosures)
|
||||
|
||||
var sql = "INSERT INTO %s (%v%v%v) VALUES (%v)"
|
||||
var statement string
|
||||
var tableName = session.statement.TableName()
|
||||
var sql string
|
||||
if session.engine.dialect.DBType() == core.ORACLE {
|
||||
sql = "INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL"
|
||||
temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr())
|
||||
statement = fmt.Sprintf(sql,
|
||||
sql = fmt.Sprintf("INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colMultiPlaces, temp))
|
||||
} else {
|
||||
statement = fmt.Sprintf(sql,
|
||||
sql = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colMultiPlaces, "),("))
|
||||
}
|
||||
res, err := session.exec(statement, args...)
|
||||
res, err := session.exec(sql, args...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||
session.cacheInsert(table, tableName)
|
||||
}
|
||||
session.cacheInsert(tableName)
|
||||
|
||||
lenAfterClosures := len(session.afterClosures)
|
||||
for i := 0; i < size; i++ {
|
||||
@ -298,7 +286,7 @@ func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
|
||||
}
|
||||
|
||||
func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||
if err := session.statement.setRefValue(rValue(bean)); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(session.statement.TableName()) <= 0 {
|
||||
@ -316,8 +304,8 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||
if processor, ok := interface{}(bean).(BeforeInsertProcessor); ok {
|
||||
processor.BeforeInsert()
|
||||
}
|
||||
// --
|
||||
colNames, args, err := genCols(session.statement.RefTable, session, bean, false, false)
|
||||
|
||||
colNames, args, err := session.genInsertColumns(bean)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -402,9 +390,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||
|
||||
defer handleAfterInsertProcessorFunc(bean)
|
||||
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||
session.cacheInsert(table, tableName)
|
||||
}
|
||||
session.cacheInsert(tableName)
|
||||
|
||||
if table.Version != "" && session.statement.checkVersion {
|
||||
verValue, err := table.VersionColumn().ValueOf(bean)
|
||||
@ -447,9 +433,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||
}
|
||||
defer handleAfterInsertProcessorFunc(bean)
|
||||
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||
session.cacheInsert(table, tableName)
|
||||
}
|
||||
session.cacheInsert(tableName)
|
||||
|
||||
if table.Version != "" && session.statement.checkVersion {
|
||||
verValue, err := table.VersionColumn().ValueOf(bean)
|
||||
@ -490,9 +474,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||
|
||||
defer handleAfterInsertProcessorFunc(bean)
|
||||
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||
session.cacheInsert(table, tableName)
|
||||
}
|
||||
session.cacheInsert(tableName)
|
||||
|
||||
if table.Version != "" && session.statement.checkVersion {
|
||||
verValue, err := table.VersionColumn().ValueOf(bean)
|
||||
@ -539,16 +521,104 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
||||
return session.innerInsert(bean)
|
||||
}
|
||||
|
||||
func (session *Session) cacheInsert(table *core.Table, tables ...string) error {
|
||||
if table == nil {
|
||||
return ErrCacheFailed
|
||||
func (session *Session) cacheInsert(table string) error {
|
||||
if !session.statement.UseCache {
|
||||
return nil
|
||||
}
|
||||
|
||||
cacher := session.engine.getCacher2(table)
|
||||
for _, t := range tables {
|
||||
session.engine.logger.Debug("[cache] clear sql:", t)
|
||||
cacher.ClearIds(t)
|
||||
cacher := session.engine.getCacher(table)
|
||||
if cacher == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
session.engine.logger.Debug("[cache] clear sql:", table)
|
||||
cacher.ClearIds(table)
|
||||
return nil
|
||||
}
|
||||
|
||||
// genInsertColumns generates insert needed columns
|
||||
func (session *Session) genInsertColumns(bean interface{}) ([]string, []interface{}, error) {
|
||||
table := session.statement.RefTable
|
||||
colNames := make([]string, 0, len(table.ColumnsSeq()))
|
||||
args := make([]interface{}, 0, len(table.ColumnsSeq()))
|
||||
|
||||
for _, col := range table.Columns() {
|
||||
if col.MapType == core.ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
|
||||
if col.IsDeleted {
|
||||
continue
|
||||
}
|
||||
|
||||
if session.statement.omitColumnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(session.statement.columnMap) > 0 && !session.statement.columnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := session.statement.incrColumns[col.Name]; ok {
|
||||
continue
|
||||
} else if _, ok := session.statement.decrColumns[col.Name]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fieldValue := *fieldValuePtr
|
||||
|
||||
if col.IsAutoIncrement {
|
||||
switch fieldValue.Type().Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
|
||||
if fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
|
||||
if fieldValue.Uint() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.String:
|
||||
if len(fieldValue.String()) == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if fieldValue.Pointer() == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok {
|
||||
if col.Nullable && isZero(fieldValue.Interface()) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
}
|
||||
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||
// if time is non-empty, then set to auto time
|
||||
val, t := session.engine.nowTime(col)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
session.afterClosures = append(session.afterClosures, func(bean interface{}) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.statement.checkVersion {
|
||||
args = append(args, 1)
|
||||
} else {
|
||||
arg, err := session.value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return colNames, args, err
|
||||
}
|
||||
args = append(args, arg)
|
||||
}
|
||||
|
||||
colNames = append(colNames, col.Name)
|
||||
}
|
||||
return colNames, args, nil
|
||||
}
|
||||
|
76
vendor/github.com/go-xorm/xorm/session_query.go
generated
vendored
76
vendor/github.com/go-xorm/xorm/session_query.go
generated
vendored
@ -17,7 +17,7 @@ import (
|
||||
|
||||
func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) {
|
||||
if len(sqlorArgs) > 0 {
|
||||
return sqlorArgs[0].(string), sqlorArgs[1:], nil
|
||||
return convertSQLOrArgs(sqlorArgs...)
|
||||
}
|
||||
|
||||
if session.statement.RawSQL != "" {
|
||||
@ -35,7 +35,7 @@ func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interfa
|
||||
if session.statement.JoinStr == "" {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = session.statement.genColumnStr()
|
||||
}
|
||||
@ -43,7 +43,7 @@ func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interfa
|
||||
} else {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.statement.Engine.Quote(strings.Replace(session.statement.GroupByStr, ",", session.engine.Quote(","), -1))
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = "*"
|
||||
}
|
||||
@ -54,13 +54,17 @@ func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interfa
|
||||
}
|
||||
}
|
||||
|
||||
if err := session.statement.processIDParam(); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
args := append(session.statement.joinArgs, condArgs...)
|
||||
sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL)
|
||||
sqlStr, err := session.statement.genSelectSQL(columnStr, condSQL, true, true)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
@ -162,6 +166,34 @@ func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func row2sliceStr(rows *core.Rows, fields []string) (results []string, err error) {
|
||||
result := make([]string, 0, len(fields))
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < len(fields); i++ {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[i]))
|
||||
// if row is null then as empty string
|
||||
if rawValue.Interface() == nil {
|
||||
result = append(result, "")
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2String(&rawValue); err == nil {
|
||||
result = append(result, data)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
@ -178,6 +210,22 @@ func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error)
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func rows2SliceString(rows *core.Rows) (resultsSlice [][]string, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
record, err := row2sliceStr(rows, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultsSlice = append(resultsSlice, record)
|
||||
}
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
// QueryString runs a raw sql and return records as []map[string]string
|
||||
func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) {
|
||||
if session.isAutoClose {
|
||||
@ -198,6 +246,26 @@ func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]stri
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
// QuerySliceString runs a raw sql and return records as [][]string
|
||||
func (session *Session) QuerySliceString(sqlorArgs ...interface{}) ([][]string, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := session.queryRows(sqlStr, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return rows2SliceString(rows)
|
||||
}
|
||||
|
||||
func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
|
||||
resultsMap = make(map[string]interface{}, len(fields))
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
|
26
vendor/github.com/go-xorm/xorm/session_raw.go
generated
vendored
26
vendor/github.com/go-xorm/xorm/session_raw.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
@ -193,11 +194,34 @@ func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, er
|
||||
return session.DB().Exec(sqlStr, args...)
|
||||
}
|
||||
|
||||
func convertSQLOrArgs(sqlorArgs ...interface{}) (string, []interface{}, error) {
|
||||
switch sqlorArgs[0].(type) {
|
||||
case string:
|
||||
return sqlorArgs[0].(string), sqlorArgs[1:], nil
|
||||
case *builder.Builder:
|
||||
return sqlorArgs[0].(*builder.Builder).ToSQL()
|
||||
case builder.Builder:
|
||||
bd := sqlorArgs[0].(builder.Builder)
|
||||
return bd.ToSQL()
|
||||
}
|
||||
|
||||
return "", nil, ErrUnSupportedType
|
||||
}
|
||||
|
||||
// Exec raw sql
|
||||
func (session *Session) Exec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
||||
func (session *Session) Exec(sqlorArgs ...interface{}) (sql.Result, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
if len(sqlorArgs) == 0 {
|
||||
return nil, ErrUnSupportedType
|
||||
}
|
||||
|
||||
sqlStr, args, err := convertSQLOrArgs(sqlorArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return session.exec(sqlStr, args...)
|
||||
}
|
||||
|
87
vendor/github.com/go-xorm/xorm/session_schema.go
generated
vendored
87
vendor/github.com/go-xorm/xorm/session_schema.go
generated
vendored
@ -6,9 +6,7 @@ package xorm
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
@ -34,8 +32,7 @@ func (session *Session) CreateTable(bean interface{}) error {
|
||||
}
|
||||
|
||||
func (session *Session) createTable(bean interface{}) error {
|
||||
v := rValue(bean)
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -54,8 +51,7 @@ func (session *Session) CreateIndexes(bean interface{}) error {
|
||||
}
|
||||
|
||||
func (session *Session) createIndexes(bean interface{}) error {
|
||||
v := rValue(bean)
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -78,8 +74,7 @@ func (session *Session) CreateUniques(bean interface{}) error {
|
||||
}
|
||||
|
||||
func (session *Session) createUniques(bean interface{}) error {
|
||||
v := rValue(bean)
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -103,8 +98,7 @@ func (session *Session) DropIndexes(bean interface{}) error {
|
||||
}
|
||||
|
||||
func (session *Session) dropIndexes(bean interface{}) error {
|
||||
v := rValue(bean)
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -128,11 +122,7 @@ func (session *Session) DropTable(beanOrTableName interface{}) error {
|
||||
}
|
||||
|
||||
func (session *Session) dropTable(beanOrTableName interface{}) error {
|
||||
tableName, err := session.engine.tableName(beanOrTableName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tableName := session.engine.TableName(beanOrTableName)
|
||||
var needDrop = true
|
||||
if !session.engine.dialect.SupportDropIfExists() {
|
||||
sqlStr, args := session.engine.dialect.TableCheckSql(tableName)
|
||||
@ -144,8 +134,8 @@ func (session *Session) dropTable(beanOrTableName interface{}) error {
|
||||
}
|
||||
|
||||
if needDrop {
|
||||
sqlStr := session.engine.Dialect().DropTableSql(tableName)
|
||||
_, err = session.exec(sqlStr)
|
||||
sqlStr := session.engine.Dialect().DropTableSql(session.engine.TableName(tableName, true))
|
||||
_, err := session.exec(sqlStr)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -157,10 +147,7 @@ func (session *Session) IsTableExist(beanOrTableName interface{}) (bool, error)
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
tableName, err := session.engine.tableName(beanOrTableName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
tableName := session.engine.TableName(beanOrTableName)
|
||||
|
||||
return session.isTableExist(tableName)
|
||||
}
|
||||
@ -173,24 +160,15 @@ func (session *Session) isTableExist(tableName string) (bool, error) {
|
||||
|
||||
// IsTableEmpty if table have any records
|
||||
func (session *Session) IsTableEmpty(bean interface{}) (bool, error) {
|
||||
v := rValue(bean)
|
||||
t := v.Type()
|
||||
|
||||
if t.Kind() == reflect.String {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
return session.isTableEmpty(bean.(string))
|
||||
} else if t.Kind() == reflect.Struct {
|
||||
rows, err := session.Count(bean)
|
||||
return rows == 0, err
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
return false, errors.New("bean should be a struct or struct's point")
|
||||
return session.isTableEmpty(session.engine.TableName(bean))
|
||||
}
|
||||
|
||||
func (session *Session) isTableEmpty(tableName string) (bool, error) {
|
||||
var total int64
|
||||
sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(tableName))
|
||||
sqlStr := fmt.Sprintf("select count(*) from %s", session.engine.Quote(session.engine.TableName(tableName, true)))
|
||||
err := session.queryRow(sqlStr).Scan(&total)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
@ -255,6 +233,12 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
session.autoResetStatement = false
|
||||
defer func() {
|
||||
session.autoResetStatement = true
|
||||
session.resetStatement()
|
||||
}()
|
||||
|
||||
var structTables []*core.Table
|
||||
|
||||
for _, bean := range beans {
|
||||
@ -264,7 +248,8 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
return err
|
||||
}
|
||||
structTables = append(structTables, table)
|
||||
var tbName = session.tbNameNoSchema(table)
|
||||
tbName := engine.TableName(bean)
|
||||
tbNameWithSchema := engine.TableName(tbName, true)
|
||||
|
||||
var oriTable *core.Table
|
||||
for _, tb := range tables {
|
||||
@ -309,32 +294,32 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
if engine.dialect.DBType() == core.MYSQL ||
|
||||
engine.dialect.DBType() == core.POSTGRES {
|
||||
engine.logger.Infof("Table %s column %s change type from %s to %s\n",
|
||||
tbName, col.Name, curType, expectedType)
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSql(table.Name, col))
|
||||
tbNameWithSchema, col.Name, curType, expectedType)
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col))
|
||||
} else {
|
||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n",
|
||||
tbName, col.Name, curType, expectedType)
|
||||
tbNameWithSchema, col.Name, curType, expectedType)
|
||||
}
|
||||
} else if strings.HasPrefix(curType, core.Varchar) && strings.HasPrefix(expectedType, core.Varchar) {
|
||||
if engine.dialect.DBType() == core.MYSQL {
|
||||
if oriCol.Length < col.Length {
|
||||
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n",
|
||||
tbName, col.Name, oriCol.Length, col.Length)
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSql(table.Name, col))
|
||||
tbNameWithSchema, col.Name, oriCol.Length, col.Length)
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') {
|
||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s",
|
||||
tbName, col.Name, curType, expectedType)
|
||||
tbNameWithSchema, col.Name, curType, expectedType)
|
||||
}
|
||||
}
|
||||
} else if expectedType == core.Varchar {
|
||||
if engine.dialect.DBType() == core.MYSQL {
|
||||
if oriCol.Length < col.Length {
|
||||
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n",
|
||||
tbName, col.Name, oriCol.Length, col.Length)
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSql(table.Name, col))
|
||||
tbNameWithSchema, col.Name, oriCol.Length, col.Length)
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -348,7 +333,7 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
}
|
||||
} else {
|
||||
session.statement.RefTable = table
|
||||
session.statement.tableName = tbName
|
||||
session.statement.tableName = tbNameWithSchema
|
||||
err = session.addColumn(col.Name)
|
||||
}
|
||||
if err != nil {
|
||||
@ -371,7 +356,7 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
|
||||
if oriIndex != nil {
|
||||
if oriIndex.Type != index.Type {
|
||||
sql := engine.dialect.DropIndexSql(tbName, oriIndex)
|
||||
sql := engine.dialect.DropIndexSql(tbNameWithSchema, oriIndex)
|
||||
_, err = session.exec(sql)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -387,7 +372,7 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
|
||||
for name2, index2 := range oriTable.Indexes {
|
||||
if _, ok := foundIndexNames[name2]; !ok {
|
||||
sql := engine.dialect.DropIndexSql(tbName, index2)
|
||||
sql := engine.dialect.DropIndexSql(tbNameWithSchema, index2)
|
||||
_, err = session.exec(sql)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -398,12 +383,12 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
for name, index := range addedNames {
|
||||
if index.Type == core.UniqueType {
|
||||
session.statement.RefTable = table
|
||||
session.statement.tableName = tbName
|
||||
err = session.addUnique(tbName, name)
|
||||
session.statement.tableName = tbNameWithSchema
|
||||
err = session.addUnique(tbNameWithSchema, name)
|
||||
} else if index.Type == core.IndexType {
|
||||
session.statement.RefTable = table
|
||||
session.statement.tableName = tbName
|
||||
err = session.addIndex(tbName, name)
|
||||
session.statement.tableName = tbNameWithSchema
|
||||
err = session.addIndex(tbNameWithSchema, name)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -428,7 +413,7 @@ func (session *Session) Sync2(beans ...interface{}) error {
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
if oriTable.GetColumn(colName) == nil {
|
||||
engine.logger.Warnf("Table %s has column %s but struct has not related field", table.Name, colName)
|
||||
engine.logger.Warnf("Table %s has column %s but struct has not related field", engine.TableName(table.Name, true), colName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
vendor/github.com/go-xorm/xorm/session_tx.go
generated
vendored
2
vendor/github.com/go-xorm/xorm/session_tx.go
generated
vendored
@ -24,6 +24,7 @@ func (session *Session) Rollback() error {
|
||||
if !session.isAutoCommit && !session.isCommitedOrRollbacked {
|
||||
session.saveLastSQL(session.engine.dialect.RollBackStr())
|
||||
session.isCommitedOrRollbacked = true
|
||||
session.isAutoCommit = true
|
||||
return session.tx.Rollback()
|
||||
}
|
||||
return nil
|
||||
@ -34,6 +35,7 @@ func (session *Session) Commit() error {
|
||||
if !session.isAutoCommit && !session.isCommitedOrRollbacked {
|
||||
session.saveLastSQL("COMMIT")
|
||||
session.isCommitedOrRollbacked = true
|
||||
session.isAutoCommit = true
|
||||
var err error
|
||||
if err = session.tx.Commit(); err == nil {
|
||||
// handle processors after tx committed
|
||||
|
115
vendor/github.com/go-xorm/xorm/session_update.go
generated
vendored
115
vendor/github.com/go-xorm/xorm/session_update.go
generated
vendored
@ -40,7 +40,7 @@ func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string,
|
||||
}
|
||||
}
|
||||
|
||||
cacher := session.engine.getCacher2(table)
|
||||
cacher := session.engine.getCacher(tableName)
|
||||
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
|
||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:])
|
||||
if err != nil {
|
||||
@ -167,7 +167,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||
var isMap = t.Kind() == reflect.Map
|
||||
var isStruct = t.Kind() == reflect.Struct
|
||||
if isStruct {
|
||||
if err := session.statement.setRefValue(v); err != nil {
|
||||
if err := session.statement.setRefBean(bean); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@ -176,12 +176,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||
}
|
||||
|
||||
if session.statement.ColumnStr == "" {
|
||||
colNames, args = buildUpdates(session.engine, session.statement.RefTable, bean, false, false,
|
||||
false, false, session.statement.allUseBool, session.statement.useAllCols,
|
||||
session.statement.mustColumnMap, session.statement.nullableMap,
|
||||
session.statement.columnMap, true, session.statement.unscoped)
|
||||
colNames, args = session.statement.buildUpdates(bean, false, false,
|
||||
false, false, true)
|
||||
} else {
|
||||
colNames, args, err = genCols(session.statement.RefTable, session, bean, true, true)
|
||||
colNames, args, err = session.genUpdateColumns(bean)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -202,7 +200,8 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||
table := session.statement.RefTable
|
||||
|
||||
if session.statement.UseAutoTime && table != nil && table.Updated != "" {
|
||||
if _, ok := session.statement.columnMap[strings.ToLower(table.Updated)]; !ok {
|
||||
if !session.statement.columnMap.contain(table.Updated) &&
|
||||
!session.statement.omitColumnMap.contain(table.Updated) {
|
||||
colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?")
|
||||
col := table.UpdatedColumn()
|
||||
val, t := session.engine.nowTime(col)
|
||||
@ -362,12 +361,11 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||
}
|
||||
}
|
||||
|
||||
if table != nil {
|
||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||
//session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||
cacher.ClearIds(tableName)
|
||||
cacher.ClearBeans(tableName)
|
||||
}
|
||||
if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache {
|
||||
//session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||
session.engine.logger.Debug("[cacheUpdate] clear table ", tableName)
|
||||
cacher.ClearIds(tableName)
|
||||
cacher.ClearBeans(tableName)
|
||||
}
|
||||
|
||||
// handle after update processors
|
||||
@ -402,3 +400,92 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||
|
||||
return res.RowsAffected()
|
||||
}
|
||||
|
||||
func (session *Session) genUpdateColumns(bean interface{}) ([]string, []interface{}, error) {
|
||||
table := session.statement.RefTable
|
||||
colNames := make([]string, 0, len(table.ColumnsSeq()))
|
||||
args := make([]interface{}, 0, len(table.ColumnsSeq()))
|
||||
|
||||
for _, col := range table.Columns() {
|
||||
if !col.IsVersion && !col.IsCreated && !col.IsUpdated {
|
||||
if session.statement.omitColumnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if col.MapType == core.ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fieldValue := *fieldValuePtr
|
||||
|
||||
if col.IsAutoIncrement {
|
||||
switch fieldValue.Type().Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
|
||||
if fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
|
||||
if fieldValue.Uint() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.String:
|
||||
if len(fieldValue.String()) == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if fieldValue.Pointer() == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (col.IsDeleted && !session.statement.unscoped) || col.IsCreated {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(session.statement.columnMap) > 0 {
|
||||
if !session.statement.columnMap.contain(col.Name) {
|
||||
continue
|
||||
} else if _, ok := session.statement.incrColumns[col.Name]; ok {
|
||||
continue
|
||||
} else if _, ok := session.statement.decrColumns[col.Name]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok {
|
||||
if col.Nullable && isZero(fieldValue.Interface()) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
}
|
||||
|
||||
if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||
// if time is non-empty, then set to auto time
|
||||
val, t := session.engine.nowTime(col)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
session.afterClosures = append(session.afterClosures, func(bean interface{}) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.statement.checkVersion {
|
||||
args = append(args, 1)
|
||||
} else {
|
||||
arg, err := session.value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return colNames, args, err
|
||||
}
|
||||
args = append(args, arg)
|
||||
}
|
||||
|
||||
colNames = append(colNames, session.engine.Quote(col.Name)+" = ?")
|
||||
}
|
||||
return colNames, args, nil
|
||||
}
|
||||
|
286
vendor/github.com/go-xorm/xorm/statement.go
generated
vendored
286
vendor/github.com/go-xorm/xorm/statement.go
generated
vendored
@ -5,7 +5,6 @@
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@ -18,21 +17,6 @@ import (
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type incrParam struct {
|
||||
colName string
|
||||
arg interface{}
|
||||
}
|
||||
|
||||
type decrParam struct {
|
||||
colName string
|
||||
arg interface{}
|
||||
}
|
||||
|
||||
type exprParam struct {
|
||||
colName string
|
||||
expr string
|
||||
}
|
||||
|
||||
// Statement save all the sql info for executing SQL
|
||||
type Statement struct {
|
||||
RefTable *core.Table
|
||||
@ -47,7 +31,6 @@ type Statement struct {
|
||||
HavingStr string
|
||||
ColumnStr string
|
||||
selectStr string
|
||||
columnMap map[string]bool
|
||||
useAllCols bool
|
||||
OmitStr string
|
||||
AltTableName string
|
||||
@ -67,6 +50,8 @@ type Statement struct {
|
||||
allUseBool bool
|
||||
checkVersion bool
|
||||
unscoped bool
|
||||
columnMap columnMap
|
||||
omitColumnMap columnMap
|
||||
mustColumnMap map[string]bool
|
||||
nullableMap map[string]bool
|
||||
incrColumns map[string]incrParam
|
||||
@ -74,6 +59,7 @@ type Statement struct {
|
||||
exprColumns map[string]exprParam
|
||||
cond builder.Cond
|
||||
bufferSize int
|
||||
context ContextCache
|
||||
}
|
||||
|
||||
// Init reset all the statement's fields
|
||||
@ -89,7 +75,8 @@ func (statement *Statement) Init() {
|
||||
statement.HavingStr = ""
|
||||
statement.ColumnStr = ""
|
||||
statement.OmitStr = ""
|
||||
statement.columnMap = make(map[string]bool)
|
||||
statement.columnMap = columnMap{}
|
||||
statement.omitColumnMap = columnMap{}
|
||||
statement.AltTableName = ""
|
||||
statement.tableName = ""
|
||||
statement.idParam = nil
|
||||
@ -113,6 +100,7 @@ func (statement *Statement) Init() {
|
||||
statement.exprColumns = make(map[string]exprParam)
|
||||
statement.cond = builder.NewCond()
|
||||
statement.bufferSize = 0
|
||||
statement.context = nil
|
||||
}
|
||||
|
||||
// NoAutoCondition if you do not want convert bean's field as query condition, then use this function
|
||||
@ -221,34 +209,33 @@ func (statement *Statement) setRefValue(v reflect.Value) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
statement.tableName = statement.Engine.tbName(v)
|
||||
statement.tableName = statement.Engine.TableName(v, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Table tempororily set table name, the parameter could be a string or a pointer of struct
|
||||
func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||
v := rValue(tableNameOrBean)
|
||||
t := v.Type()
|
||||
if t.Kind() == reflect.String {
|
||||
statement.AltTableName = tableNameOrBean.(string)
|
||||
} else if t.Kind() == reflect.Struct {
|
||||
var err error
|
||||
statement.RefTable, err = statement.Engine.autoMapType(v)
|
||||
if err != nil {
|
||||
statement.Engine.logger.Error(err)
|
||||
return statement
|
||||
}
|
||||
statement.AltTableName = statement.Engine.tbName(v)
|
||||
func (statement *Statement) setRefBean(bean interface{}) error {
|
||||
var err error
|
||||
statement.RefTable, err = statement.Engine.autoMapType(rValue(bean))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return statement
|
||||
statement.tableName = statement.Engine.TableName(bean, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Auto generating update columnes and values according a struct
|
||||
func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
includeVersion bool, includeUpdated bool, includeNil bool,
|
||||
includeAutoIncr bool, allUseBool bool, useAllCols bool,
|
||||
mustColumnMap map[string]bool, nullableMap map[string]bool,
|
||||
columnMap map[string]bool, update, unscoped bool) ([]string, []interface{}) {
|
||||
func (statement *Statement) buildUpdates(bean interface{},
|
||||
includeVersion, includeUpdated, includeNil,
|
||||
includeAutoIncr, update bool) ([]string, []interface{}) {
|
||||
engine := statement.Engine
|
||||
table := statement.RefTable
|
||||
allUseBool := statement.allUseBool
|
||||
useAllCols := statement.useAllCols
|
||||
mustColumnMap := statement.mustColumnMap
|
||||
nullableMap := statement.nullableMap
|
||||
columnMap := statement.columnMap
|
||||
omitColumnMap := statement.omitColumnMap
|
||||
unscoped := statement.unscoped
|
||||
|
||||
var colNames = make([]string, 0)
|
||||
var args = make([]interface{}, 0)
|
||||
@ -268,7 +255,14 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
if col.IsDeleted && !unscoped {
|
||||
continue
|
||||
}
|
||||
if use, ok := columnMap[strings.ToLower(col.Name)]; ok && !use {
|
||||
if omitColumnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
if len(columnMap) > 0 && !columnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if col.MapType == core.ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -604,17 +598,10 @@ func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
|
||||
}
|
||||
|
||||
func (statement *Statement) colmap2NewColsWithQuote() []string {
|
||||
newColumns := make([]string, 0, len(statement.columnMap))
|
||||
for col := range statement.columnMap {
|
||||
fields := strings.Split(strings.TrimSpace(col), ".")
|
||||
if len(fields) == 1 {
|
||||
newColumns = append(newColumns, statement.Engine.quote(fields[0]))
|
||||
} else if len(fields) == 2 {
|
||||
newColumns = append(newColumns, statement.Engine.quote(fields[0])+"."+
|
||||
statement.Engine.quote(fields[1]))
|
||||
} else {
|
||||
panic(errors.New("unwanted colnames"))
|
||||
}
|
||||
newColumns := make([]string, len(statement.columnMap), len(statement.columnMap))
|
||||
copy(newColumns, statement.columnMap)
|
||||
for i := 0; i < len(statement.columnMap); i++ {
|
||||
newColumns[i] = statement.Engine.Quote(newColumns[i])
|
||||
}
|
||||
return newColumns
|
||||
}
|
||||
@ -642,10 +629,11 @@ func (statement *Statement) Select(str string) *Statement {
|
||||
func (statement *Statement) Cols(columns ...string) *Statement {
|
||||
cols := col2NewCols(columns...)
|
||||
for _, nc := range cols {
|
||||
statement.columnMap[strings.ToLower(nc)] = true
|
||||
statement.columnMap.add(nc)
|
||||
}
|
||||
|
||||
newColumns := statement.colmap2NewColsWithQuote()
|
||||
|
||||
statement.ColumnStr = strings.Join(newColumns, ", ")
|
||||
statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.quote("*"), "*", -1)
|
||||
return statement
|
||||
@ -680,7 +668,7 @@ func (statement *Statement) UseBool(columns ...string) *Statement {
|
||||
func (statement *Statement) Omit(columns ...string) {
|
||||
newColumns := col2NewCols(columns...)
|
||||
for _, nc := range newColumns {
|
||||
statement.columnMap[strings.ToLower(nc)] = false
|
||||
statement.omitColumnMap = append(statement.omitColumnMap, nc)
|
||||
}
|
||||
statement.OmitStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", ")))
|
||||
}
|
||||
@ -719,10 +707,9 @@ func (statement *Statement) OrderBy(order string) *Statement {
|
||||
|
||||
// Desc generate `ORDER BY xx DESC`
|
||||
func (statement *Statement) Desc(colNames ...string) *Statement {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, statement.OrderStr)
|
||||
var buf builder.StringBuilder
|
||||
if len(statement.OrderStr) > 0 {
|
||||
fmt.Fprint(&buf, ", ")
|
||||
fmt.Fprint(&buf, statement.OrderStr, ", ")
|
||||
}
|
||||
newColNames := statement.col2NewColsWithQuote(colNames...)
|
||||
fmt.Fprintf(&buf, "%v DESC", strings.Join(newColNames, " DESC, "))
|
||||
@ -732,10 +719,9 @@ func (statement *Statement) Desc(colNames ...string) *Statement {
|
||||
|
||||
// Asc provide asc order by query condition, the input parameters are columns.
|
||||
func (statement *Statement) Asc(colNames ...string) *Statement {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, statement.OrderStr)
|
||||
var buf builder.StringBuilder
|
||||
if len(statement.OrderStr) > 0 {
|
||||
fmt.Fprint(&buf, ", ")
|
||||
fmt.Fprint(&buf, statement.OrderStr, ", ")
|
||||
}
|
||||
newColNames := statement.col2NewColsWithQuote(colNames...)
|
||||
fmt.Fprintf(&buf, "%v ASC", strings.Join(newColNames, " ASC, "))
|
||||
@ -743,48 +729,35 @@ func (statement *Statement) Asc(colNames ...string) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
// Table tempororily set table name, the parameter could be a string or a pointer of struct
|
||||
func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||
v := rValue(tableNameOrBean)
|
||||
t := v.Type()
|
||||
if t.Kind() == reflect.Struct {
|
||||
var err error
|
||||
statement.RefTable, err = statement.Engine.autoMapType(v)
|
||||
if err != nil {
|
||||
statement.Engine.logger.Error(err)
|
||||
return statement
|
||||
}
|
||||
}
|
||||
|
||||
statement.AltTableName = statement.Engine.TableName(tableNameOrBean, true)
|
||||
return statement
|
||||
}
|
||||
|
||||
// Join The joinOP should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
|
||||
func (statement *Statement) Join(joinOP string, tablename interface{}, condition string, args ...interface{}) *Statement {
|
||||
var buf bytes.Buffer
|
||||
var buf builder.StringBuilder
|
||||
if len(statement.JoinStr) > 0 {
|
||||
fmt.Fprintf(&buf, "%v %v JOIN ", statement.JoinStr, joinOP)
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "%v JOIN ", joinOP)
|
||||
}
|
||||
|
||||
switch tablename.(type) {
|
||||
case []string:
|
||||
t := tablename.([]string)
|
||||
if len(t) > 1 {
|
||||
fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(t[0]), statement.Engine.Quote(t[1]))
|
||||
} else if len(t) == 1 {
|
||||
fmt.Fprintf(&buf, statement.Engine.Quote(t[0]))
|
||||
}
|
||||
case []interface{}:
|
||||
t := tablename.([]interface{})
|
||||
l := len(t)
|
||||
var table string
|
||||
if l > 0 {
|
||||
f := t[0]
|
||||
v := rValue(f)
|
||||
t := v.Type()
|
||||
if t.Kind() == reflect.String {
|
||||
table = f.(string)
|
||||
} else if t.Kind() == reflect.Struct {
|
||||
table = statement.Engine.tbName(v)
|
||||
}
|
||||
}
|
||||
if l > 1 {
|
||||
fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(table),
|
||||
statement.Engine.Quote(fmt.Sprintf("%v", t[1])))
|
||||
} else if l == 1 {
|
||||
fmt.Fprintf(&buf, statement.Engine.Quote(table))
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(&buf, statement.Engine.Quote(fmt.Sprintf("%v", tablename)))
|
||||
}
|
||||
tbName := statement.Engine.TableName(tablename, true)
|
||||
|
||||
fmt.Fprintf(&buf, " ON %v", condition)
|
||||
fmt.Fprintf(&buf, "%s ON %v", tbName, condition)
|
||||
statement.JoinStr = buf.String()
|
||||
statement.joinArgs = append(statement.joinArgs, args...)
|
||||
return statement
|
||||
@ -809,18 +782,20 @@ func (statement *Statement) Unscoped() *Statement {
|
||||
}
|
||||
|
||||
func (statement *Statement) genColumnStr() string {
|
||||
var buf bytes.Buffer
|
||||
if statement.RefTable == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var buf builder.StringBuilder
|
||||
columns := statement.RefTable.Columns()
|
||||
|
||||
for _, col := range columns {
|
||||
if statement.OmitStr != "" {
|
||||
if _, ok := getFlagForColumn(statement.columnMap, col); ok {
|
||||
continue
|
||||
}
|
||||
if statement.omitColumnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(statement.columnMap) > 0 && !statement.columnMap.contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if col.MapType == core.ONLYTODB {
|
||||
@ -831,10 +806,6 @@ func (statement *Statement) genColumnStr() string {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
|
||||
if col.IsPrimaryKey && statement.Engine.Dialect().DBType() == "ql" {
|
||||
buf.WriteString("id() AS ")
|
||||
}
|
||||
|
||||
if statement.JoinStr != "" {
|
||||
if statement.TableAlias != "" {
|
||||
buf.WriteString(statement.TableAlias)
|
||||
@ -859,11 +830,13 @@ func (statement *Statement) genCreateTableSQL() string {
|
||||
func (statement *Statement) genIndexSQL() []string {
|
||||
var sqls []string
|
||||
tbName := statement.TableName()
|
||||
quote := statement.Engine.Quote
|
||||
for idxName, index := range statement.RefTable.Indexes {
|
||||
for _, index := range statement.RefTable.Indexes {
|
||||
if index.Type == core.IndexType {
|
||||
sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(tbName, idxName)),
|
||||
quote(tbName), quote(strings.Join(index.Cols, quote(","))))
|
||||
sql := statement.Engine.dialect.CreateIndexSql(tbName, index)
|
||||
/*idxTBName := strings.Replace(tbName, ".", "_", -1)
|
||||
idxTBName = strings.Replace(idxTBName, `"`, "", -1)
|
||||
sql := fmt.Sprintf("CREATE INDEX %v ON %v (%v);", quote(indexName(idxTBName, idxName)),
|
||||
quote(tbName), quote(strings.Join(index.Cols, quote(","))))*/
|
||||
sqls = append(sqls, sql)
|
||||
}
|
||||
}
|
||||
@ -889,16 +862,18 @@ func (statement *Statement) genUniqueSQL() []string {
|
||||
func (statement *Statement) genDelIndexSQL() []string {
|
||||
var sqls []string
|
||||
tbName := statement.TableName()
|
||||
idxPrefixName := strings.Replace(tbName, `"`, "", -1)
|
||||
idxPrefixName = strings.Replace(idxPrefixName, `.`, "_", -1)
|
||||
for idxName, index := range statement.RefTable.Indexes {
|
||||
var rIdxName string
|
||||
if index.Type == core.UniqueType {
|
||||
rIdxName = uniqueName(tbName, idxName)
|
||||
rIdxName = uniqueName(idxPrefixName, idxName)
|
||||
} else if index.Type == core.IndexType {
|
||||
rIdxName = indexName(tbName, idxName)
|
||||
rIdxName = indexName(idxPrefixName, idxName)
|
||||
}
|
||||
sql := fmt.Sprintf("DROP INDEX %v", statement.Engine.Quote(rIdxName))
|
||||
sql := fmt.Sprintf("DROP INDEX %v", statement.Engine.Quote(statement.Engine.TableName(rIdxName, true)))
|
||||
if statement.Engine.dialect.IndexOnTable() {
|
||||
sql += fmt.Sprintf(" ON %v", statement.Engine.Quote(statement.TableName()))
|
||||
sql += fmt.Sprintf(" ON %v", statement.Engine.Quote(tbName))
|
||||
}
|
||||
sqls = append(sqls, sql)
|
||||
}
|
||||
@ -949,7 +924,7 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
||||
v := rValue(bean)
|
||||
isStruct := v.Kind() == reflect.Struct
|
||||
if isStruct {
|
||||
statement.setRefValue(v)
|
||||
statement.setRefBean(bean)
|
||||
}
|
||||
|
||||
var columnStr = statement.ColumnStr
|
||||
@ -960,7 +935,7 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
||||
if len(statement.JoinStr) == 0 {
|
||||
if len(columnStr) == 0 {
|
||||
if len(statement.GroupByStr) > 0 {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
columnStr = statement.Engine.quoteColumns(statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = statement.genColumnStr()
|
||||
}
|
||||
@ -968,7 +943,7 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
||||
} else {
|
||||
if len(columnStr) == 0 {
|
||||
if len(statement.GroupByStr) > 0 {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
columnStr = statement.Engine.quoteColumns(statement.GroupByStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -982,13 +957,17 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
||||
if err := statement.mergeConds(bean); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
} else {
|
||||
if err := statement.processIDParam(); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
condSQL, condArgs, err := builder.ToSQL(statement.cond)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
sqlStr, err := statement.genSelectSQL(columnStr, condSQL)
|
||||
sqlStr, err := statement.genSelectSQL(columnStr, condSQL, true, true)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
@ -1001,7 +980,7 @@ func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interfa
|
||||
var condArgs []interface{}
|
||||
var err error
|
||||
if len(beans) > 0 {
|
||||
statement.setRefValue(rValue(beans[0]))
|
||||
statement.setRefBean(beans[0])
|
||||
condSQL, condArgs, err = statement.genConds(beans[0])
|
||||
} else {
|
||||
condSQL, condArgs, err = builder.ToSQL(statement.cond)
|
||||
@ -1018,7 +997,7 @@ func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interfa
|
||||
selectSQL = "count(*)"
|
||||
}
|
||||
}
|
||||
sqlStr, err := statement.genSelectSQL(selectSQL, condSQL)
|
||||
sqlStr, err := statement.genSelectSQL(selectSQL, condSQL, false, false)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
@ -1027,7 +1006,7 @@ func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interfa
|
||||
}
|
||||
|
||||
func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (string, []interface{}, error) {
|
||||
statement.setRefValue(rValue(bean))
|
||||
statement.setRefBean(bean)
|
||||
|
||||
var sumStrs = make([]string, 0, len(columns))
|
||||
for _, colName := range columns {
|
||||
@ -1043,7 +1022,7 @@ func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (stri
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
sqlStr, err := statement.genSelectSQL(sumSelect, condSQL)
|
||||
sqlStr, err := statement.genSelectSQL(sumSelect, condSQL, true, true)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
@ -1051,27 +1030,20 @@ func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (stri
|
||||
return sqlStr, append(statement.joinArgs, condArgs...), nil
|
||||
}
|
||||
|
||||
func (statement *Statement) genSelectSQL(columnStr, condSQL string) (a string, err error) {
|
||||
var distinct string
|
||||
func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit, needOrderBy bool) (string, error) {
|
||||
var (
|
||||
distinct string
|
||||
dialect = statement.Engine.Dialect()
|
||||
quote = statement.Engine.Quote
|
||||
fromStr = " FROM "
|
||||
top, mssqlCondi, whereStr string
|
||||
)
|
||||
if statement.IsDistinct && !strings.HasPrefix(columnStr, "count") {
|
||||
distinct = "DISTINCT "
|
||||
}
|
||||
|
||||
var dialect = statement.Engine.Dialect()
|
||||
var quote = statement.Engine.Quote
|
||||
var top string
|
||||
var mssqlCondi string
|
||||
|
||||
if err := statement.processIDParam(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if len(condSQL) > 0 {
|
||||
fmt.Fprintf(&buf, " WHERE %v", condSQL)
|
||||
whereStr = " WHERE " + condSQL
|
||||
}
|
||||
var whereStr = buf.String()
|
||||
var fromStr = " FROM "
|
||||
|
||||
if dialect.DBType() == core.MSSQL && strings.Contains(statement.TableName(), "..") {
|
||||
fromStr += statement.TableName()
|
||||
@ -1118,9 +1090,10 @@ func (statement *Statement) genSelectSQL(columnStr, condSQL string) (a string, e
|
||||
}
|
||||
|
||||
var orderStr string
|
||||
if len(statement.OrderStr) > 0 {
|
||||
if needOrderBy && len(statement.OrderStr) > 0 {
|
||||
orderStr = " ORDER BY " + statement.OrderStr
|
||||
}
|
||||
|
||||
var groupStr string
|
||||
if len(statement.GroupByStr) > 0 {
|
||||
groupStr = " GROUP BY " + statement.GroupByStr
|
||||
@ -1130,45 +1103,50 @@ func (statement *Statement) genSelectSQL(columnStr, condSQL string) (a string, e
|
||||
}
|
||||
}
|
||||
|
||||
// !nashtsai! REVIEW Sprintf is considered slowest mean of string concatnation, better to work with builder pattern
|
||||
a = fmt.Sprintf("SELECT %v%v%v%v%v", distinct, top, columnStr, fromStr, whereStr)
|
||||
var buf builder.StringBuilder
|
||||
fmt.Fprintf(&buf, "SELECT %v%v%v%v%v", distinct, top, columnStr, fromStr, whereStr)
|
||||
if len(mssqlCondi) > 0 {
|
||||
if len(whereStr) > 0 {
|
||||
a += " AND " + mssqlCondi
|
||||
fmt.Fprint(&buf, " AND ", mssqlCondi)
|
||||
} else {
|
||||
a += " WHERE " + mssqlCondi
|
||||
fmt.Fprint(&buf, " WHERE ", mssqlCondi)
|
||||
}
|
||||
}
|
||||
|
||||
if statement.GroupByStr != "" {
|
||||
a = fmt.Sprintf("%v GROUP BY %v", a, statement.GroupByStr)
|
||||
fmt.Fprint(&buf, " GROUP BY ", statement.GroupByStr)
|
||||
}
|
||||
if statement.HavingStr != "" {
|
||||
a = fmt.Sprintf("%v %v", a, statement.HavingStr)
|
||||
fmt.Fprint(&buf, " ", statement.HavingStr)
|
||||
}
|
||||
if statement.OrderStr != "" {
|
||||
a = fmt.Sprintf("%v ORDER BY %v", a, statement.OrderStr)
|
||||
if needOrderBy && statement.OrderStr != "" {
|
||||
fmt.Fprint(&buf, " ORDER BY ", statement.OrderStr)
|
||||
}
|
||||
if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE {
|
||||
if statement.Start > 0 {
|
||||
a = fmt.Sprintf("%v LIMIT %v OFFSET %v", a, statement.LimitN, statement.Start)
|
||||
} else if statement.LimitN > 0 {
|
||||
a = fmt.Sprintf("%v LIMIT %v", a, statement.LimitN)
|
||||
}
|
||||
} else if dialect.DBType() == core.ORACLE {
|
||||
if statement.Start != 0 || statement.LimitN != 0 {
|
||||
a = fmt.Sprintf("SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", columnStr, columnStr, a, statement.Start+statement.LimitN, statement.Start)
|
||||
if needLimit {
|
||||
if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE {
|
||||
if statement.Start > 0 {
|
||||
fmt.Fprintf(&buf, " LIMIT %v OFFSET %v", statement.LimitN, statement.Start)
|
||||
} else if statement.LimitN > 0 {
|
||||
fmt.Fprint(&buf, " LIMIT ", statement.LimitN)
|
||||
}
|
||||
} else if dialect.DBType() == core.ORACLE {
|
||||
if statement.Start != 0 || statement.LimitN != 0 {
|
||||
oldString := buf.String()
|
||||
buf.Reset()
|
||||
fmt.Fprintf(&buf, "SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d",
|
||||
columnStr, columnStr, oldString, statement.Start+statement.LimitN, statement.Start)
|
||||
}
|
||||
}
|
||||
}
|
||||
if statement.IsForUpdate {
|
||||
a = dialect.ForUpdateSql(a)
|
||||
return dialect.ForUpdateSql(buf.String()), nil
|
||||
}
|
||||
|
||||
return
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
func (statement *Statement) processIDParam() error {
|
||||
if statement.idParam == nil {
|
||||
if statement.idParam == nil || statement.RefTable == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
26
vendor/github.com/go-xorm/xorm/transaction.go
generated
vendored
Normal file
26
vendor/github.com/go-xorm/xorm/transaction.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
// Transaction Execute sql wrapped in a transaction(abbr as tx), tx will automatic commit if no errors occurred
|
||||
func (engine *Engine) Transaction(f func(*Session) (interface{}, error)) (interface{}, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
|
||||
if err := session.Begin(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := f(session)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := session.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
14
vendor/github.com/go-xorm/xorm/xorm.go
generated
vendored
14
vendor/github.com/go-xorm/xorm/xorm.go
generated
vendored
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -17,7 +19,7 @@ import (
|
||||
|
||||
const (
|
||||
// Version show the xorm's version
|
||||
Version string = "0.6.4.0910"
|
||||
Version string = "0.7.0.0504"
|
||||
)
|
||||
|
||||
func regDrvsNDialects() bool {
|
||||
@ -31,7 +33,7 @@ func regDrvsNDialects() bool {
|
||||
"mysql": {"mysql", func() core.Driver { return &mysqlDriver{} }, func() core.Dialect { return &mysql{} }},
|
||||
"mymysql": {"mysql", func() core.Driver { return &mymysqlDriver{} }, func() core.Dialect { return &mysql{} }},
|
||||
"postgres": {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }},
|
||||
"pgx": {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }},
|
||||
"pgx": {"postgres", func() core.Driver { return &pqDriverPgx{} }, func() core.Dialect { return &postgres{} }},
|
||||
"sqlite3": {"sqlite3", func() core.Driver { return &sqlite3Driver{} }, func() core.Dialect { return &sqlite3{} }},
|
||||
"oci8": {"oracle", func() core.Driver { return &oci8Driver{} }, func() core.Dialect { return &oracle{} }},
|
||||
"goracle": {"oracle", func() core.Driver { return &goracleDriver{} }, func() core.Dialect { return &oracle{} }},
|
||||
@ -90,6 +92,7 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
||||
TagIdentifier: "xorm",
|
||||
TZLocation: time.Local,
|
||||
tagHandlers: defaultTagHandlers,
|
||||
cachers: make(map[string]core.Cacher),
|
||||
}
|
||||
|
||||
if uri.DbType == core.SQLITE {
|
||||
@ -108,6 +111,13 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
||||
return engine, nil
|
||||
}
|
||||
|
||||
// NewEngineWithParams new a db manager with params. The params will be passed to dialect.
|
||||
func NewEngineWithParams(driverName string, dataSourceName string, params map[string]string) (*Engine, error) {
|
||||
engine, err := NewEngine(driverName, dataSourceName)
|
||||
engine.dialect.SetParams(params)
|
||||
return engine, err
|
||||
}
|
||||
|
||||
// Clone clone an engine
|
||||
func (engine *Engine) Clone() (*Engine, error) {
|
||||
return NewEngine(engine.DriverName(), engine.DataSourceName())
|
||||
|
2
vendor/github.com/jmespath/go-jmespath/api.go
generated
vendored
2
vendor/github.com/jmespath/go-jmespath/api.go
generated
vendored
@ -2,7 +2,7 @@ package jmespath
|
||||
|
||||
import "strconv"
|
||||
|
||||
// JmesPath is the epresentation of a compiled JMES path query. A JmesPath is
|
||||
// JMESPath is the epresentation of a compiled JMES path query. A JMESPath is
|
||||
// safe for concurrent use by multiple goroutines.
|
||||
type JMESPath struct {
|
||||
ast ASTNode
|
||||
|
Loading…
Reference in New Issue
Block a user