PostgreSQL 의존성 및 내부 유틸리티 추가:
Some checks failed
Build Push and Restart Compose / deploy (push) Failing after 1m47s
Some checks failed
Build Push and Restart Compose / deploy (push) Failing after 1m47s
- `github.com/lib/pq` PostgreSQL 드라이버 vendor 디렉토리에 추가. - PostgreSQL 관련 내부 패키지(`pqsql`, `proto`, `pqtime`, `pgpass`, `pgservice`, `pqutil`) 구현: - SQL 어휘 처리, 프로토콜 상수 및 구조 정의, 시간 파서/포맷터(`Parse`, `Format`). - `.pgpass` 파일 및 `pg_service.conf` 관리 기능 추가. - 파일/사용자 권한 검증 및 플랫폼별 사용자 정보 조회 기능 포함. - 데이터베이스 초기화 로직 추가 (`services/db.go`): - PostgreSQL 연결 설정 및 초기 스키마 생성. - 자동매매 관련 DB 레포지토리(`services/autotrade_repo.go`) 구현: - 자동매매 규칙 및 포지션 관리 로직 추가 (`dbInsertRule`, `dbLoadRules` 등).
This commit is contained in:
312
vendor/github.com/lib/pq/README.md
generated
vendored
Normal file
312
vendor/github.com/lib/pq/README.md
generated
vendored
Normal file
@@ -0,0 +1,312 @@
|
||||
pq is a Go PostgreSQL driver for database/sql.
|
||||
|
||||
All [maintained versions of PostgreSQL] are supported. Older versions may work,
|
||||
but this is not tested. [API docs].
|
||||
|
||||
[maintained versions of PostgreSQL]: https://www.postgresql.org/support/versioning
|
||||
[API docs]: https://pkg.go.dev/github.com/lib/pq
|
||||
|
||||
Connecting
|
||||
----------
|
||||
Use the `postgres` driver name in the `sql.Open()` call:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
|
||||
_ "github.com/lib/pq" // To register the driver.
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Or as URL: postgresql://localhost/pqgo
|
||||
db, err := sql.Open("postgres", "host=localhost dbname=pqgo")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// db.Open() only creates a connection pool, and doesn't actually establish
|
||||
// a connection. To ensure the connection works you need to do *something*
|
||||
// with a connection.
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also use the `pq.Config` struct:
|
||||
|
||||
```go
|
||||
cfg := pq.Config{
|
||||
Host: "localhost",
|
||||
Port: 5432,
|
||||
User: "pqgo",
|
||||
}
|
||||
// Or: create a new Config from the defaults, environment, and DSN.
|
||||
// cfg, err := pq.NewConfig("host=postgres dbname=pqgo")
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
|
||||
c, err := pq.NewConnectorConfig(cfg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Create connection pool.
|
||||
db := sql.OpenDB(c)
|
||||
defer db.Close()
|
||||
|
||||
// Make sure it works.
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
```
|
||||
|
||||
The DSN is identical to PostgreSQL's libpq; most parameters are supported and
|
||||
should behave identical. Both key=value and postgres:// URL-style connection
|
||||
strings are supported. See the doc comments on the [Config struct] for the full
|
||||
list and documentation.
|
||||
|
||||
The most notable difference is that you can use any [run-time parameter] such as
|
||||
`search_path` or `work_mem` in the connection string. This is different from
|
||||
libpq, which uses the `options` parameter for this (which also works in pq).
|
||||
|
||||
For example:
|
||||
|
||||
sql.Open("postgres", "dbname=pqgo work_mem=100kB search_path=xyz")
|
||||
|
||||
The libpq way (which also works in pq) is to use `options='-c k=v'` like so:
|
||||
|
||||
sql.Open("postgres", "dbname=pqgo options='-c work_mem=100kB -c search_path=xyz'")
|
||||
|
||||
[Config struct]: https://pkg.go.dev/github.com/lib/pq#Config
|
||||
[run-time parameter]: http://www.postgresql.org/docs/current/static/runtime-config.html
|
||||
|
||||
Errors
|
||||
------
|
||||
Errors from PostgreSQL are returned as [pq.Error]; [pq.As] can be used to
|
||||
convert an error to `pq.Error`:
|
||||
|
||||
```go
|
||||
pqErr := pq.As(err, pqerror.UniqueViolation)
|
||||
if pqErr != nil {
|
||||
return fmt.Errorf("email %q already exsts", email)
|
||||
}
|
||||
```
|
||||
|
||||
the Error() string contains the error message and code:
|
||||
|
||||
pq: duplicate key value violates unique constraint "users_lower_idx" (23505)
|
||||
|
||||
The ErrorWithDetail() string also contains the DETAIL and CONTEXT fields, if
|
||||
present. For example for the above error this helpfully contains the duplicate
|
||||
value:
|
||||
|
||||
ERROR: duplicate key value violates unique constraint "users_lower_idx" (23505)
|
||||
DETAIL: Key (lower(email))=(a@example.com) already exists.
|
||||
|
||||
Or for an invalid syntax error like this:
|
||||
|
||||
pq: invalid input syntax for type json (22P02)
|
||||
|
||||
It contains the context where this error occurred:
|
||||
|
||||
ERROR: invalid input syntax for type json (22P02)
|
||||
DETAIL: Token "asd" is invalid.
|
||||
CONTEXT: line 5, column 8:
|
||||
|
||||
3 | 'def',
|
||||
4 | 123,
|
||||
5 | 'foo', 'asd'::jsonb
|
||||
^
|
||||
|
||||
[pq.Error]: https://pkg.go.dev/github.com/lib/pq#Error
|
||||
[pq.As]: https://pkg.go.dev/github.com/lib/pq#As
|
||||
|
||||
PostgreSQL features
|
||||
-------------------
|
||||
|
||||
### Authentication
|
||||
pq supports PASSWORD, MD5, and SCRAM-SHA256 authentication out of the box. If
|
||||
you need GSS/Kerberos authentication you'll need to import the `auth/kerberos`
|
||||
module: package:
|
||||
|
||||
import "github.com/lib/pq/auth/kerberos"
|
||||
|
||||
func init() {
|
||||
pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() })
|
||||
}
|
||||
|
||||
This is in a separate module so that users who don't need Kerberos (i.e. most
|
||||
users) don't have to add unnecessary dependencies.
|
||||
|
||||
Reading a [password file] (pgpass) is also supported.
|
||||
|
||||
[password file]: http://www.postgresql.org/docs/current/static/libpq-pgpass.html
|
||||
|
||||
### Bulk imports with `COPY [..] FROM STDIN`
|
||||
You can perform bulk imports by preparing a `COPY [..] FROM STDIN` statement
|
||||
inside a transaction. The returned `sql.Stmt` can then be repeatedly executed to
|
||||
copy data. After all data has been processed you should call Exec() once with no
|
||||
arguments to flush all buffered data.
|
||||
|
||||
[Further documentation][copy-doc] and [example][copy-ex].
|
||||
|
||||
[copy-doc]: https://pkg.go.dev/github.com/lib/pq#hdr-Bulk_imports
|
||||
[copy-ex]: https://pkg.go.dev/github.com/lib/pq#example-package-CopyFromStdin
|
||||
|
||||
### NOTICE errors
|
||||
PostgreSQL has "NOTICE" errors for informational messages. For example from the
|
||||
psql CLI:
|
||||
|
||||
pqgo=# drop table if exists doesnotexist;
|
||||
NOTICE: table "doesnotexist" does not exist, skipping
|
||||
DROP TABLE
|
||||
|
||||
These errors are not returned because they're not really errors but, well,
|
||||
notices.
|
||||
|
||||
You can register a callback for these notices with [ConnectorWithNoticeHandler]
|
||||
|
||||
[ConnectorWithNoticeHandler]: https://pkg.go.dev/github.com/lib/pq#ConnectorWithNoticeHandler
|
||||
|
||||
### Using `LISTEN`/`NOTIFY`
|
||||
With [pq.Listener] notifications are send on a channel. For example:
|
||||
|
||||
```go
|
||||
l := pq.NewListener("dbname=pqgo", time.Second, time.Minute, nil)
|
||||
defer l.Close()
|
||||
|
||||
err := l.Listen("coconut")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for {
|
||||
n := <-l.Notify:
|
||||
if n == nil {
|
||||
fmt.Println("nil notify: closing Listener")
|
||||
return
|
||||
}
|
||||
fmt.Printf("notification on %q with data %q\n", n.Channel, n.Extra)
|
||||
}
|
||||
```
|
||||
|
||||
And you'll get a notification for every `notify coconut`.
|
||||
|
||||
See the API docs for a more complete example.
|
||||
|
||||
[pq.Listener]: https://pkg.go.dev/github.com/lib/pq#Listener
|
||||
|
||||
|
||||
Caveats
|
||||
-------
|
||||
### LastInsertId
|
||||
sql.Result.LastInsertId() is not supported, because the PostgreSQL protocol does
|
||||
not have this facility. Use `insert [..] returning [cols]` instead:
|
||||
|
||||
db.QueryRow(`insert into tbl [..] returning id_col`).Scan(..)
|
||||
// Or multiple rows:
|
||||
db.Query(`insert into tbl (row1), (row2) returning id_col`)
|
||||
|
||||
This will also work in SQLite and MariaDB with the same syntax. MS-SQL and
|
||||
Oracle have a similar facility (with a different syntax).
|
||||
|
||||
### timestamps
|
||||
For timestamps with a timezone (`timestamptz`/`timestamp with time zone`), pq
|
||||
uses the timezone configured in the server, as libpq. You can change this with
|
||||
`timestamp=[..]` in the connection string. It's generally recommended to use
|
||||
UTC.
|
||||
|
||||
For timestamps without a timezone (`timestamp`/`timestamp without time zone`),
|
||||
pq always uses `time.FixedZone("", 0)` as the timezone; the timestamp parameter
|
||||
has no effect here. This is intentionally not equal to time.UTC, as it's not a
|
||||
UTC time: it's a time without a timezone. Go's time package does not really
|
||||
support this concept, so this is the best we can do This will print `+0000`
|
||||
twice (e.g. `2026-03-15 17:45:47 +0000 +0000`; having a clearer name would have
|
||||
been better, but is not compatible change). See [this comment][ts] for some
|
||||
options on how to deal with this.
|
||||
|
||||
Also see the examples for [timestamptz] and [timestamp]
|
||||
|
||||
[ts]: https://github.com/lib/pq/issues/329#issuecomment-4025733506
|
||||
[timestamptz]: https://pkg.go.dev/github.com/lib/pq#example-package-TimestampWithTimezone
|
||||
[timestamp]: https://pkg.go.dev/github.com/lib/pq#example-package-TimestampWithoutTimezone
|
||||
|
||||
### bytea with copy
|
||||
All `[]byte` parameters are encoded as `bytea` when using `copy [..] from
|
||||
stdin`, which may result in errors for e.g. `jsonb` columns. The solution is to
|
||||
use a string instead of []byte. See #1023
|
||||
|
||||
Development
|
||||
-----------
|
||||
### Running tests
|
||||
Tests need to be run against a PostgreSQL database; you can use Docker compose
|
||||
to start one:
|
||||
|
||||
docker compose up -d
|
||||
|
||||
This starts the latest PostgreSQL; use `docker compose up -d pg«v»` to start a
|
||||
different version.
|
||||
|
||||
In addition, your `/etc/hosts` needs an entry:
|
||||
|
||||
127.0.0.1 postgres postgres-invalid
|
||||
|
||||
Or you can use any other PostgreSQL instance; see
|
||||
`testdata/postgres/docker-entrypoint-initdb.d` for the required setup. You can use
|
||||
the standard `PG*` environment variables to control the connection details; it
|
||||
uses the following defaults:
|
||||
|
||||
PGHOST=localhost
|
||||
PGDATABASE=pqgo
|
||||
PGUSER=pqgo
|
||||
PGSSLMODE=disable
|
||||
PGCONNECT_TIMEOUT=20
|
||||
|
||||
`PQTEST_BINARY_PARAMETERS` can be used to add `binary_parameters=yes` to all
|
||||
connection strings:
|
||||
|
||||
PQTEST_BINARY_PARAMETERS=1 go test
|
||||
|
||||
Tests can be run against pgbouncer with:
|
||||
|
||||
docker compose up -d pgbouncer pg18
|
||||
PGPORT=6432 go test ./...
|
||||
|
||||
and pgpool with:
|
||||
|
||||
docker compose up -d pgpool pg18
|
||||
PGPORT=7432 go test ./...
|
||||
|
||||
### Protocol debug output
|
||||
You can use PQGO_DEBUG=1 to make the driver print the communication with
|
||||
PostgreSQL to stderr; this works anywhere (test or applications) and can be
|
||||
useful to debug protocol problems.
|
||||
|
||||
For example:
|
||||
|
||||
% PQGO_DEBUG=1 go test -run TestSimpleQuery
|
||||
CLIENT → Startup 69 "\x00\x03\x00\x00database\x00pqgo\x00user [..]"
|
||||
SERVER ← (R) AuthRequest 4 "\x00\x00\x00\x00"
|
||||
SERVER ← (S) ParamStatus 19 "in_hot_standby\x00off\x00"
|
||||
[..]
|
||||
SERVER ← (Z) ReadyForQuery 1 "I"
|
||||
START conn.query
|
||||
START conn.simpleQuery
|
||||
CLIENT → (Q) Query 9 "select 1\x00"
|
||||
SERVER ← (T) RowDescription 29 "\x00\x01?column?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x04\xff\xff\xff\xff\x00\x00"
|
||||
SERVER ← (D) DataRow 7 "\x00\x01\x00\x00\x00\x011"
|
||||
END conn.simpleQuery
|
||||
END conn.query
|
||||
SERVER ← (C) CommandComplete 9 "SELECT 1\x00"
|
||||
SERVER ← (Z) ReadyForQuery 1 "I"
|
||||
CLIENT → (X) Terminate 0 ""
|
||||
PASS
|
||||
ok github.com/lib/pq 0.010s
|
||||
Reference in New Issue
Block a user