@shortlink-org/portolan 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -205
- package/cli/init.mjs +285 -0
- package/cli/init.test.mjs +158 -0
- package/cli/portolan.mjs +37 -73
- package/index.html +19 -0
- package/package.json +5 -10
- package/plugins/README.md +66 -27
- package/plugins/portolan-go.wasm +0 -0
- package/portolan.json +52 -73
- package/public/landing/cats/bug-hunter.webp +0 -0
- package/public/landing/cats/compass-nap.webp +0 -0
- package/public/landing/cats/diagrammer.webp +0 -0
- package/public/landing/cats/docs-reader.webp +0 -0
- package/public/landing/cats/laptop.webp +0 -0
- package/public/landing/cats/map-inspector.webp +0 -0
- package/public/landing/cats/server-break.webp +0 -0
- package/public/landing/cats/star-mapper.webp +0 -0
- package/public/landing/cats/system-builder.webp +0 -0
- package/public/landing/cats/thread-tangle.webp +0 -0
- package/public/og.png +0 -0
- package/public/readme-header.webp +0 -0
- package/schema/portolan.schema.json +180 -0
- package/scripts/builtin-plugins.mjs +14 -0
- package/scripts/delivery-presets.mjs +353 -0
- package/scripts/gen.mjs +37 -4
- package/scripts/history.mjs +126 -0
- package/scripts/history.test.mjs +110 -0
- package/scripts/host-plugins/fetch-bsr.mjs +351 -0
- package/{plugins/fetch-bsr/options.schema.json → scripts/host-plugins/fetch-bsr.options.json} +4 -0
- package/scripts/host-plugins/fetch-bsr.test.mjs +212 -0
- package/scripts/host-plugins/fetch-csr.mjs +386 -0
- package/scripts/host-plugins/fetch-csr.test.mjs +178 -0
- package/scripts/host-plugins/fetch-git.mjs +379 -0
- package/scripts/host-plugins/fetch-git.test.mjs +210 -0
- package/scripts/local-api.mjs +22 -4
- package/scripts/local-api.test.mjs +84 -2
- package/scripts/manifest.mjs +3 -2
- package/scripts/package-smoke.mjs +6 -2
- package/scripts/plugin-host.mjs +77 -18
- package/scripts/plugin-host.test.mjs +50 -1
- package/scripts/plugin-wasm-worker.mjs +6 -3
- package/scripts/run-builtin.mjs +6 -26
- package/scripts/schema.mjs +6 -1
- package/src/app/App.tsx +24 -429
- package/src/app/Breadcrumbs.test.ts +7 -0
- package/src/app/Breadcrumbs.tsx +15 -2
- package/src/app/CatalogApp.tsx +436 -0
- package/src/app/Sidebar.tsx +0 -1
- package/src/chat/ChatPanel.tsx +98 -41
- package/src/chat/Composer.tsx +4 -2
- package/src/chat/Conversation.tsx +79 -15
- package/src/chat/Header.tsx +43 -9
- package/src/chat/Starter.tsx +64 -3
- package/src/chat/Steps.tsx +1 -1
- package/src/chat/flags.test.ts +51 -14
- package/src/chat/flags.ts +8 -2
- package/src/chat/page-context.test.ts +51 -0
- package/src/chat/page-context.ts +128 -0
- package/src/chat/prompt.test.ts +49 -1
- package/src/chat/prompt.ts +42 -1
- package/src/chat/tools.ts +7 -2
- package/src/chat/transport.ts +16 -4
- package/src/components/ProblemRow.tsx +182 -0
- package/src/data.ts +20 -5
- package/src/er/ErCanvas.tsx +1 -1
- package/src/graph/DependencyGraph.tsx +10 -1
- package/src/graph/FocusedEventGraph.tsx +1 -1
- package/src/graph/GraphToolbar.tsx +2 -4
- package/src/index.css +220 -2
- package/src/landing/DraggableReveal.tsx +168 -0
- package/src/landing/EstateGraph.tsx +28 -0
- package/src/landing/FlowPlayback.tsx +282 -0
- package/src/landing/HeroMap.tsx +128 -0
- package/src/landing/LandingPage.tsx +757 -0
- package/src/landing/ProductFrame.tsx +68 -0
- package/src/landing/ProductTour.tsx +371 -0
- package/src/landing/catalog.ts +25 -0
- package/src/landing/motion.tsx +52 -0
- package/src/lib/all-problems.ts +28 -0
- package/src/lib/local-api.ts +35 -1
- package/src/lib/setup-info.test.ts +8 -0
- package/src/lib/setup-info.ts +3 -2
- package/src/lib/source-code.ts +2 -1
- package/src/likec4/C4View.tsx +5 -0
- package/src/likec4/InteractiveView.tsx +5 -1
- package/src/map/ContextMapGraph.tsx +47 -20
- package/src/pages/ContextMap.tsx +5 -1
- package/src/pages/FlowDetail.tsx +24 -7
- package/src/pages/Overview.tsx +68 -12
- package/src/pages/Problems.tsx +6 -193
- package/src/pages/Settings.tsx +133 -108
- package/src/pages/settings/DeliverySettings.tsx +229 -0
- package/src/pages/settings/PreferencesSettings.tsx +101 -0
- package/src/routes.test.ts +20 -0
- package/src/routes.ts +13 -1
- package/vite.config.ts +12 -8
- package/catalog/enum_test.go +0 -46
- package/catalog/model.go +0 -932
- package/catalog/roundtrip_test.go +0 -185
- package/catalog/via_test.go +0 -38
- package/go.mod +0 -14
- package/go.sum +0 -14
- package/internal/commands/cargo.go +0 -154
- package/internal/commands/commands.go +0 -143
- package/internal/commands/commands_test.go +0 -323
- package/internal/commands/gradle.go +0 -77
- package/internal/commands/justfile.go +0 -82
- package/internal/commands/makefile.go +0 -106
- package/internal/commands/maven.go +0 -93
- package/internal/commands/packagejson.go +0 -159
- package/internal/commands/pyproject.go +0 -169
- package/internal/commands/taskfile.go +0 -101
- package/internal/commands/testdata/estate/.cargo/config.toml +0 -7
- package/internal/commands/testdata/estate/Makefile +0 -33
- package/internal/commands/testdata/estate/Taskfile.yml +0 -21
- package/internal/commands/testdata/estate/build.gradle.kts +0 -21
- package/internal/commands/testdata/estate/justfile +0 -20
- package/internal/commands/testdata/estate/package.json +0 -13
- package/internal/commands/testdata/estate/pom.xml +0 -29
- package/internal/commands/testdata/estate/pyproject.toml +0 -27
- package/internal/commands/testdata/estate/xtask/src/main.rs +0 -27
- package/internal/commands/testdata/golden/commands.json +0 -305
- package/internal/gohttp/analyze.go +0 -2500
- package/internal/gohttp/endpoints.go +0 -1067
- package/internal/gohttp/roots.go +0 -320
- package/internal/gohttp/typed.go +0 -143
- package/internal/goscan/constants.go +0 -85
- package/internal/goscan/goscan_test.go +0 -227
- package/internal/goscan/names.go +0 -52
- package/internal/goscan/parse_test.go +0 -11
- package/internal/goscan/source.go +0 -36
- package/internal/goscan/tree.go +0 -155
- package/internal/goscan/types.go +0 -99
- package/internal/wsdl/ids.go +0 -127
- package/internal/wsdl/ids_test.go +0 -21
- package/internal/wsdl/model.go +0 -62
- package/internal/wsdl/parse.go +0 -920
- package/internal/wsdl/parse_test.go +0 -133
- package/plugin/describe.go +0 -107
- package/plugin/describe_test.go +0 -114
- package/plugin/protocol.go +0 -117
- package/plugin/schematest/schematest.go +0 -126
- package/plugins/extract-adr/describe.go +0 -19
- package/plugins/extract-adr/describe_test.go +0 -11
- package/plugins/extract-adr/extract.go +0 -153
- package/plugins/extract-adr/extract_test.go +0 -350
- package/plugins/extract-adr/history.go +0 -99
- package/plugins/extract-adr/main.go +0 -65
- package/plugins/extract-adr/parse.go +0 -642
- package/plugins/extract-adr/parse_test.go +0 -405
- package/plugins/extract-asyncapi/describe.go +0 -19
- package/plugins/extract-asyncapi/describe_test.go +0 -11
- package/plugins/extract-asyncapi/extract.go +0 -315
- package/plugins/extract-asyncapi/extract_test.go +0 -197
- package/plugins/extract-asyncapi/main.go +0 -48
- package/plugins/extract-asyncapi/spec.go +0 -151
- package/plugins/extract-commands/describe.go +0 -19
- package/plugins/extract-commands/describe_test.go +0 -11
- package/plugins/extract-commands/extract.go +0 -79
- package/plugins/extract-commands/extract_test.go +0 -92
- package/plugins/extract-commands/main.go +0 -55
- package/plugins/extract-csr/avro.go +0 -258
- package/plugins/extract-csr/describe.go +0 -19
- package/plugins/extract-csr/describe_test.go +0 -11
- package/plugins/extract-csr/extract.go +0 -338
- package/plugins/extract-csr/extract_test.go +0 -374
- package/plugins/extract-csr/jsonschema.go +0 -343
- package/plugins/extract-csr/lock.go +0 -25
- package/plugins/extract-csr/main.go +0 -84
- package/plugins/extract-csr/subject.go +0 -102
- package/plugins/extract-flows/describe.go +0 -19
- package/plugins/extract-flows/describe_test.go +0 -11
- package/plugins/extract-flows/extract.go +0 -91
- package/plugins/extract-flows/main.go +0 -45
- package/plugins/extract-flows/parse.go +0 -593
- package/plugins/extract-flows/parse_test.go +0 -204
- package/plugins/extract-glossary/describe.go +0 -19
- package/plugins/extract-glossary/describe_test.go +0 -11
- package/plugins/extract-glossary/extract.go +0 -115
- package/plugins/extract-glossary/extract_test.go +0 -220
- package/plugins/extract-glossary/main.go +0 -59
- package/plugins/extract-glossary/parse.go +0 -214
- package/plugins/extract-glossary/parse_test.go +0 -203
- package/plugins/extract-go/aggregate.go +0 -214
- package/plugins/extract-go/client.go +0 -409
- package/plugins/extract-go/client_test.go +0 -266
- package/plugins/extract-go/describe.go +0 -19
- package/plugins/extract-go/describe_test.go +0 -11
- package/plugins/extract-go/enum.go +0 -195
- package/plugins/extract-go/enum_test.go +0 -82
- package/plugins/extract-go/event.go +0 -99
- package/plugins/extract-go/extract.go +0 -191
- package/plugins/extract-go/extract_test.go +0 -261
- package/plugins/extract-go/flow.go +0 -1441
- package/plugins/extract-go/flow_test.go +0 -609
- package/plugins/extract-go/httpclient.go +0 -174
- package/plugins/extract-go/httpclient_test.go +0 -296
- package/plugins/extract-go/ids.go +0 -92
- package/plugins/extract-go/layout.go +0 -225
- package/plugins/extract-go/layout_test.go +0 -125
- package/plugins/extract-go/lifecycle.go +0 -324
- package/plugins/extract-go/lifecycle_test.go +0 -108
- package/plugins/extract-go/main.go +0 -79
- package/plugins/extract-go/operation.go +0 -157
- package/plugins/extract-go/source.go +0 -316
- package/plugins/extract-go/transport.go +0 -321
- package/plugins/extract-go/transport_test.go +0 -145
- package/plugins/extract-go/wiring.go +0 -434
- package/plugins/extract-go-nats/describe.go +0 -19
- package/plugins/extract-go-nats/describe_test.go +0 -11
- package/plugins/extract-go-nats/extract.go +0 -177
- package/plugins/extract-go-nats/extract_test.go +0 -389
- package/plugins/extract-go-nats/index.go +0 -379
- package/plugins/extract-go-nats/main.go +0 -42
- package/plugins/extract-go-nats/resolve.go +0 -161
- package/plugins/extract-go-nats/sites.go +0 -224
- package/plugins/extract-graphql/describe.go +0 -19
- package/plugins/extract-graphql/describe_test.go +0 -11
- package/plugins/extract-graphql/extract.go +0 -433
- package/plugins/extract-graphql/extract_test.go +0 -256
- package/plugins/extract-graphql/ids.go +0 -49
- package/plugins/extract-graphql/lex.go +0 -237
- package/plugins/extract-graphql/main.go +0 -51
- package/plugins/extract-graphql/parse.go +0 -621
- package/plugins/extract-graphql/parse_test.go +0 -122
- package/plugins/extract-http-clients/describe.go +0 -19
- package/plugins/extract-http-clients/describe_test.go +0 -11
- package/plugins/extract-http-clients/extract.go +0 -705
- package/plugins/extract-http-clients/extract_test.go +0 -1263
- package/plugins/extract-http-clients/main.go +0 -42
- package/plugins/extract-openapi/describe.go +0 -19
- package/plugins/extract-openapi/describe_test.go +0 -11
- package/plugins/extract-openapi/discover.go +0 -243
- package/plugins/extract-openapi/extract.go +0 -526
- package/plugins/extract-openapi/extract_test.go +0 -545
- package/plugins/extract-openapi/main.go +0 -75
- package/plugins/extract-openapi/spec.go +0 -350
- package/plugins/extract-project/describe.go +0 -19
- package/plugins/extract-project/describe_test.go +0 -11
- package/plugins/extract-project/extract.go +0 -221
- package/plugins/extract-project/extract_test.go +0 -109
- package/plugins/extract-project/main.go +0 -41
- package/plugins/extract-proto/ast.go +0 -125
- package/plugins/extract-proto/consumes.go +0 -77
- package/plugins/extract-proto/describe.go +0 -19
- package/plugins/extract-proto/extract.go +0 -293
- package/plugins/extract-proto/extract_test.go +0 -459
- package/plugins/extract-proto/ids.go +0 -89
- package/plugins/extract-proto/ids_test.go +0 -57
- package/plugins/extract-proto/lex.go +0 -285
- package/plugins/extract-proto/main.go +0 -100
- package/plugins/extract-proto/module.go +0 -120
- package/plugins/extract-proto/parse.go +0 -720
- package/plugins/extract-proto/parse_test.go +0 -307
- package/plugins/extract-proto/provides.go +0 -236
- package/plugins/extract-proto/resolve.go +0 -222
- package/plugins/extract-proto/resolve_test.go +0 -119
- package/plugins/extract-redis/describe.go +0 -19
- package/plugins/extract-redis/describe_test.go +0 -11
- package/plugins/extract-redis/extract.go +0 -183
- package/plugins/extract-redis/extract_test.go +0 -168
- package/plugins/extract-redis/keyspaces.go +0 -469
- package/plugins/extract-redis/main.go +0 -44
- package/plugins/extract-river/describe.go +0 -19
- package/plugins/extract-river/describe_test.go +0 -11
- package/plugins/extract-river/extract.go +0 -507
- package/plugins/extract-river/extract_test.go +0 -132
- package/plugins/extract-river/main.go +0 -42
- package/plugins/extract-sql/ddl.go +0 -893
- package/plugins/extract-sql/ddl_test.go +0 -401
- package/plugins/extract-sql/describe.go +0 -19
- package/plugins/extract-sql/describe_test.go +0 -11
- package/plugins/extract-sql/layout.go +0 -221
- package/plugins/extract-sql/layout_test.go +0 -55
- package/plugins/extract-sql/lineage.go +0 -107
- package/plugins/extract-sql/main.go +0 -141
- package/plugins/extract-sql/maps.go +0 -564
- package/plugins/extract-sql/maps_java.go +0 -117
- package/plugins/extract-sql/maps_rust.go +0 -333
- package/plugins/extract-sql/maps_rust_test.go +0 -70
- package/plugins/extract-sql/maps_test.go +0 -204
- package/plugins/extract-sql/maps_ts.go +0 -398
- package/plugins/extract-sql/maps_ts_test.go +0 -136
- package/plugins/extract-sql/projection.go +0 -70
- package/plugins/extract-sql/projection_test.go +0 -50
- package/plugins/extract-sql/store.go +0 -420
- package/plugins/extract-sql/store_test.go +0 -233
- package/plugins/extract-sql/view.go +0 -295
- package/plugins/extract-watermill/describe.go +0 -19
- package/plugins/extract-watermill/describe_test.go +0 -11
- package/plugins/extract-watermill/extract.go +0 -1228
- package/plugins/extract-watermill/extract_test.go +0 -234
- package/plugins/extract-watermill/main.go +0 -41
- package/plugins/extract-wsdl/describe.go +0 -19
- package/plugins/extract-wsdl/describe_test.go +0 -11
- package/plugins/extract-wsdl/extract.go +0 -148
- package/plugins/extract-wsdl/extract_test.go +0 -45
- package/plugins/extract-wsdl/main.go +0 -53
- package/plugins/fetch-bsr/auth.go +0 -114
- package/plugins/fetch-bsr/bsr.go +0 -240
- package/plugins/fetch-bsr/cache.go +0 -66
- package/plugins/fetch-bsr/describe.go +0 -19
- package/plugins/fetch-bsr/fetch.go +0 -192
- package/plugins/fetch-bsr/fetch_test.go +0 -465
- package/plugins/fetch-bsr/lock.go +0 -71
- package/plugins/fetch-bsr/main.go +0 -117
- package/plugins/fetch-csr/auth.go +0 -95
- package/plugins/fetch-csr/cache.go +0 -69
- package/plugins/fetch-csr/describe.go +0 -19
- package/plugins/fetch-csr/describe_test.go +0 -11
- package/plugins/fetch-csr/fetch.go +0 -254
- package/plugins/fetch-csr/fetch_test.go +0 -494
- package/plugins/fetch-csr/lock.go +0 -95
- package/plugins/fetch-csr/main.go +0 -122
- package/plugins/fetch-csr/registry.go +0 -209
- package/plugins/fetch-git/cache.go +0 -65
- package/plugins/fetch-git/describe.go +0 -19
- package/plugins/fetch-git/describe_test.go +0 -11
- package/plugins/fetch-git/fetch.go +0 -181
- package/plugins/fetch-git/fetch_test.go +0 -332
- package/plugins/fetch-git/git.go +0 -169
- package/plugins/fetch-git/lock.go +0 -72
- package/plugins/fetch-git/main.go +0 -127
- package/plugins/fetch-git/offline.go +0 -39
- package/plugins/fetch-git/pin.go +0 -90
- package/plugins/fetch-git/pin_test.go +0 -74
- package/plugins/gen-backstage/describe.go +0 -17
- package/plugins/gen-backstage/main.go +0 -22
- package/plugins/gen-backstage/plugin.go +0 -473
- package/plugins/gen-backstage/plugin_test.go +0 -145
- package/plugins/gen-backstage.wasm +0 -0
- package/plugins/gen-markdown/adr.go +0 -162
- package/plugins/gen-markdown/aggregate.go +0 -362
- package/plugins/gen-markdown/canonical.go +0 -93
- package/plugins/gen-markdown/context.go +0 -90
- package/plugins/gen-markdown/coverage_test.go +0 -89
- package/plugins/gen-markdown/describe.go +0 -19
- package/plugins/gen-markdown/describe_test.go +0 -11
- package/plugins/gen-markdown/external.go +0 -71
- package/plugins/gen-markdown/flow.go +0 -277
- package/plugins/gen-markdown/glossary.go +0 -76
- package/plugins/gen-markdown/glossary_test.go +0 -148
- package/plugins/gen-markdown/llms.go +0 -302
- package/plugins/gen-markdown/main.go +0 -22
- package/plugins/gen-markdown/markdown.go +0 -254
- package/plugins/gen-markdown/markdown_test.go +0 -100
- package/plugins/gen-markdown/module.go +0 -107
- package/plugins/gen-markdown/plugin.go +0 -39
- package/plugins/gen-markdown/quality_test.go +0 -176
- package/plugins/gen-markdown/redis_test.go +0 -38
- package/plugins/gen-markdown/render.go +0 -344
- package/plugins/gen-markdown/render_test.go +0 -186
- package/plugins/gen-markdown/service.go +0 -456
- package/plugins/gen-markdown/source.go +0 -177
- package/plugins/gen-markdown/store.go +0 -201
- package/plugins/gen-markdown.wasm +0 -0
- package/plugins/gen-mermaid/describe.go +0 -17
- package/plugins/gen-mermaid/main.go +0 -22
- package/plugins/gen-mermaid/plugin.go +0 -104
- package/plugins/gen-mermaid/plugin_test.go +0 -33
- package/plugins/gen-mermaid.wasm +0 -0
- package/plugins/openapi/ids.go +0 -261
- package/plugins/openapi/ids_test.go +0 -98
- package/plugins/verify-codeowners/describe.go +0 -19
- package/plugins/verify-codeowners/describe_test.go +0 -11
- package/plugins/verify-codeowners/main.go +0 -75
- package/plugins/verify-codeowners/match.go +0 -85
- package/plugins/verify-codeowners/match_test.go +0 -47
- package/plugins/verify-codeowners/owners.go +0 -164
- package/plugins/verify-codeowners/owners_test.go +0 -225
- package/plugins/verify-codeowners/parse.go +0 -90
- package/plugins/verify-codeowners/parse_test.go +0 -62
- package/plugins/verify-otel/describe.go +0 -19
- package/plugins/verify-otel/describe_test.go +0 -11
- package/plugins/verify-otel/main.go +0 -53
- package/plugins/verify-otel/match.go +0 -336
- package/plugins/verify-otel/otlp.go +0 -200
- package/plugins/verify-otel/verify.go +0 -734
- package/plugins/verify-otel/verify_test.go +0 -460
- /package/{plugins/fetch-csr/options.schema.json → scripts/host-plugins/fetch-csr.options.json} +0 -0
- /package/{plugins/fetch-git/options.schema.json → scripts/host-plugins/fetch-git.options.json} +0 -0
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
package main
|
|
2
|
-
|
|
3
|
-
// Reading a view.
|
|
4
|
-
//
|
|
5
|
-
// A view is kept apart from a table rather than folded in behind a flag: it has
|
|
6
|
-
// no key, no constraints and no rows of its own, and what it has instead is
|
|
7
|
-
// what it reads. So this reads the select: which relations it draws from, what
|
|
8
|
-
// each output column is called, and - the part a table cannot say - which
|
|
9
|
-
// column each one was computed from.
|
|
10
|
-
//
|
|
11
|
-
// The type of a column is not in the statement, because a view does not declare
|
|
12
|
-
// one. It is taken from the column it is computed from when there is exactly
|
|
13
|
-
// one; a column summed, coalesced or joined out of several says nothing and is
|
|
14
|
-
// left blank rather than guessed at.
|
|
15
|
-
|
|
16
|
-
import (
|
|
17
|
-
"strings"
|
|
18
|
-
|
|
19
|
-
"github.com/pgplex/pgparser/nodes"
|
|
20
|
-
|
|
21
|
-
"github.com/shortlink-org/portolan/catalog"
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
// view is what one CREATE VIEW says, before the store turns names into ids.
|
|
25
|
-
type view struct {
|
|
26
|
-
name string
|
|
27
|
-
doc string
|
|
28
|
-
// materialized: the database keeps the rows rather than recomputing them,
|
|
29
|
-
// which means they can be stale. A reader has to know that before believing
|
|
30
|
-
// one, so it is carried rather than inferred from the name.
|
|
31
|
-
materialized bool
|
|
32
|
-
// reads names the relations of the FROM clause, in the order written.
|
|
33
|
-
reads []string
|
|
34
|
-
// columns, in the order the select lists them.
|
|
35
|
-
columns []viewColumn
|
|
36
|
-
// definition is the statement as it was written.
|
|
37
|
-
definition string
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
type viewColumn struct {
|
|
41
|
-
name string
|
|
42
|
-
// from is "<relation>.<column>" for every column this one is computed from.
|
|
43
|
-
from []string
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
func readView(stmt *nodes.ViewStmt, sql string) view {
|
|
47
|
-
return selectInto(relationName(stmt.View), stmt.Query, false, sql)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// readMaterializedView reads the other spelling. The grammar calls it a CREATE
|
|
51
|
-
// TABLE AS whose object type is a matview, because that is what it is: a query
|
|
52
|
-
// whose rows are kept.
|
|
53
|
-
func readMaterializedView(stmt *nodes.CreateTableAsStmt, sql string) (view, bool) {
|
|
54
|
-
if stmt.Objtype != nodes.OBJECT_MATVIEW || stmt.Into == nil || stmt.Into.Rel == nil {
|
|
55
|
-
return view{}, false
|
|
56
|
-
}
|
|
57
|
-
query := stmt.Query
|
|
58
|
-
if query == nil {
|
|
59
|
-
query = stmt.Into.ViewQuery
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return selectInto(relationName(stmt.Into.Rel), query, true, sql), true
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
func selectInto(name string, node nodes.Node, materialized bool, sql string) view {
|
|
66
|
-
out := view{name: name, materialized: materialized}
|
|
67
|
-
|
|
68
|
-
query, ok := node.(*nodes.SelectStmt)
|
|
69
|
-
if !ok {
|
|
70
|
-
return out
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// alias -> relation, so `j.id` can be read as a column of journal_entries.
|
|
74
|
-
relations := map[string]string{}
|
|
75
|
-
readFrom(query.FromClause, relations, &out.reads)
|
|
76
|
-
|
|
77
|
-
for _, item := range items(query.TargetList) {
|
|
78
|
-
target, ok := item.(*nodes.ResTarget)
|
|
79
|
-
if !ok {
|
|
80
|
-
continue
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
var sources []string
|
|
84
|
-
columnRefs(target.Val, relations, &sources)
|
|
85
|
-
|
|
86
|
-
name := target.Name
|
|
87
|
-
if name == "" && len(sources) == 1 {
|
|
88
|
-
// `SELECT j.state` names its column after the column it takes.
|
|
89
|
-
name = sources[0][strings.LastIndex(sources[0], ".")+1:]
|
|
90
|
-
}
|
|
91
|
-
if name == "" {
|
|
92
|
-
continue
|
|
93
|
-
}
|
|
94
|
-
out.columns = append(out.columns, viewColumn{name: name, from: sources})
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
out.definition = definitionOf(sql, out.name, materialized)
|
|
98
|
-
|
|
99
|
-
return out
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// readFrom walks the FROM clause, which is a tree once anything is joined.
|
|
103
|
-
func readFrom(list *nodes.List, relations map[string]string, reads *[]string) {
|
|
104
|
-
for _, item := range items(list) {
|
|
105
|
-
readFromItem(item, relations, reads)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
func readFromItem(item nodes.Node, relations map[string]string, reads *[]string) {
|
|
110
|
-
switch node := item.(type) {
|
|
111
|
-
case *nodes.RangeVar:
|
|
112
|
-
name := relationName(node)
|
|
113
|
-
relations[node.Relname] = name
|
|
114
|
-
relations[name] = name
|
|
115
|
-
if node.Alias != nil && node.Alias.Aliasname != "" {
|
|
116
|
-
relations[node.Alias.Aliasname] = name
|
|
117
|
-
}
|
|
118
|
-
*reads = append(*reads, name)
|
|
119
|
-
|
|
120
|
-
case *nodes.JoinExpr:
|
|
121
|
-
readFromItem(node.Larg, relations, reads)
|
|
122
|
-
readFromItem(node.Rarg, relations, reads)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// columnRefs collects every column an expression reaches, however deep: a sum
|
|
127
|
-
// of a coalesce of a column is still that column's value arriving here.
|
|
128
|
-
func columnRefs(node nodes.Node, relations map[string]string, into *[]string) {
|
|
129
|
-
switch expression := node.(type) {
|
|
130
|
-
case *nodes.ColumnRef:
|
|
131
|
-
fields := stringList(expression.Fields)
|
|
132
|
-
if len(fields) == 0 {
|
|
133
|
-
return
|
|
134
|
-
}
|
|
135
|
-
column := fields[len(fields)-1]
|
|
136
|
-
relation := ""
|
|
137
|
-
if len(fields) > 1 {
|
|
138
|
-
relation = relations[fields[len(fields)-2]]
|
|
139
|
-
} else {
|
|
140
|
-
// A qualified relation has two lookup keys (base name and full
|
|
141
|
-
// name), but it is still only one FROM source.
|
|
142
|
-
for _, candidate := range relations {
|
|
143
|
-
if relation == "" {
|
|
144
|
-
relation = candidate
|
|
145
|
-
} else if relation != candidate {
|
|
146
|
-
relation = ""
|
|
147
|
-
break
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
if relation == "" || column == "*" {
|
|
152
|
-
return
|
|
153
|
-
}
|
|
154
|
-
*into = append(*into, relation+"."+column)
|
|
155
|
-
|
|
156
|
-
case *nodes.FuncCall:
|
|
157
|
-
for _, argument := range items(expression.Args) {
|
|
158
|
-
columnRefs(argument, relations, into)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
case *nodes.CoalesceExpr:
|
|
162
|
-
for _, argument := range items(expression.Args) {
|
|
163
|
-
columnRefs(argument, relations, into)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
case *nodes.A_Expr:
|
|
167
|
-
columnRefs(expression.Lexpr, relations, into)
|
|
168
|
-
columnRefs(expression.Rexpr, relations, into)
|
|
169
|
-
|
|
170
|
-
case *nodes.TypeCast:
|
|
171
|
-
columnRefs(expression.Arg, relations, into)
|
|
172
|
-
|
|
173
|
-
case *nodes.CaseExpr:
|
|
174
|
-
columnRefs(expression.Arg, relations, into)
|
|
175
|
-
for _, when := range items(expression.Args) {
|
|
176
|
-
if clause, ok := when.(*nodes.CaseWhen); ok {
|
|
177
|
-
columnRefs(clause.Expr, relations, into)
|
|
178
|
-
columnRefs(clause.Result, relations, into)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
columnRefs(expression.Defresult, relations, into)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// definitionOf cuts the statement out of the file it was read from.
|
|
186
|
-
//
|
|
187
|
-
// The parse tree is not printed back: a reader comparing the page to the
|
|
188
|
-
// migration wants the SQL somebody wrote, down to the line breaks they chose.
|
|
189
|
-
func definitionOf(sql, name string, materialized bool) string {
|
|
190
|
-
lower := strings.ToLower(sql)
|
|
191
|
-
opening := "create view "
|
|
192
|
-
if materialized {
|
|
193
|
-
opening = "create materialized view "
|
|
194
|
-
}
|
|
195
|
-
at := strings.Index(lower, opening+strings.ToLower(name))
|
|
196
|
-
if at < 0 {
|
|
197
|
-
at = strings.Index(lower, "create or replace view "+strings.ToLower(name))
|
|
198
|
-
}
|
|
199
|
-
if at < 0 {
|
|
200
|
-
return ""
|
|
201
|
-
}
|
|
202
|
-
end := strings.Index(sql[at:], ";")
|
|
203
|
-
if end < 0 {
|
|
204
|
-
return strings.TrimSpace(sql[at:])
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return strings.TrimSpace(sql[at : at+end+1])
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// asCatalog turns the names into ids, and takes what the statement does not
|
|
211
|
-
// say - a column's type, and whether it can be null - from the column it is
|
|
212
|
-
// computed from.
|
|
213
|
-
func (v view) asCatalog(storeID, source string, tables []catalog.Table) catalog.View {
|
|
214
|
-
out := catalog.View{
|
|
215
|
-
ID: storeID + "." + v.name,
|
|
216
|
-
Name: v.name,
|
|
217
|
-
Doc: v.doc,
|
|
218
|
-
Materialized: v.materialized,
|
|
219
|
-
Definition: v.definition,
|
|
220
|
-
Source: source,
|
|
221
|
-
}
|
|
222
|
-
for _, relation := range v.reads {
|
|
223
|
-
out.Reads = append(out.Reads, storeID+"."+relation)
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
for _, column := range v.columns {
|
|
227
|
-
held := catalog.Column{Name: column.name, Nullable: true}
|
|
228
|
-
for _, from := range column.from {
|
|
229
|
-
held.From = append(held.From, storeID+"."+from)
|
|
230
|
-
}
|
|
231
|
-
if len(column.from) == 1 {
|
|
232
|
-
at := strings.LastIndex(column.from[0], ".")
|
|
233
|
-
if at < 0 {
|
|
234
|
-
continue
|
|
235
|
-
}
|
|
236
|
-
relation, name := column.from[0][:at], column.from[0][at+1:]
|
|
237
|
-
if source := columnOf(tables, storeID+"."+relation, name); source != nil {
|
|
238
|
-
held.Type = source.Type
|
|
239
|
-
held.Nullable = source.Nullable
|
|
240
|
-
held.Maps = source.Maps
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
out.Columns = append(out.Columns, held)
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// What it holds is what the relation it is built on holds: a view over one
|
|
247
|
-
// aggregate's tables is another way of reading that aggregate, and a view
|
|
248
|
-
// that draws on several says nothing here rather than picking one.
|
|
249
|
-
persists := ""
|
|
250
|
-
for _, relation := range v.reads {
|
|
251
|
-
table := tableOf(tables, storeID+"."+relation)
|
|
252
|
-
if table == nil || table.Persists == nil {
|
|
253
|
-
continue
|
|
254
|
-
}
|
|
255
|
-
if persists == "" {
|
|
256
|
-
persists = table.Persists.Aggregate
|
|
257
|
-
|
|
258
|
-
continue
|
|
259
|
-
}
|
|
260
|
-
if persists != table.Persists.Aggregate {
|
|
261
|
-
persists = ""
|
|
262
|
-
|
|
263
|
-
break
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
if persists != "" {
|
|
267
|
-
out.Persists = &catalog.Persists{Aggregate: persists}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return out
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
func tableOf(tables []catalog.Table, id string) *catalog.Table {
|
|
274
|
-
for i := range tables {
|
|
275
|
-
if tables[i].ID == id {
|
|
276
|
-
return &tables[i]
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return nil
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
func columnOf(tables []catalog.Table, tableID, name string) *catalog.Column {
|
|
284
|
-
table := tableOf(tables, tableID)
|
|
285
|
-
if table == nil {
|
|
286
|
-
return nil
|
|
287
|
-
}
|
|
288
|
-
for i := range table.Columns {
|
|
289
|
-
if table.Columns[i].Name == name {
|
|
290
|
-
return &table.Columns[i]
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
return nil
|
|
295
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
package main
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
_ "embed"
|
|
5
|
-
|
|
6
|
-
"github.com/shortlink-org/portolan/plugin"
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
//go:embed options.schema.json
|
|
10
|
-
var optionsSchema []byte
|
|
11
|
-
|
|
12
|
-
func descriptor() plugin.Descriptor {
|
|
13
|
-
return plugin.Descriptor{
|
|
14
|
-
Name: "extract-watermill",
|
|
15
|
-
Summary: "Reads Watermill router and CQRS handlers plus publications into channels and source-backed message flows.",
|
|
16
|
-
Phases: []string{plugin.PhaseExtract},
|
|
17
|
-
Options: optionsSchema,
|
|
18
|
-
}
|
|
19
|
-
}
|