testing with local cockroach started for tests and migrations

This commit is contained in:
adlerhurst 2020-10-02 16:21:51 +02:00
parent 169b1787df
commit eb51a429ff
33 changed files with 1277 additions and 1185 deletions

View File

@ -11,7 +11,7 @@ docker run -d \
--hostname=zitadel-db \
-p 26257:26257 -p 8080:8080 \
-v "${GOPATH}/src/github.com/caos/zitadel/cockroach-data/zitadel1:/cockroach/cockroach-data" \
cockroachdb/cockroach:latest start --insecure
cockroachdb/cockroach:20.1.6 start-single-node --insecure
```
### local database migrations

17
go.mod
View File

@ -12,23 +12,24 @@ require (
github.com/VictoriaMetrics/fastcache v1.5.7
github.com/ajstarks/svgo v0.0.0-20200725142600-7a3c8b57fecb
github.com/allegro/bigcache v1.2.1
github.com/aws/aws-sdk-go v1.34.24 // indirect
github.com/aws/aws-sdk-go v1.35.0 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc
github.com/caos/logging v0.0.2
github.com/caos/oidc v0.10.0
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
github.com/cockroachdb/cockroach-go/v2 v2.0.7
github.com/cockroachdb/cockroach-go/v2 v2.0.8
github.com/envoyproxy/protoc-gen-validate v0.4.1
github.com/ghodss/yaml v1.0.0
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/mock v1.4.4
github.com/golang/protobuf v1.4.2
github.com/golang/snappy v0.0.2 // indirect
github.com/gorilla/csrf v1.7.0
github.com/gorilla/mux v1.8.0
github.com/gorilla/schema v1.2.0
github.com/gorilla/securecookie v1.1.1
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
github.com/grpc-ecosystem/grpc-gateway v1.14.8
github.com/grpc-ecosystem/grpc-gateway v1.15.0
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/inconshreveable/log15 v0.0.0-20200109203555-b30bc20e4fd1 // indirect
@ -37,12 +38,13 @@ require (
github.com/kevinburke/go.uuid v1.2.0 // indirect
github.com/kevinburke/rest v0.0.0-20200429221318-0d2892b400f8 // indirect
github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.8.0
github.com/mattn/go-colorable v0.1.7 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.1 // indirect
github.com/nicksnyder/go-i18n/v2 v2.0.3
github.com/nicksnyder/go-i18n/v2 v2.1.1
github.com/pquerna/otp v1.2.0
github.com/rakyll/statik v0.1.7
github.com/rs/cors v1.7.0
@ -51,10 +53,11 @@ require (
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
github.com/ttacon/libphonenumber v1.1.0
go.opencensus.io v0.22.4
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
golang.org/x/text v0.3.3
golang.org/x/tools v0.0.0-20200916140129-56d9a0cd3487
google.golang.org/genproto v0.0.0-20200916143405-f6a2fa72f0c4
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c
google.golang.org/genproto v0.0.0-20200930140634-01fc692af84b
google.golang.org/grpc v1.32.0
google.golang.org/protobuf v1.25.0
gopkg.in/square/go-jose.v2 v2.5.1

67
go.sum
View File

@ -33,12 +33,12 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4 h1:ksUxwH3OD5sxkjzEqGxNTl+Xjsmu3BnC/300MhSVTSc=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@ -65,14 +65,12 @@ github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9Pq
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.34.24 h1:eTBgLksUJNLk5EwBl/lUweXjBZHbxvfcvqUxAJu7Fqg=
github.com/aws/aws-sdk-go v1.34.24/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.35.0 h1:Pxqn1MWNfBCNcX7jrXCCTfsKpg5ms2IMUMmmcGtYJuo=
github.com/aws/aws-sdk-go v1.35.0/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo=
github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0=
github.com/caos/oidc v0.9.1 h1:w/QccYOrEe6mkd/I2QKbCGwz8P+jnCpVF3+5FYQWMV4=
github.com/caos/oidc v0.9.1/go.mod h1:RREtWSRzH/mXQXJkxB63mFDZ/RUNyzoU6czd6UJfvJI=
github.com/caos/oidc v0.10.0 h1:/GKyQgKHvkc2jNCXzmdJs9hCXDYdArCMm3d5FXaiNWA=
github.com/caos/oidc v0.10.0/go.mod h1:RREtWSRzH/mXQXJkxB63mFDZ/RUNyzoU6czd6UJfvJI=
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
@ -87,12 +85,16 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cockroach-go/v2 v2.0.7 h1:Xkv9PbnvBrZjxRdW7l6GLz76bxAE/xaro+SGTyLz6gQ=
github.com/cockroachdb/cockroach-go/v2 v2.0.7/go.mod h1:nkf7rUmgPdawp3EwRjXIumihI2AYg9usGNWbJ2hsJqI=
github.com/cockroachdb/cockroach-go v2.0.1+incompatible h1:rkk9T7FViadPOz28xQ68o18jBSpyShru0mayVumxqYA=
github.com/cockroachdb/cockroach-go v2.0.1+incompatible/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
github.com/cockroachdb/cockroach-go/v2 v2.0.8 h1:50C/7ptrrfdxDccCjDU0xsdeBca+S0/AYW4Mo8RyzFE=
github.com/cockroachdb/cockroach-go/v2 v2.0.8/go.mod h1:nkf7rUmgPdawp3EwRjXIumihI2AYg9usGNWbJ2hsJqI=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -126,7 +128,9 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
@ -164,7 +168,10 @@ github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@ -181,7 +188,9 @@ github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -189,6 +198,7 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99 h1:Ak8CrdlwwXwAZxzS66vgPt4U8yUZX7JwLvVR58FN5jM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
@ -209,13 +219,14 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
github.com/grpc-ecosystem/grpc-gateway v1.14.8 h1:hXClj+iFpmLM8i3lkO6i4Psli4P2qObQuQReiII26U8=
github.com/grpc-ecosystem/grpc-gateway v1.14.8/go.mod h1:NZE8t6vs6TnwLL/ITkaK8W3ecMLGAbh2jXTclvpiwYo=
github.com/grpc-ecosystem/grpc-gateway v1.15.0 h1:ntPNC9TD/6l2XDenJZe6T5lSMg95thpV9sGAqHX4WU8=
github.com/grpc-ecosystem/grpc-gateway v1.15.0/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
@ -243,6 +254,7 @@ github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01C
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik=
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
@ -260,10 +272,13 @@ github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a h1:Z7+SSApKiwPjNic+NF9+j7h657Uyvdp/jA3iTKhpj4E=
github.com/kevinburke/go-types v0.0.0-20200309064045-f2d4aea18a7a/go.mod h1:/Pk5i/SqYdYv1cie5wGwoZ4P6TpgMi+Yf58mtJSHdOw=
@ -288,6 +303,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@ -317,10 +334,11 @@ github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/I
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/nicksnyder/go-i18n/v2 v2.0.3 h1:ks/JkQiOEhhuF6jpNvx+Wih1NIiXzUnZeZVnJuI8R8M=
github.com/nicksnyder/go-i18n/v2 v2.0.3/go.mod h1:oDab7q8XCYMRlcrBnaY/7B1eOectbvj6B1UPBT+p5jo=
github.com/nicksnyder/go-i18n/v2 v2.1.1 h1:ATCOanRDlrfKVB4WHAdJnLEqZtDmKYsweqsOUYflnBU=
github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -330,6 +348,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok=
github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
@ -343,6 +362,7 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea h1:jaXWVFZ98/ihXniiDzqNXQgMSgklX4kjfDWZTE3ZtdU=
github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
@ -389,7 +409,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -401,8 +420,8 @@ golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae h1:duLSQW+DZ5MsXKX7kc4rXlq6/mmxz4G6ewJuBPlhRe0=
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -535,6 +554,8 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zr
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -544,6 +565,7 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -594,8 +616,10 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200916140129-56d9a0cd3487 h1:jEXXH7h6Rp9Y9LIqQyAv86w5q9cU5lxqfllDwaYU228=
golang.org/x/tools v0.0.0-20200916140129-56d9a0cd3487/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20200930213115-e57f6d466a48 h1:/N7U6gDrclaaWCzrdxtKeyEcUx2goazt5PelznylQNM=
golang.org/x/tools v0.0.0-20200930213115-e57f6d466a48/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c h1:9BSeO6440XJVa2mxIcRAndAol4g4g2KflCVGcHx9Yu8=
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -670,8 +694,8 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200916143405-f6a2fa72f0c4 h1:0FQbRyP6f/LVRsofCaQD4BMMd5kRAXMo/WvispzB940=
google.golang.org/genproto v0.0.0-20200916143405-f6a2fa72f0c4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200930140634-01fc692af84b h1:GJQgk4o/yzqYEu9Y6V4gRCI54KRlkOE0xAZeEGUUJjw=
google.golang.org/genproto v0.0.0-20200930140634-01fc692af84b/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -689,7 +713,6 @@ google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@ -715,11 +738,11 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

View File

@ -87,20 +87,20 @@ func (es *Eventstore) aggregatesToEvents(aggregates []aggregater) ([]*repository
for _, aggregate := range aggregates {
var previousEvent *repository.Event
for _, event := range aggregate.Events() {
//TODO: map event.Data() into json
var data []byte
events = append(events, &repository.Event{
AggregateID: aggregate.ID(),
AggregateType: repository.AggregateType(aggregate.Type()),
ResourceOwner: aggregate.ResourceOwner(),
EditorService: event.EditorService(),
EditorUser: event.EditorUser(),
Type: repository.EventType(event.Type()),
Version: repository.Version(aggregate.Version()),
PreviousEvent: previousEvent,
Data: event.Data(),
AggregateID: aggregate.ID(),
AggregateType: repository.AggregateType(aggregate.Type()),
ResourceOwner: aggregate.ResourceOwner(),
EditorService: event.EditorService(),
EditorUser: event.EditorUser(),
Type: repository.EventType(event.Type()),
Version: repository.Version(aggregate.Version()),
PreviousEvent: previousEvent,
Data: data,
PreviousSequence: event.PreviousSequence(),
})
if previousEvent != nil && event.CheckPrevious() {
events[len(events)-1].PreviousSequence = event.PreviousSequence()
}
previousEvent = events[len(events)-1]
}
}

View File

@ -1,17 +0,0 @@
package repository
import (
"testing"
"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/server"
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
)
func TestBlub(t *testing.T) {
s, db, kvDB := serverutils.StartServer(t, base.TestServerArgs{})
defer s.Stopper().Stop()
// If really needed, in tests that can depend on server, downcast to
// server.TestServer:
ts := s.(*server.TestServer)
}

View File

@ -0,0 +1,227 @@
package repository
import (
"context"
"database/sql"
"errors"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/cockroachdb/cockroach-go/v2/crdb"
//sql import for cockroach
_ "github.com/lib/pq"
)
const (
crdbInsert = "WITH input_event ( " +
" event_type, " +
" aggregate_type, " +
" aggregate_id, " +
" aggregate_version, " +
" creation_date, " +
" event_data, " +
" editor_user, " +
" editor_service, " +
" resource_owner, " +
" previous_sequence, " +
" check_previous, " +
// variables below are calculated
" max_event_seq, " +
" event_count " +
") " +
" AS( " +
" SELECT " +
" $1::VARCHAR," +
" $2::VARCHAR," +
" $3::VARCHAR," +
" $4::VARCHAR," +
" COALESCE($5::TIMESTAMPTZ, NOW()), " +
" $6::JSONB, " +
" $7::VARCHAR, " +
" $8::VARCHAR, " +
" $9::VARCHAR, " +
" $10::BIGINT, " +
" $11::BOOLEAN," +
" MAX(event_sequence) AS max_event_seq, " +
" COUNT(*) AS event_count " +
" FROM eventstore.events " +
" WHERE " +
" aggregate_type = $2::VARCHAR " +
" AND aggregate_id = $3::VARCHAR " +
") " +
"INSERT INTO eventstore.events " +
" ( " +
" event_type, " +
" aggregate_type," +
" aggregate_id, " +
" aggregate_version, " +
" creation_date, " +
" event_data, " +
" editor_user, " +
" editor_service, " +
" resource_owner, " +
" previous_sequence " +
" ) " +
" ( " +
" SELECT " +
" event_type, " +
" aggregate_type," +
" aggregate_id, " +
" aggregate_version, " +
" COALESCE(creation_date, NOW()), " +
" event_data, " +
" editor_user, " +
" editor_service, " +
" resource_owner, " +
" ( " +
" SELECT " +
" CASE " +
" WHEN NOT check_previous THEN " +
" max_event_seq " +
" ELSE " +
" previous_sequence " +
" END" +
" ) " +
" FROM input_event " +
" WHERE EXISTS ( " +
" SELECT " +
" CASE " +
" WHEN NOT check_previous THEN 1 " +
" ELSE ( " +
" SELECT 1 FROM input_event " +
" WHERE max_event_seq = previous_sequence OR (previous_sequence IS NULL AND event_count = 0) " +
" ) " +
" END " +
" ) " +
" ) " +
"RETURNING event_sequence, creation_date "
)
type CRDB struct {
db *sql.DB
}
func (db *CRDB) Health(ctx context.Context) error { return db.db.Ping() }
// Push adds all events to the eventstreams of the aggregates.
// This call is transaction save. The transaction will be rolled back if one event fails
func (db *CRDB) Push(ctx context.Context, events ...*Event) error {
err := crdb.ExecuteTx(ctx, db.db, nil, func(tx *sql.Tx) error {
stmt, err := tx.PrepareContext(ctx, crdbInsert)
if err != nil {
tx.Rollback()
logging.Log("SQL-3to5p").WithError(err).Warn("prepare failed")
return caos_errs.ThrowInternal(err, "SQL-OdXRE", "prepare failed")
}
for _, event := range events {
previousSequence := event.PreviousSequence
if event.PreviousEvent != nil {
previousSequence = event.PreviousSequence
}
err = stmt.QueryRowContext(ctx,
event.Type,
event.AggregateType,
event.AggregateID,
event.Version,
event.CreationDate,
event.Data,
event.EditorUser,
event.EditorService,
event.ResourceOwner,
previousSequence,
event.CheckPreviousSequence,
).Scan(&event.Sequence, &event.CreationDate)
if err != nil {
tx.Rollback()
logging.LogWithFields("SQL-IP3js",
"aggregate", event.AggregateType,
"aggregateId", event.AggregateID,
"aggregateType", event.AggregateType,
"eventType", event.Type).WithError(err).Info("query failed")
return caos_errs.ThrowInternal(err, "SQL-SBP37", "unable to create event")
}
}
return nil
})
if err != nil && !errors.Is(err, &caos_errs.CaosError{}) {
err = caos_errs.ThrowInternal(err, "SQL-DjgtG", "unable to store events")
}
return err
}
// Filter returns all events matching the given search query
// func (db *CRDB) Filter(ctx context.Context, searchQuery *SearchQuery) (events []*Event, err error) {
// return events, nil
// }
//LatestSequence returns the latests sequence found by the the search query
func (db *CRDB) LatestSequence(ctx context.Context, queryFactory *SearchQuery) (uint64, error) {
return 0, nil
}
func (db *CRDB) prepareQuery(columns Columns) (string, func(s scanner, dest interface{}) error) {
switch columns {
case Columns_Max_Sequence:
return "SELECT MAX(event_sequence) FROM eventstore.events", func(scan scanner, dest interface{}) (err error) {
sequence, ok := dest.(*Sequence)
if !ok {
return caos_errs.ThrowInvalidArgument(nil, "SQL-NBjA9", "type must be sequence")
}
err = scan(sequence)
if err == nil || errors.Is(err, sql.ErrNoRows) {
return nil
}
return caos_errs.ThrowInternal(err, "SQL-bN5xg", "something went wrong")
}
case Columns_Event:
return selectStmt, func(row scanner, dest interface{}) (err error) {
event, ok := dest.(*Event)
if !ok {
return caos_errs.ThrowInvalidArgument(nil, "SQL-4GP6F", "type must be event")
}
var previousSequence Sequence
data := make(Data, 0)
err = row(
&event.CreationDate,
&event.Type,
&event.Sequence,
&previousSequence,
&data,
&event.EditorService,
&event.EditorUser,
&event.ResourceOwner,
&event.AggregateType,
&event.AggregateID,
&event.Version,
)
if err != nil {
logging.Log("SQL-kn1Sw").WithError(err).Warn("unable to scan row")
return caos_errs.ThrowInternal(err, "SQL-J0hFS", "unable to scan row")
}
event.PreviousSequence = uint64(previousSequence)
event.Data = make([]byte, len(data))
copy(event.Data, data)
return nil
}
default:
return "", nil
}
}
func (db *CRDB) prepareFilter(filters []*Filter) string {
filter := ""
// for _, f := range filters{
// f.
// }
return filter
}

View File

@ -1,6 +1,7 @@
package repository
import (
"database/sql"
"time"
)
@ -11,6 +12,7 @@ type Event struct {
//Sequence is the sequence of the event
Sequence uint64
//PreviousSequence is the sequence of the previous sequence
// if it's 0 then it's the first event of this aggregate
PreviousSequence uint64
@ -19,6 +21,10 @@ type Event struct {
// it implements a linked list
PreviousEvent *Event
//CheckPreviousSequence decides if the event can only be written
// if event.PreviousSequence == max(event_sequence) of this aggregate
CheckPreviousSequence bool
//CreationDate is the time the event is created
// it's used for human readability.
// Don't use it for event ordering,
@ -31,7 +37,7 @@ type Event struct {
//Data describe the changed fields (e.g. userName = "hodor")
// data must always a pointer to a struct, a struct or a byte array containing json bytes
Data interface{}
Data []byte
//EditorService should be a unique identifier for the service which created the event
// it's meant for maintainability
@ -54,6 +60,8 @@ type Event struct {
// an aggregate can only be managed by one organisation
// use the ID of the org
ResourceOwner string
stmt *sql.Stmt
}
//EventType is the description of the change

View File

@ -0,0 +1,62 @@
package repository
import (
"context"
"database/sql"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
type Querier interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
}
// Filter returns all events matching the given search query
func (db *CRDB) Filter(ctx context.Context, searchQuery *es_models.SearchQueryFactory) (events []*Event, err error) {
return filter(db.db, searchQuery)
}
func filter(querier Querier, searchQuery *es_models.SearchQueryFactory) (events []*Event, err error) {
query, limit, values, rowScanner := buildQuery(searchQuery)
if query == "" {
return nil, errors.ThrowInvalidArgument(nil, "SQL-rWeBw", "invalid query factory")
}
rows, err := querier.Query(query, values...)
if err != nil {
logging.Log("SQL-HP3Uk").WithError(err).Info("query failed")
return nil, errors.ThrowInternal(err, "SQL-IJuyR", "unable to filter events")
}
defer rows.Close()
events = make([]*Event, 0, limit)
for rows.Next() {
event := new(Event)
err := rowScanner(rows.Scan, event)
if err != nil {
return nil, err
}
events = append(events, event)
}
return events, nil
}
// func (db *SQL) LatestSequence(ctx context.Context, queryFactory *es_models.SearchQueryFactory) (uint64, error) {
// query, _, values, rowScanner := buildQuery(queryFactory)
// if query == "" {
// return 0, errors.ThrowInvalidArgument(nil, "SQL-rWeBw", "invalid query factory")
// }
// row := db.client.QueryRow(query, values...)
// sequence := new(Sequence)
// err := rowScanner(row.Scan, sequence)
// if err != nil {
// logging.Log("SQL-WsxTg").WithError(err).Info("query failed")
// return 0, errors.ThrowInternal(err, "SQL-Yczyx", "unable to filter latest sequence")
// }
// return uint64(*sequence), nil
// }

View File

@ -1,82 +0,0 @@
package repository
import "context"
type InMemory struct {
events []*Event
}
func (repo *InMemory) Health(ctx context.Context) error { return nil }
// PushEvents adds all events of the given aggregates to the eventstreams of the aggregates.
// This call is transaction save. The transaction will be rolled back if one event fails
func (repo *InMemory) Push(ctx context.Context, events ...*Event) error {
repo.events = append(repo.events, events...)
return nil
}
// Filter returns all events matching the given search query
func (repo *InMemory) Filter(ctx context.Context, searchQuery *SearchQuery) (events []*Event, err error) {
indexes := repo.filter(searchQuery)
events = make([]*Event, len(indexes))
for i, index := range indexes {
events[i] = repo.events[index]
}
return events, nil
}
func (repo *InMemory) filter(query *SearchQuery) []int {
foundIndex := make([]int, 0, query.Limit)
events:
for i, event := range repo.events {
if query.Limit > 0 && uint64(len(foundIndex)) < query.Limit {
return foundIndex
}
for _, filter := range query.Filters {
var value interface{}
switch filter.field {
case Field_AggregateID:
value = event.AggregateID
case Field_EditorService:
value = event.EditorService
case Field_EventType:
value = event.Type
case Field_AggregateType:
value = event.AggregateType
case Field_EditorUser:
value = event.EditorUser
case Field_ResourceOwner:
value = event.ResourceOwner
case Field_LatestSequence:
value = event.Sequence
}
switch filter.operation {
case Operation_Equals:
if filter.value == value {
foundIndex = append(foundIndex, i)
}
case Operation_Greater:
fallthrough
case Operation_Less:
return nil
case Operation_In:
values := filter.Value().([]interface{})
for _, val := range values {
if val == value {
foundIndex = append(foundIndex, i)
continue events
}
}
}
}
}
return foundIndex
}
//LatestSequence returns the latests sequence found by the the search query
func (repo *InMemory) LatestSequence(ctx context.Context, queryFactory *SearchQuery) (uint64, error) {
return 0, nil
}

View File

@ -0,0 +1,163 @@
package repository
import (
"database/sql"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"testing"
"time"
"github.com/caos/logging"
"github.com/cockroachdb/cockroach-go/v2/testserver"
)
var (
migrationsPath = os.ExpandEnv("${GOPATH}/src/github.com/caos/zitadel/migrations/cockroach")
db *sql.DB
)
func TestMain(m *testing.M) {
ts, err := testserver.NewTestServer()
if err != nil {
logging.LogWithFields("REPOS-RvjLG", "error", err).Fatal("unable to start db")
}
db, err = sql.Open("postgres", ts.PGURL().String())
if err != nil {
logging.LogWithFields("REPOS-CF6dQ", "error", err).Fatal("unable to connect to db")
}
defer func() {
db.Close()
ts.Stop()
}()
if err = executeMigrations(); err != nil {
logging.LogWithFields("REPOS-jehDD", "error", err).Fatal("migrations failed")
}
os.Exit(m.Run())
}
func TestInsert(t *testing.T) {
tx, _ := db.Begin()
var seq Sequence
var d time.Time
row := tx.QueryRow(crdbInsert, "event.type", "aggregate.type", "aggregate.id", Version("v1"), nil, Data(nil), "editor.user", "editor.service", "resource.owner", Sequence(0), false)
err := row.Scan(&seq, &d)
row = tx.QueryRow(crdbInsert, "event.type", "aggregate.type", "aggregate.id", Version("v1"), nil, Data(nil), "editor.user", "editor.service", "resource.owner", Sequence(1), true)
err = row.Scan(&seq, &d)
row = tx.QueryRow(crdbInsert, "event.type", "aggregate.type", "aggregate.id", Version("v1"), nil, Data(nil), "editor.user", "editor.service", "resource.owner", Sequence(0), false)
err = row.Scan(&seq, &d)
tx.Commit()
rows, err := db.Query("select * from eventstore.events order by event_sequence")
defer rows.Close()
fmt.Println(err)
fmt.Println(rows.Columns())
for rows.Next() {
i := make([]interface{}, 12)
var id string
rows.Scan(&id, &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7], &i[8], &i[9], &i[10], &i[11])
i[0] = id
fmt.Println(i)
}
t.Fail()
}
func executeMigrations() error {
files, err := migrationFilePaths()
if err != nil {
return err
}
sort.Sort(files)
for _, file := range files {
migration, err := ioutil.ReadFile(string(file))
if err != nil {
return err
}
transactionInMigration := strings.Contains(string(migration), "BEGIN;")
exec := db.Exec
var tx *sql.Tx
if !transactionInMigration {
tx, err = db.Begin()
if err != nil {
return fmt.Errorf("begin file: %v || err: %w", file, err)
}
exec = tx.Exec
}
if _, err = exec(string(migration)); err != nil {
return fmt.Errorf("exec file: %v || err: %w", file, err)
}
if !transactionInMigration {
if err = tx.Commit(); err != nil {
return fmt.Errorf("commit file: %v || err: %w", file, err)
}
}
}
return nil
}
type migrationPaths []string
type version struct {
major int
minor int
}
func versionFromPath(s string) version {
v := s[strings.Index(s, "/V")+2 : strings.Index(s, "__")]
splitted := strings.Split(v, ".")
res := version{}
var err error
if len(splitted) >= 1 {
res.major, err = strconv.Atoi(splitted[0])
if err != nil {
panic(err)
}
}
if len(splitted) >= 2 {
res.minor, err = strconv.Atoi(splitted[1])
if err != nil {
panic(err)
}
}
return res
}
func (a migrationPaths) Len() int { return len(a) }
func (a migrationPaths) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a migrationPaths) Less(i, j int) bool {
versionI := versionFromPath(a[i])
versionJ := versionFromPath(a[j])
return versionI.major < versionJ.major ||
(versionI.major == versionJ.major && versionI.minor < versionJ.minor)
}
func migrationFilePaths() (migrationPaths, error) {
files := make(migrationPaths, 0)
err := filepath.Walk(migrationsPath, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() || !strings.HasSuffix(info.Name(), ".sql") {
return err
}
files = append(files, path)
return nil
})
return files, err
}

View File

@ -0,0 +1,199 @@
package repository
import (
"database/sql"
"errors"
"fmt"
"strconv"
"strings"
"github.com/caos/logging"
z_errors "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/lib/pq"
)
const (
selectStmt = "SELECT" +
" creation_date" +
", event_type" +
", event_sequence" +
", previous_sequence" +
", event_data" +
", editor_service" +
", editor_user" +
", resource_owner" +
", aggregate_type" +
", aggregate_id" +
", aggregate_version" +
" FROM eventstore.events"
)
func buildQuery(queryFactory *models.SearchQueryFactory) (query string, limit uint64, values []interface{}, rowScanner func(s scanner, dest interface{}) error) {
searchQuery, err := queryFactory.Build()
if err != nil {
logging.Log("SQL-cshKu").WithError(err).Warn("search query factory invalid")
return "", 0, nil, nil
}
query, rowScanner = prepareColumns(searchQuery.Columns)
where, values := prepareCondition(searchQuery.Filters)
if where == "" || query == "" {
return "", 0, nil, nil
}
query += where
if searchQuery.Columns != models.Columns_Max_Sequence {
query += " ORDER BY event_sequence"
if searchQuery.Desc {
query += " DESC"
}
}
if searchQuery.Limit > 0 {
values = append(values, searchQuery.Limit)
query += " LIMIT ?"
}
query = numberPlaceholder(query, "?", "$")
return query, searchQuery.Limit, values, rowScanner
}
func prepareCondition(filters []*models.Filter) (clause string, values []interface{}) {
values = make([]interface{}, len(filters))
clauses := make([]string, len(filters))
if len(filters) == 0 {
return clause, values
}
for i, filter := range filters {
value := filter.GetValue()
switch value.(type) {
case []bool, []float64, []int64, []string, []models.AggregateType, []models.EventType, *[]bool, *[]float64, *[]int64, *[]string, *[]models.AggregateType, *[]models.EventType:
value = pq.Array(value)
}
clauses[i] = getCondition(filter)
if clauses[i] == "" {
return "", nil
}
values[i] = value
}
return " WHERE " + strings.Join(clauses, " AND "), values
}
type scanner func(dest ...interface{}) error
func prepareColumns(columns models.Columns) (string, func(s scanner, dest interface{}) error) {
switch columns {
case models.Columns_Max_Sequence:
return "SELECT MAX(event_sequence) FROM eventstore.events", func(row scanner, dest interface{}) (err error) {
sequence, ok := dest.(*Sequence)
if !ok {
return z_errors.ThrowInvalidArgument(nil, "SQL-NBjA9", "type must be sequence")
}
err = row(sequence)
if err == nil || errors.Is(err, sql.ErrNoRows) {
return nil
}
return z_errors.ThrowInternal(err, "SQL-bN5xg", "something went wrong")
}
case models.Columns_Event:
return selectStmt, func(row scanner, dest interface{}) (err error) {
event, ok := dest.(*models.Event)
if !ok {
return z_errors.ThrowInvalidArgument(nil, "SQL-4GP6F", "type must be event")
}
var previousSequence Sequence
data := make(Data, 0)
err = row(
&event.CreationDate,
&event.Type,
&event.Sequence,
&previousSequence,
&data,
&event.EditorService,
&event.EditorUser,
&event.ResourceOwner,
&event.AggregateType,
&event.AggregateID,
&event.AggregateVersion,
)
if err != nil {
logging.Log("SQL-kn1Sw").WithError(err).Warn("unable to scan row")
return z_errors.ThrowInternal(err, "SQL-J0hFS", "unable to scan row")
}
event.PreviousSequence = uint64(previousSequence)
event.Data = make([]byte, len(data))
copy(event.Data, data)
return nil
}
default:
return "", nil
}
}
func numberPlaceholder(query, old, new string) string {
for i, hasChanged := 1, true; hasChanged; i++ {
newQuery := strings.Replace(query, old, new+strconv.Itoa(i), 1)
hasChanged = query != newQuery
query = newQuery
}
return query
}
func getCondition(filter *es_models.Filter) (condition string) {
field := getField(filter.GetField())
operation := getOperation(filter.GetOperation())
if field == "" || operation == "" {
return ""
}
format := getConditionFormat(filter.GetOperation())
return fmt.Sprintf(format, field, operation)
}
func getConditionFormat(operation es_models.Operation) string {
if operation == es_models.Operation_In {
return "%s %s ANY(?)"
}
return "%s %s ?"
}
func getField(field es_models.Field) string {
switch field {
case es_models.Field_AggregateID:
return "aggregate_id"
case es_models.Field_AggregateType:
return "aggregate_type"
case es_models.Field_LatestSequence:
return "event_sequence"
case es_models.Field_ResourceOwner:
return "resource_owner"
case es_models.Field_EditorService:
return "editor_service"
case es_models.Field_EditorUser:
return "editor_user"
case es_models.Field_EventType:
return "event_type"
}
return ""
}
func getOperation(operation es_models.Operation) string {
switch operation {
case es_models.Operation_Equals, es_models.Operation_In:
return "="
case es_models.Operation_Greater:
return ">"
case es_models.Operation_Less:
return "<"
}
return ""
}

View File

@ -0,0 +1,486 @@
package repository
import (
"database/sql"
"reflect"
"testing"
"time"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
"github.com/lib/pq"
)
func Test_numberPlaceholder(t *testing.T) {
type args struct {
query string
old string
new string
}
type res struct {
query string
}
tests := []struct {
name string
args args
res res
}{
{
name: "no replaces",
args: args{
new: "$",
old: "?",
query: "SELECT * FROM eventstore.events",
},
res: res{
query: "SELECT * FROM eventstore.events",
},
},
{
name: "two replaces",
args: args{
new: "$",
old: "?",
query: "SELECT * FROM eventstore.events WHERE aggregate_type = ? AND LIMIT = ?",
},
res: res{
query: "SELECT * FROM eventstore.events WHERE aggregate_type = $1 AND LIMIT = $2",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := numberPlaceholder(tt.args.query, tt.args.old, tt.args.new); got != tt.res.query {
t.Errorf("numberPlaceholder() = %v, want %v", got, tt.res.query)
}
})
}
}
func Test_getOperation(t *testing.T) {
t.Run("all ops", func(t *testing.T) {
for op, expected := range map[es_models.Operation]string{
es_models.Operation_Equals: "=",
es_models.Operation_In: "=",
es_models.Operation_Greater: ">",
es_models.Operation_Less: "<",
es_models.Operation(-1): "",
} {
if got := getOperation(op); got != expected {
t.Errorf("getOperation() = %v, want %v", got, expected)
}
}
})
}
func Test_getField(t *testing.T) {
t.Run("all fields", func(t *testing.T) {
for field, expected := range map[es_models.Field]string{
es_models.Field_AggregateType: "aggregate_type",
es_models.Field_AggregateID: "aggregate_id",
es_models.Field_LatestSequence: "event_sequence",
es_models.Field_ResourceOwner: "resource_owner",
es_models.Field_EditorService: "editor_service",
es_models.Field_EditorUser: "editor_user",
es_models.Field_EventType: "event_type",
es_models.Field(-1): "",
} {
if got := getField(field); got != expected {
t.Errorf("getField() = %v, want %v", got, expected)
}
}
})
}
func Test_getConditionFormat(t *testing.T) {
type args struct {
operation es_models.Operation
}
tests := []struct {
name string
args args
want string
}{
{
name: "no in operation",
args: args{
operation: es_models.Operation_Equals,
},
want: "%s %s ?",
},
{
name: "in operation",
args: args{
operation: es_models.Operation_In,
},
want: "%s %s ANY(?)",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := getConditionFormat(tt.args.operation); got != tt.want {
t.Errorf("prepareConditionFormat() = %v, want %v", got, tt.want)
}
})
}
}
func Test_getCondition(t *testing.T) {
type args struct {
filter *es_models.Filter
}
tests := []struct {
name string
args args
want string
}{
{
name: "equals",
args: args{filter: es_models.NewFilter(es_models.Field_AggregateID, "", es_models.Operation_Equals)},
want: "aggregate_id = ?",
},
{
name: "greater",
args: args{filter: es_models.NewFilter(es_models.Field_LatestSequence, 0, es_models.Operation_Greater)},
want: "event_sequence > ?",
},
{
name: "less",
args: args{filter: es_models.NewFilter(es_models.Field_LatestSequence, 5000, es_models.Operation_Less)},
want: "event_sequence < ?",
},
{
name: "in list",
args: args{filter: es_models.NewFilter(es_models.Field_AggregateType, []es_models.AggregateType{"movies", "actors"}, es_models.Operation_In)},
want: "aggregate_type = ANY(?)",
},
{
name: "invalid operation",
args: args{filter: es_models.NewFilter(es_models.Field_AggregateType, []es_models.AggregateType{"movies", "actors"}, es_models.Operation(-1))},
want: "",
},
{
name: "invalid field",
args: args{filter: es_models.NewFilter(es_models.Field(-1), []es_models.AggregateType{"movies", "actors"}, es_models.Operation_Equals)},
want: "",
},
{
name: "invalid field and operation",
args: args{filter: es_models.NewFilter(es_models.Field(-1), []es_models.AggregateType{"movies", "actors"}, es_models.Operation(-1))},
want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := getCondition(tt.args.filter); got != tt.want {
t.Errorf("getCondition() = %v, want %v", got, tt.want)
}
})
}
}
func Test_prepareColumns(t *testing.T) {
type args struct {
columns models.Columns
dest interface{}
dbErr error
}
type res struct {
query string
dbRow []interface{}
expected interface{}
dbErr func(error) bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "invalid columns",
args: args{columns: es_models.Columns(-1)},
res: res{
query: "",
dbErr: func(err error) bool { return err == nil },
},
},
{
name: "max column",
args: args{
columns: es_models.Columns_Max_Sequence,
dest: new(Sequence),
},
res: res{
query: "SELECT MAX(event_sequence) FROM eventstore.events",
dbRow: []interface{}{Sequence(5)},
expected: Sequence(5),
},
},
{
name: "max sequence wrong dest type",
args: args{
columns: es_models.Columns_Max_Sequence,
dest: new(uint64),
},
res: res{
query: "SELECT MAX(event_sequence) FROM eventstore.events",
dbErr: errors.IsErrorInvalidArgument,
},
},
{
name: "event",
args: args{
columns: es_models.Columns_Event,
dest: new(models.Event),
},
res: res{
query: "SELECT creation_date, event_type, event_sequence, previous_sequence, event_data, editor_service, editor_user, resource_owner, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events",
dbRow: []interface{}{time.Time{}, models.EventType(""), uint64(5), Sequence(0), Data(nil), "", "", "", models.AggregateType("user"), "hodor", models.Version("")},
expected: models.Event{AggregateID: "hodor", AggregateType: "user", Sequence: 5, Data: make(Data, 0)},
},
},
{
name: "event wrong dest type",
args: args{
columns: es_models.Columns_Event,
dest: new(uint64),
},
res: res{
query: "SELECT creation_date, event_type, event_sequence, previous_sequence, event_data, editor_service, editor_user, resource_owner, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events",
dbErr: errors.IsErrorInvalidArgument,
},
},
{
name: "event query error",
args: args{
columns: es_models.Columns_Event,
dest: new(models.Event),
dbErr: sql.ErrConnDone,
},
res: res{
query: "SELECT creation_date, event_type, event_sequence, previous_sequence, event_data, editor_service, editor_user, resource_owner, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events",
dbErr: errors.IsInternal,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
query, rowScanner := prepareColumns(tt.args.columns)
if query != tt.res.query {
t.Errorf("prepareColumns() got = %v, want %v", query, tt.res.query)
}
if tt.res.query == "" && rowScanner != nil {
t.Errorf("row scanner should be nil")
}
if rowScanner == nil {
return
}
err := rowScanner(prepareTestScan(tt.args.dbErr, tt.res.dbRow), tt.args.dest)
if tt.res.dbErr != nil {
if !tt.res.dbErr(err) {
t.Errorf("wrong error type in rowScanner got: %v", err)
}
} else {
if !reflect.DeepEqual(reflect.Indirect(reflect.ValueOf(tt.args.dest)).Interface(), tt.res.expected) {
t.Errorf("unexpected result from rowScanner want: %v got: %v", tt.res.dbRow, tt.args.dest)
}
}
})
}
}
func prepareTestScan(err error, res []interface{}) scanner {
return func(dests ...interface{}) error {
if err != nil {
return err
}
if len(dests) != len(res) {
return errors.ThrowInvalidArgumentf(nil, "SQL-NML1q", "expected len %d got %d", len(res), len(dests))
}
for i, r := range res {
reflect.ValueOf(dests[i]).Elem().Set(reflect.ValueOf(r))
}
return nil
}
}
func Test_prepareCondition(t *testing.T) {
type args struct {
filters []*models.Filter
}
type res struct {
clause string
values []interface{}
}
tests := []struct {
name string
args args
res res
}{
{
name: "nil filters",
args: args{
filters: nil,
},
res: res{
clause: "",
values: nil,
},
},
{
name: "empty filters",
args: args{
filters: []*es_models.Filter{},
},
res: res{
clause: "",
values: nil,
},
},
{
name: "invalid condition",
args: args{
filters: []*es_models.Filter{
es_models.NewFilter(es_models.Field_AggregateID, "wrong", es_models.Operation(-1)),
},
},
res: res{
clause: "",
values: nil,
},
},
{
name: "array as condition value",
args: args{
filters: []*es_models.Filter{
es_models.NewFilter(es_models.Field_AggregateType, []es_models.AggregateType{"user", "org"}, es_models.Operation_In),
},
},
res: res{
clause: " WHERE aggregate_type = ANY(?)",
values: []interface{}{pq.Array([]es_models.AggregateType{"user", "org"})},
},
},
{
name: "multiple filters",
args: args{
filters: []*es_models.Filter{
es_models.NewFilter(es_models.Field_AggregateType, []es_models.AggregateType{"user", "org"}, es_models.Operation_In),
es_models.NewFilter(es_models.Field_AggregateID, "1234", es_models.Operation_Equals),
es_models.NewFilter(es_models.Field_EventType, []es_models.EventType{"user.created", "org.created"}, es_models.Operation_In),
},
},
res: res{
clause: " WHERE aggregate_type = ANY(?) AND aggregate_id = ? AND event_type = ANY(?)",
values: []interface{}{pq.Array([]es_models.AggregateType{"user", "org"}), "1234", pq.Array([]es_models.EventType{"user.created", "org.created"})},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotClause, gotValues := prepareCondition(tt.args.filters)
if gotClause != tt.res.clause {
t.Errorf("prepareCondition() gotClause = %v, want %v", gotClause, tt.res.clause)
}
if len(gotValues) != len(tt.res.values) {
t.Errorf("wrong length of gotten values got = %d, want %d", len(gotValues), len(tt.res.values))
return
}
for i, value := range gotValues {
if !reflect.DeepEqual(value, tt.res.values[i]) {
t.Errorf("prepareCondition() gotValues = %v, want %v", gotValues, tt.res.values)
}
}
})
}
}
func Test_buildQuery(t *testing.T) {
type args struct {
queryFactory *models.SearchQueryFactory
}
type res struct {
query string
limit uint64
values []interface{}
rowScanner bool
}
tests := []struct {
name string
args args
res res
}{
{
name: "invalid query factory",
args: args{
queryFactory: nil,
},
res: res{
query: "",
limit: 0,
rowScanner: false,
values: nil,
},
},
{
name: "with order by desc",
args: args{
queryFactory: es_models.NewSearchQueryFactory("user").OrderDesc(),
},
res: res{
query: "SELECT creation_date, event_type, event_sequence, previous_sequence, event_data, editor_service, editor_user, resource_owner, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence DESC",
rowScanner: true,
values: []interface{}{es_models.AggregateType("user")},
},
},
{
name: "with limit",
args: args{
queryFactory: es_models.NewSearchQueryFactory("user").Limit(5),
},
res: res{
query: "SELECT creation_date, event_type, event_sequence, previous_sequence, event_data, editor_service, editor_user, resource_owner, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence LIMIT $2",
rowScanner: true,
values: []interface{}{es_models.AggregateType("user"), uint64(5)},
limit: 5,
},
},
{
name: "with limit and order by desc",
args: args{
queryFactory: es_models.NewSearchQueryFactory("user").Limit(5).OrderDesc(),
},
res: res{
query: "SELECT creation_date, event_type, event_sequence, previous_sequence, event_data, editor_service, editor_user, resource_owner, aggregate_type, aggregate_id, aggregate_version FROM eventstore.events WHERE aggregate_type = $1 ORDER BY event_sequence DESC LIMIT $2",
rowScanner: true,
values: []interface{}{es_models.AggregateType("user"), uint64(5)},
limit: 5,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotQuery, gotLimit, gotValues, gotRowScanner := buildQuery(tt.args.queryFactory)
if gotQuery != tt.res.query {
t.Errorf("buildQuery() gotQuery = %v, want %v", gotQuery, tt.res.query)
}
if gotLimit != tt.res.limit {
t.Errorf("buildQuery() gotLimit = %v, want %v", gotLimit, tt.res.limit)
}
if len(gotValues) != len(tt.res.values) {
t.Errorf("wrong length of gotten values got = %d, want %d", len(gotValues), len(tt.res.values))
return
}
for i, value := range gotValues {
if !reflect.DeepEqual(value, tt.res.values[i]) {
t.Errorf("prepareCondition() gotValues = %v, want %v", gotValues, tt.res.values)
}
}
if (tt.res.rowScanner && gotRowScanner == nil) || (!tt.res.rowScanner && gotRowScanner != nil) {
t.Errorf("rowScanner should be nil==%v got nil==%v", tt.res.rowScanner, gotRowScanner == nil)
}
})
}
}

View File

@ -0,0 +1,47 @@
package repository
import "database/sql/driver"
// Data represents a byte array that may be null.
// Data implements the sql.Scanner interface
type Data []byte
// Scan implements the Scanner interface.
func (data *Data) Scan(value interface{}) error {
if value == nil {
*data = nil
return nil
}
*data = Data(value.([]byte))
return nil
}
// Value implements the driver Valuer interface.
func (data Data) Value() (driver.Value, error) {
if len(data) == 0 {
return nil, nil
}
return []byte(data), nil
}
// Sequence represents a number that may be null.
// Sequence implements the sql.Scanner interface
type Sequence uint64
// Scan implements the Scanner interface.
func (seq *Sequence) Scan(value interface{}) error {
if value == nil {
*seq = 0
return nil
}
*seq = Sequence(value.(int64))
return nil
}
// Value implements the driver Valuer interface.
func (seq Sequence) Value() (driver.Value, error) {
if seq == 0 {
return nil, nil
}
return int64(seq), nil
}

View File

@ -1,5 +1,18 @@
ALTER TABLE management.machine_keys DROP COLUMN IF EXISTS public_key;
ALTER TABLE management.machine_keys ADD COLUMN public_key BYTES;
-- table manipulations need to be in seperate transactions
-- (see: https://github.com/cockroachdb/cockroach/issues/13380#issuecomment-306560448)
BEGIN;
ALTER TABLE management.machine_keys DROP COLUMN IF EXISTS public_key;
COMMIT;
BEGIN;
ALTER TABLE management.machine_keys ADD COLUMN public_key BYTES;
COMMIT;
BEGIN;
ALTER TABLE auth.machine_keys DROP COLUMN IF EXISTS public_key;
ALTER TABLE auth.machine_keys ADD COLUMN public_key BYTES;
COMMIT;
BEGIN;
ALTER TABLE auth.machine_keys ADD COLUMN public_key BYTES;
COMMIT;

View File

@ -1,36 +0,0 @@
ATTACH DATABASE '${GOPATH}/src/github.com/caos/zitadel/.local/management.db' AS 'management';
ATTACH DATABASE '${GOPATH}/src/github.com/caos/zitadel/.local/auth.db' AS 'auth';
ATTACH DATABASE '${GOPATH}/src/github.com/caos/zitadel/.local/notification.db' AS 'notification';
ATTACH DATABASE '${GOPATH}/src/github.com/caos/zitadel/.local/adminapi.db' AS 'adminapi';
ATTACH DATABASE '${GOPATH}/src/github.com/caos/zitadel/.local/authz.db' AS 'authz';
ATTACH DATABASE '${GOPATH}/src/github.com/caos/zitadel/.local/eventstore.db' AS 'eventstore';
-- CREATE USER eventstore;
-- GRANT SELECT, INSERT ON DATABASE eventstore TO eventstore;
-- CREATE USER management;
-- GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE management TO management;
-- GRANT SELECT, INSERT ON DATABASE eventstore TO management;
-- CREATE USER adminapi;
-- GRANT SELECT, INSERT, UPDATE, DELETE, DROP ON DATABASE adminapi TO adminapi;
-- GRANT SELECT, INSERT ON DATABASE eventstore TO adminapi;
-- GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE auth TO adminapi;
-- GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE authz TO adminapi;
-- GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE management TO adminapi;
-- GRANT SELECT, INSERT, UPDATE, DROP, DELETE ON DATABASE notification TO adminapi;
-- CREATE USER auth;
-- GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE auth TO auth;
-- GRANT SELECT, INSERT ON DATABASE eventstore TO auth;
-- CREATE USER notification;
-- GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE notification TO notification;
-- GRANT SELECT, INSERT ON DATABASE eventstore TO notification;
-- CREATE USER authz;
-- GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE authz TO authz;
-- GRANT SELECT, INSERT ON DATABASE eventstore TO authz;
-- GRANT SELECT, INSERT, UPDATE ON DATABASE auth TO authz;

View File

@ -1,15 +0,0 @@
ALTER TABLE management.users ADD COLUMN machine_name STRING, ADD COLUMN machine_description STRING, ADD COLUMN user_type STRING;
ALTER TABLE adminapi.users ADD COLUMN machine_name STRING, ADD COLUMN machine_description STRING, ADD COLUMN user_type STRING;
ALTER TABLE auth.users ADD COLUMN machine_name STRING, ADD COLUMN machine_description STRING, ADD COLUMN user_type STRING;
CREATE TABLE management.machine_keys (
id TEXT,
user_id TEXT,
machine_type SMALLINT,
expiration_date TIMESTAMPTZ,
sequence BIGINT,
creation_date TIMESTAMPTZ,
PRIMARY KEY (id, user_id)
)

View File

@ -1,18 +0,0 @@
CREATE TABLE auth.user_memberships (
user_id TEXT,
member_type SMALLINT,
aggregate_id TEXT,
object_id TEXT,
roles TEXT ARRAY,
display_name TEXT,
resource_owner TEXT,
resource_owner_name TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
PRIMARY KEY (user_id, member_type, aggregate_id, object_id)
);
ALTER TABLE management.user_memberships ADD COLUMN resource_owner_name TEXT;

View File

@ -1,14 +0,0 @@
CREATE TABLE auth.machine_keys (
id TEXT,
user_id TEXT,
machine_type SMALLINT,
expiration_date TIMESTAMPTZ,
sequence BIGINT,
creation_date TIMESTAMPTZ,
public_key JSONB,
PRIMARY KEY (id, user_id)
);
ALTER TABLE management.machine_keys ADD COLUMN public_key JSONB;

View File

@ -1,5 +0,0 @@
ALTER TABLE management.machine_keys DROP COLUMN IF EXISTS public_key;
ALTER TABLE management.machine_keys ADD COLUMN public_key BYTES;
ALTER TABLE auth.machine_keys DROP COLUMN IF EXISTS public_key;
ALTER TABLE auth.machine_keys ADD COLUMN public_key BYTES;

View File

@ -1,105 +0,0 @@
ALTER TABLE adminapi.idp_configs ADD COLUMN oidc_idp_display_name_mapping SMALLINT;
ALTER TABLE adminapi.idp_configs ADD COLUMN oidc_idp_username_mapping SMALLINT;
ALTER TABLE management.idp_configs ADD COLUMN oidc_idp_display_name_mapping SMALLINT;
ALTER TABLE management.idp_configs ADD COLUMN oidc_idp_username_mapping SMALLINT;
CREATE TABLE auth.idp_configs (
idp_config_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
aggregate_id TEXT,
name TEXT,
logo_src BYTES,
idp_state SMALLINT,
idp_provider_type SMALLINT,
is_oidc BOOLEAN,
oidc_client_id TEXT,
oidc_client_secret JSONB,
oidc_issuer TEXT,
oidc_scopes TEXT ARRAY,
oidc_idp_display_name_mapping SMALLINT,
oidc_idp_username_mapping SMALLINT,
PRIMARY KEY (idp_config_id)
);
CREATE TABLE auth.login_policies (
aggregate_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
login_policy_state SMALLINT,
sequence BIGINT,
allow_register BOOLEAN,
allow_username_password BOOLEAN,
allow_external_idp BOOLEAN,
PRIMARY KEY (aggregate_id)
);
CREATE TABLE auth.idp_providers (
aggregate_id TEXT,
idp_config_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
name string,
idp_config_type SMALLINT,
idp_provider_type SMALLINT,
PRIMARY KEY (aggregate_id, idp_config_id)
);
CREATE TABLE auth.user_external_idps (
external_user_id TEXT,
idp_config_id TEXT,
user_id TEXT,
idp_name TEXT,
user_display_name TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
resource_owner TEXT,
PRIMARY KEY (external_user_id, idp_config_id)
);
CREATE TABLE management.user_external_idps (
idp_config_id TEXT,
external_user_id TEXT,
user_id TEXT,
idp_name TEXT,
user_display_name TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
resource_owner TEXT,
PRIMARY KEY (external_user_id, idp_config_id)
);
CREATE TABLE adminapi.user_external_idps (
idp_config_id TEXT,
external_user_id TEXT,
user_id TEXT,
idp_name TEXT,
user_display_name TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
resource_owner TEXT,
PRIMARY KEY (external_user_id, idp_config_id)
);

View File

@ -1,3 +0,0 @@
ALTER TABLE adminapi.idp_providers ADD COLUMN idp_state SMALLINT;
ALTER TABLE management.idp_providers ADD COLUMN idp_state SMALLINT;
ALTER TABLE auth.idp_providers ADD COLUMN idp_state SMALLINT;

View File

@ -1,18 +0,0 @@
CREATE TABLE eventstore.events (
event_type TEXT,
aggregate_type TEXT NOT NULL,
aggregate_id TEXT NOT NULL,
aggregate_version TEXT NOT NULL,
event_sequence INTEGER,
previous_sequence BIGINT,
creation_date TIMESTAMPT NOT NULL DEFAULT CURRENT_TIMESTAMP,
event_data JSONB,
editor_user TEXT NOT NULL,
editor_service TEXT NOT NULL,
resource_owner TEXT NOT NULL,
CONSTRAINT event_sequence_pk PRIMARY KEY (event_sequence DESC),
CONSTRAINT previous_sequence_unique UNIQUE (previous_sequence DESC)
);
CREATE INDEX eventstore.agg_type_agg_id ON events (aggregate_type, aggregate_id);

View File

@ -1,628 +0,0 @@
CREATE TABLE management.locks (
locker_id TEXT,
locked_until TIMESTAMP,
view_name TEXT,
PRIMARY KEY (view_name)
);
CREATE TABLE management.current_sequences (
view_name TEXT,
current_sequence BIGINT,
timestamp TIMESTAMP,
PRIMARY KEY (view_name)
);
CREATE TABLE management.failed_events (
view_name TEXT,
failed_sequence BIGINT,
failure_count SMALLINT,
err_msg TEXT,
PRIMARY KEY (view_name, failed_sequence)
);
CREATE TABLE management.projects (
project_id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
project_name TEXT,
project_state SMALLINT,
resource_owner TEXT,
sequence BIGINT,
PRIMARY KEY (project_id)
);
CREATE TABLE management.project_grants (
grant_id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
project_id TEXT,
project_name TEXT,
org_name TEXT,
project_state SMALLINT,
resource_owner TEXT,
org_id TEXT,
granted_role_keys TEXT Array,
sequence BIGINT,
resource_owner_name TEXT,
PRIMARY KEY (grant_id)
);
CREATE TABLE management.project_roles (
project_id TEXT,
role_key TEXT,
display_name TEXT,
resource_owner TEXT,
org_id TEXT,
group_name TEXT,
creation_date TIMESTAMP,
sequence BIGINT,
PRIMARY KEY (org_id, project_id, role_key)
);
CREATE TABLE management.project_members (
user_id TEXT,
project_id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
user_name TEXT,
email_address TEXT,
first_name TEXT,
last_name TEXT,
roles TEXT ARRAY,
display_name TEXT,
sequence BIGINT,
PRIMARY KEY (project_id, user_id)
);
CREATE TABLE management.project_grant_members (
user_id TEXT,
grant_id TEXT,
project_id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
user_name TEXT,
email_address TEXT,
first_name TEXT,
last_name TEXT,
roles TEXT ARRAY,
display_name TEXT,
sequence BIGINT,
PRIMARY KEY (grant_id, user_id)
);
CREATE TABLE management.applications (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
sequence BIGINT,
app_state SMALLINT,
resource_owner TEXT,
app_name TEXT,
project_id TEXT,
app_type SMALLINT,
is_oidc BOOLEAN,
oidc_client_id TEXT,
oidc_redirect_uris TEXT ARRAY,
oidc_response_types SMALLINT ARRAY,
oidc_grant_types SMALLINT ARRAY,
oidc_application_type SMALLINT,
oidc_auth_method_type SMALLINT,
oidc_post_logout_redirect_uris TEXT ARRAY,
PRIMARY KEY (id)
);
CREATE TABLE management.users (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
user_state SMALLINT,
last_login TIMESTAMP,
password_change TIMESTAMP,
user_name TEXT,
login_names TEXT ARRAY,
preferred_login_name TEXT,
first_name TEXT,
last_name TEXT,
nick_Name TEXT,
display_name TEXT,
preferred_language TEXT,
gender SMALLINT,
email TEXT,
is_email_verified BOOLEAN,
phone TEXT,
is_phone_verified BOOLEAN,
country TEXT,
locality TEXT,
postal_code TEXT,
region TEXT,
street_address TEXT,
otp_state SMALLINT,
sequence BIGINT,
password_set BOOLEAN,
password_change_required BOOLEAN,
mfa_max_set_up SMALLINT,
mfa_init_skipped TIMESTAMP,
init_required BOOLEAN,
PRIMARY KEY (id)
);
CREATE TABLE management.user_grants (
id TEXT,
resource_owner TEXT,
project_id TEXT,
user_id TEXT,
org_name TEXT,
project_name TEXT,
user_name TEXT,
display_name TEXT,
first_name TEXT,
last_name TEXT,
email TEXT,
role_keys TEXT Array,
grant_id TEXT,
grant_state SMALLINT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
sequence BIGINT,
PRIMARY KEY (id)
);
CREATE TABLE management.org_domains (
creation_date TIMESTAMP,
change_date TIMESTAMP,
sequence BIGINT,
domain TEXT,
org_id TEXT,
verified BOOLEAN,
primary_domain BOOLEAN,
PRIMARY KEY (org_id, domain)
);
CREATE TABLE auth.locks (
locker_id TEXT,
locked_until TIMESTAMP,
view_name TEXT,
PRIMARY KEY (view_name)
);
CREATE TABLE auth.current_sequences (
view_name TEXT,
timestamp TIMESTAMP,
current_sequence BIGINT,
PRIMARY KEY (view_name)
);
CREATE TABLE auth.failed_events (
view_name TEXT,
failed_sequence BIGINT,
failure_count SMALLINT,
err_msg TEXT,
PRIMARY KEY (view_name, failed_sequence)
);
CREATE TABLE auth.auth_requests (
id TEXT,
request JSONB,
code TEXT,
request_type smallint,
PRIMARY KEY (id)
);
CREATE TABLE auth.users (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
user_state SMALLINT,
password_set BOOLEAN,
password_change_required BOOLEAN,
password_change TIMESTAMP,
last_login TIMESTAMP,
user_name TEXT,
login_names TEXT ARRAY,
preferred_login_name TEXT,
first_name TEXT,
last_name TEXT,
nick_name TEXT,
display_name TEXT,
preferred_language TEXT,
gender SMALLINT,
email TEXT,
is_email_verified BOOLEAN,
phone TEXT,
is_phone_verified BOOLEAN,
country TEXT,
locality TEXT,
postal_code TEXT,
region TEXT,
street_address TEXT,
otp_state SMALLINT,
mfa_max_set_up SMALLINT,
mfa_init_skipped TIMESTAMP,
sequence BIGINT,
init_required BOOLEAN,
PRIMARY KEY (id)
);
CREATE TABLE auth.user_sessions (
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
state SMALLINT,
user_agent_id TEXT,
user_id TEXT,
user_name TEXT,
password_verification TIMESTAMP,
mfa_software_verification TIMESTAMP,
mfa_hardware_verification TIMESTAMP,
sequence BIGINT,
mfa_software_verification_type SMALLINT,
mfa_hardware_verification_type SMALLINT,
user_display_name TEXT,
login_name TEXT,
PRIMARY KEY (user_agent_id, user_id)
);
CREATE TABLE auth.tokens (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
application_id TEXT,
user_agent_id TEXT,
user_id TEXT,
expiration TIMESTAMP,
sequence BIGINT,
scopes TEXT ARRAY,
audience TEXT ARRAY,
PRIMARY KEY (id)
);
CREATE TABLE notification.locks (
locker_id TEXT,
locked_until TIMESTAMP,
view_name TEXT,
PRIMARY KEY (view_name)
);
CREATE TABLE notification.current_sequences (
view_name TEXT,
timestamp TIMESTAMP,
current_sequence BIGINT,
PRIMARY KEY (view_name)
);
CREATE TABLE notification.failed_events (
view_name TEXT,
failed_sequence BIGINT,
failure_count SMALLINT,
err_msg TEXT,
PRIMARY KEY (view_name, failed_sequence)
);
CREATE TABLE notification.notify_users (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
user_name TEXT,
first_name TEXT,
last_name TEXT,
nick_Name TEXT,
display_name TEXT,
preferred_language TEXT,
gender SMALLINT,
last_email TEXT,
verified_email TEXT,
last_phone TEXT,
verified_phone TEXT,
sequence BIGINT,
password_set BOOLEAN,
login_names TEXT,
preferred_login_name TEXT,
PRIMARY KEY (id)
);
CREATE TABLE adminapi.orgs (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
org_state SMALLINT,
sequence BIGINT,
domain TEXT,
name TEXT,
PRIMARY KEY (id)
);
CREATE TABLE adminapi.failed_events (
view_name TEXT,
failed_sequence BIGINT,
failure_count SMALLINT,
err_msg TEXT,
PRIMARY KEY (view_name, failed_sequence)
);
CREATE TABLE adminapi.locks (
locker_id TEXT,
locked_until TIMESTAMP,
view_name TEXT,
PRIMARY KEY (view_name)
);
CREATE TABLE adminapi.current_sequences (
view_name TEXT,
timestamp TIMESTAMP,
current_sequence BIGINT,
PRIMARY KEY (view_name)
);
CREATE TABLE adminapi.iam_members (
user_id TEXT,
iam_id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
user_name TEXT,
email_address TEXT,
first_name TEXT,
last_name TEXT,
roles TEXT ARRAY,
display_name TEXT,
sequence BIGINT,
PRIMARY KEY (user_id)
);
CREATE TABLE management.orgs (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
org_state SMALLINT,
sequence BIGINT,
domain TEXT,
name TEXT,
PRIMARY KEY (id)
);
CREATE TABLE management.org_members (
user_id TEXT,
org_id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
user_name TEXT,
email_address TEXT,
first_name TEXT,
last_name TEXT,
roles TEXT ARRAY,
display_name TEXT,
sequence BIGINT,
PRIMARY KEY (org_id, user_id)
);
CREATE TABLE auth.keys (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
private BOOLEAN,
expiry TIMESTAMP,
algorithm TEXT,
usage SMALLINT,
key JSONB,
sequence BIGINT,
PRIMARY KEY (id, private)
);
CREATE TABLE auth.applications (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
sequence BIGINT,
app_state SMALLINT,
resource_owner TEXT,
app_name TEXT,
project_id TEXT,
app_type SMALLINT,
is_oidc BOOLEAN,
oidc_client_id TEXT,
oidc_redirect_uris TEXT ARRAY,
oidc_response_types SMALLINT ARRAY,
oidc_grant_types SMALLINT ARRAY,
oidc_application_type SMALLINT,
oidc_auth_method_type SMALLINT,
oidc_post_logout_redirect_uris TEXT ARRAY,
PRIMARY KEY (id)
);
CREATE TABLE auth.user_grants (
id TEXT,
resource_owner TEXT,
project_id TEXT,
user_id TEXT,
org_name TEXT,
project_name TEXT,
user_name TEXT,
first_name TEXT,
last_name TEXT,
display_name TEXT,
email TEXT,
role_keys TEXT Array,
grant_id TEXT,
grant_state SMALLINT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
sequence BIGINT,
PRIMARY KEY (id)
);
CREATE TABLE auth.orgs (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
org_state SMALLINT,
sequence BIGINT,
domain TEXT,
name TEXT,
PRIMARY KEY (id)
);
CREATE TABLE authz.locks (
locker_id TEXT,
locked_until TIMESTAMP,
view_name TEXT,
PRIMARY KEY (view_name)
);
CREATE TABLE authz.current_sequences (
view_name TEXT,
timestamp TIMESTAMP,
current_sequence BIGINT,
PRIMARY KEY (view_name)
);
CREATE TABLE authz.failed_events (
view_name TEXT,
failed_sequence BIGINT,
failure_count SMALLINT,
err_msg TEXT,
PRIMARY KEY (view_name, failed_sequence)
);
CREATE TABLE authz.user_grants (
id TEXT,
resource_owner TEXT,
project_id TEXT,
user_id TEXT,
org_name TEXT,
project_name TEXT,
user_name TEXT,
first_name TEXT,
last_name TEXT,
display_name TEXT,
email TEXT,
role_keys TEXT Array,
grant_id TEXT,
grant_state SMALLINT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
sequence BIGINT,
PRIMARY KEY (id)
);
CREATE TABLE authz.applications (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
sequence BIGINT,
app_state SMALLINT,
resource_owner TEXT,
app_name TEXT,
project_id TEXT,
app_type SMALLINT,
is_oidc BOOLEAN,
oidc_client_id TEXT,
oidc_redirect_uris TEXT ARRAY,
oidc_response_types SMALLINT ARRAY,
oidc_grant_types SMALLINT ARRAY,
oidc_application_type SMALLINT,
oidc_auth_method_type SMALLINT,
oidc_post_logout_redirect_uris TEXT ARRAY,
PRIMARY KEY (id)
);
CREATE TABLE authz.orgs (
id TEXT,
creation_date TIMESTAMP,
change_date TIMESTAMP,
resource_owner TEXT,
org_state SMALLINT,
sequence BIGINT,
domain TEXT,
name TEXT,
PRIMARY KEY (id)
);

View File

@ -1,15 +0,0 @@
CREATE TABLE management.user_memberships (
user_id TEXT,
member_type SMALLINT,
aggregate_id TEXT,
object_id TEXT,
roles TEXT ARRAY,
display_name TEXT,
resource_owner TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
PRIMARY KEY (user_id, member_type, aggregate_id, object_id)
);

View File

@ -1,14 +0,0 @@
ALTER TABLE management.applications ADD COLUMN oidc_version SMALLINT;
ALTER TABLE management.applications ADD COLUMN none_compliant BOOLEAN;
ALTER TABLE management.applications ADD COLUMN compliance_problems TEXT ARRAY;
ALTER TABLE management.applications ADD COLUMN dev_mode BOOLEAN;
ALTER TABLE auth.applications ADD COLUMN oidc_version SMALLINT;
ALTER TABLE auth.applications ADD COLUMN none_compliant BOOLEAN;
ALTER TABLE auth.applications ADD COLUMN compliance_problems TEXT ARRAY;
ALTER TABLE auth.applications ADD COLUMN dev_mode BOOLEAN;
ALTER TABLE authz.applications ADD COLUMN oidc_version SMALLINT;
ALTER TABLE authz.applications ADD COLUMN none_compliant BOOLEAN;
ALTER TABLE authz.applications ADD COLUMN compliance_problems TEXT ARRAY;
ALTER TABLE authz.applications ADD COLUMN dev_mode BOOLEAN;

View File

@ -1,40 +0,0 @@
ALTER TABLE management.org_domains ADD COLUMN validation_type SMALLINT;
CREATE TABLE adminapi.users (
id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
resource_owner TEXT,
user_state SMALLINT,
last_login TIMESTAMPTZ,
password_change TIMESTAMPTZ,
user_name TEXT,
login_names TEXT ARRAY,
preferred_login_name TEXT,
first_name TEXT,
last_name TEXT,
nick_Name TEXT,
display_name TEXT,
preferred_language TEXT,
gender SMALLINT,
email TEXT,
is_email_verified BOOLEAN,
phone TEXT,
is_phone_verified BOOLEAN,
country TEXT,
locality TEXT,
postal_code TEXT,
region TEXT,
street_address TEXT,
otp_state SMALLINT,
sequence BIGINT,
password_set BOOLEAN,
password_change_required BOOLEAN,
mfa_max_set_up SMALLINT,
mfa_init_skipped TIMESTAMPTZ,
init_required BOOLEAN,
PRIMARY KEY (id)
);

View File

@ -1,11 +0,0 @@
ALTER TABLE management.applications ADD COLUMN origin_allow_list TEXT ARRAY;
ALTER TABLE auth.applications ADD COLUMN origin_allow_list TEXT ARRAY;
ALTER TABLE authz.applications ADD COLUMN origin_allow_list TEXT ARRAY;
DELETE FROM management.applications;
DELETE FROM auth.applications;
DELETE FROM authz.applications;
UPDATE management.current_sequences set current_sequence = 0 where view_name = 'management.applications';
UPDATE auth.current_sequences set current_sequence = 0 where view_name = 'auth.applications';
UPDATE authz.current_sequences set current_sequence = 0 where view_name = 'authz.applications';

View File

@ -1,104 +0,0 @@
CREATE TABLE adminapi.idp_configs (
idp_config_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
aggregate_id TEXT,
name TEXT,
logo_src BYTES,
idp_state SMALLINT,
idp_provider_type SMALLINT,
is_oidc BOOLEAN,
oidc_client_id TEXT,
oidc_client_secret JSONB,
oidc_issuer TEXT,
oidc_scopes TEXT ARRAY,
PRIMARY KEY (idp_config_id)
);
CREATE TABLE management.idp_configs (
idp_config_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
aggregate_id TEXT,
name TEXT,
logo_src BYTES,
idp_state SMALLINT,
idp_provider_type SMALLINT,
is_oidc BOOLEAN,
oidc_client_id TEXT,
oidc_client_secret JSONB,
oidc_issuer TEXT,
oidc_scopes TEXT ARRAY,
PRIMARY KEY (idp_config_id)
);
CREATE TABLE adminapi.login_policies (
aggregate_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
login_policy_state SMALLINT,
sequence BIGINT,
allow_register BOOLEAN,
allow_username_password BOOLEAN,
allow_external_idp BOOLEAN,
PRIMARY KEY (aggregate_id)
);
CREATE TABLE management.login_policies (
aggregate_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
login_policy_state SMALLINT,
sequence BIGINT,
allow_register BOOLEAN,
allow_username_password BOOLEAN,
allow_external_idp BOOLEAN,
PRIMARY KEY (aggregate_id)
);
CREATE TABLE adminapi.idp_providers (
aggregate_id TEXT,
idp_config_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
name string,
idp_config_type SMALLINT,
idp_provider_type SMALLINT,
PRIMARY KEY (aggregate_id, idp_config_id)
);
CREATE TABLE management.idp_providers (
aggregate_id TEXT,
idp_config_id TEXT,
creation_date TIMESTAMPTZ,
change_date TIMESTAMPTZ,
sequence BIGINT,
name string,
idp_config_type SMALLINT,
idp_provider_type SMALLINT,
PRIMARY KEY (aggregate_id, idp_config_id)
);

View File

@ -1,3 +0,0 @@
ALTER TABLE management.users ADD COLUMN username_change_required BOOLEAN;
ALTER TABLE auth.users ADD COLUMN username_change_required BOOLEAN;
ALTER TABLE adminapi.users ADD COLUMN username_change_required BOOLEAN;

View File

@ -1 +0,0 @@
ALTER TABLE auth.tokens ADD COLUMN preferred_language TEXT;

View File

@ -1,5 +0,0 @@
//+build ignore
package migrations
//go:generate flyway -url=jdbc:postgresql://localhost:26257/defaultdb -user=root -password= -locations=filesystem:./ clean

View File

@ -1,5 +0,0 @@
//+build ignore
package migrations
//go:generate flyway -url=jdbc:sqlite:/Users/silvanreusser/go/src/github.com/caos/zitadel/.local/zitadel.db -user=admin -password= -schemas=eventstore, -locations=filesystem:./ migrate