(Feat): Initial Commit
This commit is contained in:
11
docs/README.md
Normal file
11
docs/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# `/docs`
|
||||
|
||||
Design and user documents (in addition to your godoc generated documentation).
|
||||
|
||||
https://github.com/golang-standards/project-layout/tree/master/docs
|
||||
|
||||
Examples:
|
||||
|
||||
* https://github.com/gohugoio/hugo/tree/master/docs
|
||||
* https://github.com/openshift/origin/tree/master/docs
|
||||
* https://github.com/dapr/dapr/tree/master/docs
|
||||
1
docs/schemacrawler/.gitignore
vendored
Normal file
1
docs/schemacrawler/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
schema.*
|
||||
31
docs/schemacrawler/README.md
Normal file
31
docs/schemacrawler/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# `/docs/schemacrawler`
|
||||
|
||||
To locally (re-)generate a schemacrawler diagramm, execute any of the following commands from your **host** machine.
|
||||
|
||||
```bash
|
||||
# Note that the project must be already running within docker-compose (and the "spec" database should already be migrated via "make sql" or "make all").
|
||||
# First find out under which docker network the "allaboutapps.dev/aw/go-starter" project is available (as started via ./docker-helper.sh --up).
|
||||
# Typically it's "<dir_name>_default".
|
||||
docker network ls
|
||||
# [...]
|
||||
# go-starter_default
|
||||
|
||||
# Ensure you are within the /docs/schemacrawler directory
|
||||
cd docs/schemacrawler
|
||||
pwd
|
||||
# [...]/docs/schemacrawler
|
||||
|
||||
# Generate a png (exchange --network="..." with your docker network before executing this command)
|
||||
docker run --network=go-starter_default -v $(pwd):/home/schcrwlr/share -v $(pwd)/schemacrawler.config.properties:/opt/schemacrawler/config/schemacrawler.config.properties --entrypoint=/opt/schemacrawler/bin/schemacrawler.sh schemacrawler/schemacrawler --server=postgresql --host=postgres --port=5432 --database=spec --schemas=public --user=dbuser --password=dbpass --info-level=standard --command=schema --portable-names --title "allaboutapps.dev/aw/go-starter" --output-format=png --output-file=/home/schcrwlr/share/schema.png
|
||||
|
||||
# Generate a pdf (exchange --network="..." with your docker network before executing this command)
|
||||
docker run --network=go-starter_default -v $(pwd):/home/schcrwlr/share -v $(pwd)/schemacrawler.config.properties:/opt/schemacrawler/config/schemacrawler.config.properties --entrypoint=/opt/schemacrawler/bin/schemacrawler.sh schemacrawler/schemacrawler --server=postgresql --host=postgres --port=5432 --database=spec --schemas=public --user=dbuser --password=dbpass --info-level=standard --command=schema --portable-names --title "allaboutapps.dev/aw/go-starter" --output-format=pdf --output-file=/home/schcrwlr/share/schema.pdf
|
||||
|
||||
# Feel free to override schemacrawler configuration settings in "./schemacrawler.config.properties".
|
||||
```
|
||||
|
||||
For further information see:
|
||||
- Latest [Dockerfile](https://github.com/schemacrawler/SchemaCrawler/blob/master/schemacrawler-docker/Dockerfile) of schemacrawler
|
||||
- [SchemaCrawler Database Diagramming](https://www.schemacrawler.com/diagramming.html) (intro to most diagramming options)
|
||||
- [Docker Image for SchemaCrawler](https://www.schemacrawler.com/docker-image.html) (about running schemacrawler in Docker)
|
||||
- [DockerHub `schemacrawler/schemacrawler`](https://hub.docker.com/r/schemacrawler/schemacrawler/) (available version of this Docker image)
|
||||
181
docs/schemacrawler/schemacrawler.config.properties
Normal file
181
docs/schemacrawler/schemacrawler.config.properties
Normal file
@@ -0,0 +1,181 @@
|
||||
# --=----=----=----=----=----=----=----=----=----=----=----=----=----=----=----=
|
||||
# - SchemaCrawler: Configuration Options
|
||||
# --=----=----=----=----=----=----=----=----=----=----=----=----=----=----=----=
|
||||
#
|
||||
# - Metadata Retrieval Options
|
||||
# ------------------------------------------------------------------------------
|
||||
# - Override the metadata retrieval strategy
|
||||
# - This can affect speed, so they are commented out in order to use database
|
||||
# - specific defaults
|
||||
# - Default: Hard-coded into each database plugin, otherwise metadata
|
||||
# - Possible values for each property are metadata or data_dictionary_all
|
||||
#schemacrawler.schema.retrieval.strategy.typeinfo=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.tables=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.tablecolumns=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.primarykeys=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.indexes=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.foreignkeys=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.procedures=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.procedurecolumns=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.functions=metadata
|
||||
#schemacrawler.schema.retrieval.strategy.functioncolumns=metadata
|
||||
#
|
||||
# - Limit Options - inclusion rules for database objects
|
||||
# ------------------------------------------------------------------------------
|
||||
# - Regular expression schema pattern to filter
|
||||
# - schema names
|
||||
# - Default: .* for include, <none> for exclude
|
||||
# - IMPORTANT: Please uncomment the follow patterns only for
|
||||
# - database that support schemas. SQLite for example does
|
||||
# - not support schemas
|
||||
#schemacrawler.schema.pattern.include=.*
|
||||
#schemacrawler.schema.pattern.exclude=
|
||||
# - Regular expression table and column name pattern to filter table
|
||||
# - and column names
|
||||
# - Column regular expression to match fully qualified column names,
|
||||
# - in the form "CATALOGNAME.SCHEMANAME.TABLENAME.COLUMNNAME"
|
||||
# - Default: .* for include, <none> for exclude
|
||||
#schemacrawler.table.pattern.include=.*
|
||||
#schemacrawler.table.pattern.exclude=
|
||||
#schemacrawler.column.pattern.include=.*
|
||||
#schemacrawler.column.pattern.exclude=
|
||||
# - Regular expression routine and routine parameter name pattern to filter
|
||||
# - routine and routine parameter names
|
||||
# - Default: .* for include, <none> for exclude
|
||||
#schemacrawler.routine.pattern.include=
|
||||
#schemacrawler.routine.pattern.exclude=.*
|
||||
#schemacrawler.routine.inout.pattern.include=.*
|
||||
#schemacrawler.routine.inout.pattern.exclude=
|
||||
# - Regular expression synonym pattern to filter
|
||||
# - synonym names
|
||||
# - Default: <none> for include, .* for exclude
|
||||
#schemacrawler.synonym.pattern.include=
|
||||
#schemacrawler.synonym.pattern.exclude=.*
|
||||
# - Regular expression sequence pattern to filter
|
||||
# - sequence names
|
||||
# - Default: <none> for include, .* for exclude
|
||||
#schemacrawler.sequence.pattern.include=
|
||||
#schemacrawler.sequence.pattern.exclude=.*
|
||||
#
|
||||
# - Grep Options - inclusion rules
|
||||
# ------------------------------------------------------------------------------
|
||||
# - Include patterns for table columns
|
||||
# - Default: .* for include, <none> for exclude
|
||||
#schemacrawler.grep.column.pattern.include=.*
|
||||
#schemacrawler.grep.column.pattern.exclude=
|
||||
# - Include patterns for routine parameters
|
||||
# - Default: .* for include, <none> for exclude
|
||||
#schemacrawler.grep.routine.inout.pattern.include=.*
|
||||
#schemacrawler.grep.routine.inout.pattern.exclude=
|
||||
# - Include patterns for table and routine definitions
|
||||
# - Default: .* for include, <none> for exclude
|
||||
#schemacrawler.grep.definition.pattern.include=.*
|
||||
#schemacrawler.grep.definition.pattern.exclude=
|
||||
#
|
||||
# - Sorting Options
|
||||
# ------------------------------------------------------------------------------
|
||||
# - Sort orders for objects
|
||||
#schemacrawler.format.sort_alphabetically.tables=true
|
||||
#schemacrawler.format.sort_alphabetically.table_columns=false
|
||||
#schemacrawler.format.sort_alphabetically.table_foreignkeys=false
|
||||
#schemacrawler.format.sort_alphabetically.table_indexes=false
|
||||
#schemacrawler.format.sort_alphabetically.routines=true
|
||||
#schemacrawler.format.sort_alphabetically.routine_columns=false
|
||||
#
|
||||
# - Show Options - text output formatting
|
||||
# ------------------------------------------------------------------------------
|
||||
# - Controls generation of the SchemaCrawler header and footer in output
|
||||
# - Default: false
|
||||
#schemacrawler.format.no_header=false
|
||||
#schemacrawler.format.no_footer=false
|
||||
schemacrawler.format.no_schemacrawler_info=true
|
||||
schemacrawler.format.show_database_info=true
|
||||
#schemacrawler.format.show_jdbc_driver_info=false
|
||||
# - Controls display of remarks for tables and columns in output
|
||||
# - Default: false
|
||||
#schemacrawler.format.hide_remarks=false
|
||||
# - Shows all object names with the catalog and schema names, for easier comparison
|
||||
# - across different schemas
|
||||
# - Default: false
|
||||
#schemacrawler.format.show_unqualified_names=false
|
||||
# - Shows standard column names instead of database specific column names
|
||||
# - Default: false
|
||||
#schemacrawler.format.show_standard_column_type_names=false
|
||||
# - Shows ordinal numbers for columns
|
||||
# - Default: false
|
||||
#schemacrawler.format.show_ordinal_numbers=false
|
||||
# - Shows table row counts - use with --info-level=maximum
|
||||
# - Default: false
|
||||
#schemacrawler.format.show_row_counts=false
|
||||
# - If foreign key names, constraint names, trigger names,
|
||||
# - specific names for routines, or index and primary key names
|
||||
# - are not explicitly provided while creating a schema, most
|
||||
# - database systems assign default names. These names can show
|
||||
# - up as spurious diffs in SchemaCrawler output.
|
||||
# - All of these are hidden with the --portable-names
|
||||
# - command-line option. For more control, use the following
|
||||
# - options.
|
||||
# - Hides foreign key names, constraint names, trigger names,
|
||||
# - specific names for routines, index and primary key names
|
||||
# - Default: false
|
||||
#schemacrawler.format.hide_primarykey_names=false
|
||||
#schemacrawler.format.hide_foreignkey_names=false
|
||||
#schemacrawler.format.hide_index_names=false
|
||||
#schemacrawler.format.hide_trigger_names=false
|
||||
#schemacrawler.format.hide_routine_specific_names=false
|
||||
#schemacrawler.format.hide_constraint_names=false
|
||||
#schemacrawler.format.show_weak_associations=false
|
||||
# Specifies how to quote (delimit) database object names in text output
|
||||
# Options are
|
||||
# - quote_none - Do not quote any database object names
|
||||
# - quote_all - Always quote database object names
|
||||
# - quote_if_special_characters - Only quote database object names
|
||||
# if they contain special characters
|
||||
# - quote_if_special_characters_and_reserved_words - Quote database object names
|
||||
# if they contain special characters or SQL 2003 reserved words
|
||||
# - Default: quote_if_special_characters_and_reserved_words
|
||||
#schemacrawler.format.identifier_quoting_strategy=quote_if_special_characters_and_reserved_words
|
||||
# - Does not color-code catalog and schema names.
|
||||
# - Default: false
|
||||
#schemacrawler.format.no_schema_colors=false
|
||||
# - Encoding of input files, such as Apache Velocity templates
|
||||
# - Default: UTF-8
|
||||
#schemacrawler.encoding.input=UTF-8
|
||||
# - Encoding of SchemaCrawler output files
|
||||
# - Default: UTF-8
|
||||
#schemacrawler.encoding.output=UTF-8
|
||||
#
|
||||
# - Graphing Options
|
||||
# - (some graphing options may be controlled by text formatting options)
|
||||
# ------------------------------------------------------------------------------
|
||||
# - Show a crow's foot symbol to indicate cardinality
|
||||
# - Default: true
|
||||
#schemacrawler.graph.show.primarykey.cardinality=true
|
||||
#schemacrawler.graph.show.foreignkey.cardinality=true
|
||||
#
|
||||
# - Graph attributes for Graphviz, supporting graph, node and edge
|
||||
# - See https://www.graphviz.org/doc/info/attrs.html
|
||||
schemacrawler.graph.graphviz.graph.rankdir=RL
|
||||
schemacrawler.graph.graphviz.graph.labeljust=r
|
||||
schemacrawler.graph.graphviz.graph.fontname=Helvetica
|
||||
schemacrawler.graph.graphviz.node.fontname=Helvetica
|
||||
schemacrawler.graph.graphviz.node.shape=none
|
||||
schemacrawler.graph.graphviz.edge.fontname=Helvetica
|
||||
|
||||
# schemacrawler.graph.graphviz.graph.splines=ortho
|
||||
|
||||
# - Additional options for Graphviz, to control diagram generation
|
||||
# - See https://www.graphviz.org/doc/info/command.html
|
||||
# schemacrawler.graph.graphviz_opts=-Gdpi=150
|
||||
# - Data Output Options
|
||||
# ------------------------------------------------------------------------------
|
||||
# - Whether to show data from CLOB and BLOB objects
|
||||
# - Default: false
|
||||
#schemacrawler.data.show_lobs=false
|
||||
# --=----=----=----=----=----=----=----=----=----=----=----=----=----=----=----=
|
||||
# Queries
|
||||
# --=----=----=----=----=----=----=----=----=----=----=----=----=----=----=----=
|
||||
# Define your own named queries, which then become SchemaCrawler command
|
||||
hsqldb.tables=SELECT * FROM INFORMATION_SCHEMA.SYSTEM_TABLES
|
||||
tables.select=SELECT ${columns} FROM ${table} ORDER BY ${columns}
|
||||
tables.drop=DROP ${tabletype} ${table}
|
||||
106
docs/server-initialization.md
Normal file
106
docs/server-initialization.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Server Initialization
|
||||
|
||||
As our projects have grown, we have gradually added more and more dependent components. Consequently, fully initializing the top-level `Server` struct has become a rather complex task, especially considering the lack of reliable protection against accidental usage of an uninitialized `Server` instance or attached services.
|
||||
|
||||
To simplify our workflow, we made the decision to integrate the **wire** code generation tool into our project. This tool effectively resolves the dependency graph and ensures that the server components are always initialized in the correct order.
|
||||
|
||||
> Wire is a code generation tool that automates connecting components using dependency injection.
|
||||
|
||||
https://pkg.go.dev/github.com/google/wire.
|
||||
|
||||
To accomplish this, we had to introduce certain changes, which may be potentially breaking. We acknowledge that the downstream projects will require some effort in adapting to these changes. Nevertheless, we strongly believe that the long-term benefits will justify the initial investment.
|
||||
|
||||
Please read the following instructions carefully.
|
||||
|
||||
## 1. Define providers
|
||||
**BEFORE**: server components initialized within the methods defined on the `Server` struct.
|
||||
For example:
|
||||
```go
|
||||
func (s *Server) InitPush() error {
|
||||
```
|
||||
|
||||
**AFTER**: providers defined according to the wire guideline: https://github.com/google/wire/blob/main/docs/guide.md#defining-providers.
|
||||
|
||||
Providers are just ordinary functions getting the necessary dependencies as input parameters and returning an initialized component.
|
||||
For example:
|
||||
```go
|
||||
func NewPush(cfg config.Server, db *sql.DB) (*push.Service, error) {
|
||||
```
|
||||
|
||||
### REQUIRED ACTION
|
||||
Convert all `func (s *Server) Init*` methods into providers conforming to the wire guidelines.
|
||||
|
||||
If for any reason a provider function can't live in it's dedicated package, you can place it in `providers.go`.
|
||||
|
||||
Please refer to `internal/api/wire.go` to check currently used wire providers. They are listed as params to the `wire.Build()` function.
|
||||
|
||||
## 2. Define injectors
|
||||
Injectors are declared in `internal/api/wire.go`. They instruct wire which providers should be used to satisfy the dependencies of a top level component.
|
||||
|
||||
### REQUIRED ACTION
|
||||
Add the providers defined in the previous step to the `InitNewServer*` functions in `internal/api/wire.go`. More injectors might be added if needed.
|
||||
|
||||
### Some hints:
|
||||
- Components that should be skipped by wire should be labeled with `wire:"-"` (although this is not recommended).
|
||||
- The order of `wire.Build()` arguments doesn't matter.
|
||||
- If any provider is missing, wire generation will fail. Also, if any provider failes to create a dependent component in runtime, `InitNewServer*` returns an error.
|
||||
- If there are two or more components of the same type, declare a custom type for each of them to let wire identify the right provider to be used: https://github.com/google/wire/blob/main/docs/best-practices.md#distinguishing-types. A newly created type should be returned by a corresponding provider.
|
||||
- If a `Server`'s member is an interface and the corresponding provider returns a pointer to a struct, use the `Bind` function: https://pkg.go.dev/github.com/google/wire#Bind.
|
||||
- Providers commonly used together might be grouped into sets: https://pkg.go.dev/github.com/google/wire#ProviderSet.
|
||||
|
||||
## 3. Generate
|
||||
Functions declared in wire.go are just recepies for code generation and are excluded from build with the `+build wireinject` directive.
|
||||
To generate the code, wire command has to be invoked in the directory where wire.go resides.
|
||||
|
||||
Generated code can appears in `wire_gen.go` and looks like:
|
||||
```go
|
||||
func InitNewServer(cfg config.Server) (*Server, error) {
|
||||
db, err := NewDB(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
service, err := NewPush(cfg, db)
|
||||
```
|
||||
|
||||
Because `wire.go` is excluded from build, function signatures can be duplicated in `wire_gen.go`. On any `wire.go` change, `wire_gen.go` needs to be updated.
|
||||
|
||||
Wire generation has been added to Makefile step `go-generate`.
|
||||
|
||||
### REQUIRED ACTION
|
||||
#### Wire tool installation:
|
||||
```sh
|
||||
make init
|
||||
```
|
||||
|
||||
#### Wire generation:
|
||||
```sh
|
||||
wire gen ./...
|
||||
```
|
||||
or via `make`:
|
||||
```sh
|
||||
make go-generate
|
||||
```
|
||||
|
||||
On errors you can simply remove `wire_gen.go` and try again - sometimes it helps.
|
||||
Otherwire, see [this section](#some-hints) or get familiar with the wire documentation.
|
||||
|
||||
## 4. Integrate into existing code
|
||||
|
||||
After successful generation, `func (s *Server) Init*` methods are no longer needed. We can remove them and update each place where they have been used previously to use newly generated functions.
|
||||
|
||||
### REQUIRED ACTION
|
||||
Remove all `func (s *Server) Init*` methods and run
|
||||
```sh
|
||||
make go-build
|
||||
```
|
||||
At each place where the compilation fails do the following:
|
||||
- remove the usage of these methods.
|
||||
- replace `NewServer(cfg)` or any other previously used `Server` provider with the corresponding function generated by wire, for example `InitNewServer`.
|
||||
|
||||
Sometimes having a fully initialized server is not required (see `scripts/internal/handlers/check.go`). In such cases, components we want to use need a manual initialization - the providers have to be invoked in the right order and the resulting components have to be assigned to the `Server`.
|
||||
|
||||
When you're done, verify the sweet fruits of your labor with:
|
||||
```sh
|
||||
make all
|
||||
make test
|
||||
```
|
||||
Reference in New Issue
Block a user