Skip to content

Commit 7910a02

Browse files
committed
✨ feat: added postgres service interface and handler #1
1 parent 55c7c9b commit 7910a02

3 files changed

Lines changed: 162 additions & 6 deletions

File tree

postgresconn/postgresconn.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ func NewClient(config postgres.PostgresConfig) (*sqlx.DB, dbx.Dbx) {
6464
}
6565

6666
func GetPostgresPIDConn(db *sqlx.DB) (int, error) {
67-
var pid int
68-
err := db.QueryRow("SELECT pg_backend_pid() AS pid").Scan(&pid)
69-
if err != nil {
70-
return 0, err
71-
}
72-
return pid, nil
67+
s := NewPostgresService(db)
68+
return s.GetPIDConn()
7369
}

postgresconn/postgresconn_model.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
11
package postgresconn
2+
3+
type PostgresFunctionDetail struct {
4+
RoutineName string `db:"routine_name" json:"routine_name"`
5+
DataType string `db:"data_type" json:"data_type"`
6+
ParameterName string `db:"parameter_name" json:"parameter_name"`
7+
ParameterMode string `db:"parameter_mode" json:"parameter_mode"`
8+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package postgresconn
2+
3+
import (
4+
"strings"
5+
6+
"github.com/jmoiron/sqlx"
7+
8+
_ "github.com/lib/pq"
9+
)
10+
11+
type PostgresService interface {
12+
GetPIDConn() (int, error)
13+
Database() string
14+
GetAllTables() ([]string, error)
15+
GetAllFunctions() ([]string, error)
16+
GetAllProcedures() ([]string, error)
17+
GetFunctionDetails(function string) ([]PostgresFunctionDetail, error)
18+
GetFunctionReturnType(function string) (string, error)
19+
BuildFunction(function string) (string, error)
20+
ShowFunctionContent(function string) (string, error)
21+
ShowProcedureContent(procedure string) (string, error)
22+
}
23+
24+
type postgresServiceImpl struct {
25+
dbConn *sqlx.DB
26+
}
27+
28+
func NewPostgresService(dbConn *sqlx.DB) PostgresService {
29+
p := &postgresServiceImpl{
30+
dbConn: dbConn,
31+
}
32+
return p
33+
}
34+
35+
func (p *postgresServiceImpl) GetPIDConn() (int, error) {
36+
var pid int
37+
err := p.dbConn.QueryRow("SELECT pg_backend_pid() AS pid").Scan(&pid)
38+
if err != nil {
39+
return 0, err
40+
}
41+
return pid, nil
42+
}
43+
44+
func (p *postgresServiceImpl) GetAllTables() ([]string, error) {
45+
var tableNames []string
46+
err := p.dbConn.Select(&tableNames, "SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE'")
47+
if err != nil {
48+
return nil, err
49+
}
50+
return tableNames, nil
51+
}
52+
53+
func (p *postgresServiceImpl) GetAllFunctions() ([]string, error) {
54+
var functions []string
55+
err := p.dbConn.Select(&functions, "SELECT routine_name FROM information_schema.routines WHERE routine_catalog = $1 AND routine_schema = 'public' AND routine_type = 'FUNCTION'", p.Database())
56+
if err != nil {
57+
return nil, err
58+
}
59+
return functions, nil
60+
}
61+
62+
func (p *postgresServiceImpl) Database() string {
63+
var database string
64+
err := p.dbConn.Get(&database, "SELECT current_database()")
65+
if err != nil {
66+
panic(err)
67+
}
68+
return database
69+
}
70+
71+
func (p *postgresServiceImpl) GetAllProcedures() ([]string, error) {
72+
var procedures []string
73+
err := p.dbConn.Select(&procedures, "SELECT routine_name FROM information_schema.routines WHERE routine_catalog = $1 AND routine_schema = 'public' AND routine_type = 'PROCEDURE'", p.Database())
74+
if err != nil {
75+
return nil, err
76+
}
77+
return procedures, nil
78+
}
79+
80+
func (p *postgresServiceImpl) GetFunctionDetails(function string) ([]PostgresFunctionDetail, error) {
81+
var functionDetails []PostgresFunctionDetail
82+
err := p.dbConn.Select(&functionDetails, `
83+
SELECT
84+
r.routine_name,
85+
p.data_type,
86+
p.parameter_name,
87+
p.parameter_mode
88+
FROM information_schema.routines r
89+
JOIN information_schema.parameters p
90+
ON r.specific_name = p.specific_name
91+
WHERE r.routine_catalog = $1
92+
AND r.routine_schema = 'public'
93+
AND r.routine_name = $2
94+
`, p.Database(), function)
95+
if err != nil {
96+
return nil, err
97+
}
98+
return functionDetails, nil
99+
}
100+
101+
func (p *postgresServiceImpl) GetFunctionReturnType(function string) (string, error) {
102+
var returnType string
103+
err := p.dbConn.QueryRow("SELECT pg_get_function_result(oid) FROM pg_proc WHERE proname = $1", function).Scan(&returnType)
104+
if err != nil {
105+
return "", err
106+
}
107+
return returnType, nil
108+
}
109+
110+
func (p *postgresServiceImpl) BuildFunction(function string) (string, error) {
111+
functionDetails, err := p.GetFunctionDetails(function)
112+
if err != nil {
113+
return "", err
114+
}
115+
returnType, err := p.GetFunctionReturnType(function)
116+
if err != nil {
117+
return "", err
118+
}
119+
var builder strings.Builder
120+
builder.WriteString("CREATE OR REPLACE FUNCTION " + function + "(")
121+
for i, detail := range functionDetails {
122+
if i > 0 {
123+
builder.WriteString(", ")
124+
}
125+
builder.WriteString(detail.ParameterName + " " + detail.DataType)
126+
if detail.ParameterMode != "IN" {
127+
builder.WriteString(" " + detail.ParameterMode)
128+
}
129+
}
130+
builder.WriteString(") RETURNS " + returnType + " AS $$\n")
131+
builder.WriteString("BEGIN\n\n")
132+
builder.WriteString("\n")
133+
builder.WriteString("\nEND;\n$$ LANGUAGE plpgsql;")
134+
return builder.String(), nil
135+
}
136+
137+
func (ps *postgresServiceImpl) ShowFunctionContent(function string) (string, error) {
138+
var functionContent string
139+
err := ps.dbConn.QueryRow("SELECT pg_get_functiondef($1::regproc)", function).Scan(&functionContent)
140+
if err != nil {
141+
return "", err
142+
}
143+
return functionContent, nil
144+
}
145+
146+
func (p *postgresServiceImpl) ShowProcedureContent(procedure string) (string, error) {
147+
var procedureContent string
148+
err := p.dbConn.QueryRow("SELECT pg_get_functiondef($1::regproc)", procedure).Scan(&procedureContent)
149+
if err != nil {
150+
return "", err
151+
}
152+
return procedureContent, nil
153+
}

0 commit comments

Comments
 (0)