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` 등).
72 lines
2.7 KiB
Go
72 lines
2.7 KiB
Go
package pq
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
)
|
|
|
|
// QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be
|
|
// used as part of an SQL statement. For example:
|
|
//
|
|
// tblname := "my_table"
|
|
// data := "my_data"
|
|
// quoted := pq.QuoteIdentifier(tblname)
|
|
// err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data)
|
|
//
|
|
// Any double quotes in name will be escaped. The quoted identifier will be case
|
|
// sensitive when used in a query. If the input string contains a zero byte, the
|
|
// result will be truncated immediately before it.
|
|
func QuoteIdentifier(name string) string {
|
|
end := strings.IndexRune(name, 0)
|
|
if end > -1 {
|
|
name = name[:end]
|
|
}
|
|
return `"` + strings.Replace(name, `"`, `""`, -1) + `"`
|
|
}
|
|
|
|
// BufferQuoteIdentifier satisfies the same purpose as QuoteIdentifier, but backed by a
|
|
// byte buffer.
|
|
func BufferQuoteIdentifier(name string, buffer *bytes.Buffer) {
|
|
// TODO(v2): this should have accepted an io.Writer, not *bytes.Buffer.
|
|
end := strings.IndexRune(name, 0)
|
|
if end > -1 {
|
|
name = name[:end]
|
|
}
|
|
buffer.WriteRune('"')
|
|
buffer.WriteString(strings.Replace(name, `"`, `""`, -1))
|
|
buffer.WriteRune('"')
|
|
}
|
|
|
|
// QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal
|
|
// to DDL and other statements that do not accept parameters) to be used as part
|
|
// of an SQL statement. For example:
|
|
//
|
|
// exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z")
|
|
// err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))
|
|
//
|
|
// Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be
|
|
// replaced by two backslashes (i.e. "\\") and the C-style escape identifier
|
|
// that PostgreSQL provides ('E') will be prepended to the string.
|
|
func QuoteLiteral(literal string) string {
|
|
// This follows the PostgreSQL internal algorithm for handling quoted literals
|
|
// from libpq, which can be found in the "PQEscapeStringInternal" function,
|
|
// which is found in the libpq/fe-exec.c source file:
|
|
// https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/libpq/fe-exec.c
|
|
//
|
|
// substitute any single-quotes (') with two single-quotes ('')
|
|
literal = strings.Replace(literal, `'`, `''`, -1)
|
|
// determine if the string has any backslashes (\) in it.
|
|
// if it does, replace any backslashes (\) with two backslashes (\\)
|
|
// then, we need to wrap the entire string with a PostgreSQL
|
|
// C-style escape. Per how "PQEscapeStringInternal" handles this case, we
|
|
// also add a space before the "E"
|
|
if strings.Contains(literal, `\`) {
|
|
literal = strings.Replace(literal, `\`, `\\`, -1)
|
|
literal = ` E'` + literal + `'`
|
|
} else {
|
|
// otherwise, we can just wrap the literal with a pair of single quotes
|
|
literal = `'` + literal + `'`
|
|
}
|
|
return literal
|
|
}
|