Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
agentchat
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李伟@五瓣科技
agentchat
Commits
854f7d9a
Commit
854f7d9a
authored
May 29, 2025
by
Wade
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pg qa
parent
a0fd01f7
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
234 additions
and
0 deletions
+234
-0
go.mod
go.mod
+2
-0
go.sum
go.sum
+4
-0
pgvector.sql
pgvector.sql
+29
-0
qa.go
qa.go
+199
-0
No files found.
go.mod
View file @
854f7d9a
...
@@ -36,11 +36,13 @@ require (
...
@@ -36,11 +36,13 @@ require (
github.com/joho/godotenv v1.5.1 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mbleigh/raymond v0.0.0-20250414171441-6b3a58ab9e0a // indirect
github.com/mbleigh/raymond v0.0.0-20250414171441-6b3a58ab9e0a // indirect
github.com/milvus-io/milvus-proto/go-api/v2 v2.4.10-0.20240819025435-512e3b98866a // indirect
github.com/milvus-io/milvus-proto/go-api/v2 v2.4.10-0.20240819025435-512e3b98866a // indirect
github.com/milvus-io/milvus-sdk-go/v2 v2.4.2 // indirect
github.com/milvus-io/milvus-sdk-go/v2 v2.4.2 // indirect
github.com/ollama/ollama v0.6.5 // indirect
github.com/ollama/ollama v0.6.5 // indirect
github.com/pgvector/pgvector-go v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
github.com/tidwall/gjson v1.18.0 // indirect
...
...
go.sum
View file @
854f7d9a
...
@@ -174,6 +174,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
...
@@ -174,6 +174,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
...
@@ -212,6 +214,8 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
...
@@ -212,6 +214,8 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pgvector/pgvector-go v0.3.0 h1:Ij+Yt78R//uYqs3Zk35evZFvr+G0blW0OUN+Q2D1RWc=
github.com/pgvector/pgvector-go v0.3.0/go.mod h1:duFy+PXWfW7QQd5ibqutBO4GxLsUZ9RVXhFZGIBsWSA=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
...
...
pgvector.sql
0 → 100644
View file @
854f7d9a
create
table
public
.
qa
(
id
bigint
generated
by
default
as
identity
not
null
,
created_at
timestamp
with
time
zone
not
null
default
now
(),
user_id
bigint
null
,
username
text
null
,
question
text
null
,
answer
text
null
,
constraint
qa_pkey
primary
key
(
id
)
)
TABLESPACE
pg_default
;
create
view
public
.
latest_qa
as
select
distinct
on
(
qa
.
user_id
)
qa
.
id
,
qa
.
created_at
,
qa
.
user_id
,
qa
.
username
,
qa
.
question
,
qa
.
answer
from
qa
order
by
qa
.
user_id
,
qa
.
created_at
desc
;
\ No newline at end of file
qa.go
0 → 100644
View file @
854f7d9a
package
main
import
(
"context"
"database/sql"
"flag"
"fmt"
"log"
"time"
_
"github.com/lib/pq"
)
var
(
connString
=
flag
.
String
(
"dbconn"
,
""
,
"database connection string"
)
)
// QA 结构体表示 qa 表的记录
type
QA
struct
{
ID
int64
// 主键
CreatedAt
time
.
Time
// 创建时间
UserID
*
int64
// 可空的用户 ID
Username
*
string
// 可空的用户名
Question
*
string
// 可空的问题
Answer
*
string
// 可空的答案
}
// QAStore 定义 DAO 接口
type
QAStore
interface
{
// GetLatestQA 从 latest_qa 视图读取指定 user_id 的最新记录
GetLatestQA
(
ctx
context
.
Context
,
userID
*
int64
)
([]
QA
,
error
)
// WriteQA 插入或更新 qa 表记录
WriteQA
(
ctx
context
.
Context
,
qa
QA
)
(
int64
,
error
)
}
// qaStore 是 QAStore 接口的实现
type
qaStore
struct
{
db
*
sql
.
DB
}
// NewQAStore 创建新的 QAStore 实例
func
NewQAStore
(
db
*
sql
.
DB
)
QAStore
{
return
&
qaStore
{
db
:
db
}
}
// GetLatestQA 从 latest_qa 视图读取数据
func
(
s
*
qaStore
)
GetLatestQA
(
ctx
context
.
Context
,
userID
*
int64
)
([]
QA
,
error
)
{
query
:=
`
SELECT id, created_at, user_id, username, question, answer
FROM latest_qa
WHERE user_id = $1 OR (user_id IS NULL AND $1 IS NULL)`
args
:=
[]
interface
{}{
userID
}
if
userID
==
nil
{
args
=
[]
interface
{}{
nil
}
}
rows
,
err
:=
s
.
db
.
QueryContext
(
ctx
,
query
,
args
...
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"query latest_qa: %w"
,
err
)
}
defer
rows
.
Close
()
var
results
[]
QA
for
rows
.
Next
()
{
var
qa
QA
var
userIDVal
sql
.
NullInt64
var
username
,
question
,
answer
sql
.
NullString
if
err
:=
rows
.
Scan
(
&
qa
.
ID
,
&
qa
.
CreatedAt
,
&
userIDVal
,
&
username
,
&
question
,
&
answer
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"scan row: %w"
,
err
)
}
if
userIDVal
.
Valid
{
qa
.
UserID
=
&
userIDVal
.
Int64
}
if
username
.
Valid
{
qa
.
Username
=
&
username
.
String
}
if
question
.
Valid
{
qa
.
Question
=
&
question
.
String
}
if
answer
.
Valid
{
qa
.
Answer
=
&
answer
.
String
}
results
=
append
(
results
,
qa
)
}
if
err
:=
rows
.
Err
();
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"row iteration: %w"
,
err
)
}
return
results
,
nil
}
// WriteQA 插入或更新 qa 表记录
func
(
s
*
qaStore
)
WriteQA
(
ctx
context
.
Context
,
qa
QA
)
(
int64
,
error
)
{
if
qa
.
ID
!=
0
{
// 更新记录
query
:=
`
UPDATE qa
SET user_id = $1, username = $2, question = $3, answer = $4
WHERE id = $5
RETURNING id`
var
updatedID
int64
err
:=
s
.
db
.
QueryRowContext
(
ctx
,
query
,
qa
.
UserID
,
qa
.
Username
,
qa
.
Question
,
qa
.
Answer
,
qa
.
ID
)
.
Scan
(
&
updatedID
)
if
err
==
sql
.
ErrNoRows
{
return
0
,
fmt
.
Errorf
(
"no record found with id %d"
,
qa
.
ID
)
}
if
err
!=
nil
{
return
0
,
fmt
.
Errorf
(
"update qa: %w"
,
err
)
}
return
updatedID
,
nil
}
// 插入新记录
query
:=
`
INSERT INTO qa (user_id, username, question, answer)
VALUES ($1, $2, $3, $4)
RETURNING id`
var
newID
int64
err
:=
s
.
db
.
QueryRowContext
(
ctx
,
query
,
qa
.
UserID
,
qa
.
Username
,
qa
.
Question
,
qa
.
Answer
)
.
Scan
(
&
newID
)
if
err
!=
nil
{
return
0
,
fmt
.
Errorf
(
"insert qa: %w"
,
err
)
}
return
newID
,
nil
}
func
mainQA
()
{
flag
.
Parse
()
ctx
:=
context
.
Background
()
if
*
connString
==
""
{
log
.
Fatal
(
"need -dbconn"
)
}
db
,
err
:=
sql
.
Open
(
"postgres"
,
*
connString
)
if
err
!=
nil
{
log
.
Fatalf
(
"open database: %v"
,
err
)
}
defer
db
.
Close
()
store
:=
NewQAStore
(
db
)
// 示例:读取 user_id=101 的最新 QA
results
,
err
:=
store
.
GetLatestQA
(
ctx
,
int64Ptr
(
101
))
if
err
!=
nil
{
log
.
Fatalf
(
"get latest QA: %v"
,
err
)
}
for
_
,
qa
:=
range
results
{
fmt
.
Printf
(
"ID: %d, CreatedAt: %v, UserID: %v, Username: %v, Question: %v, Answer: %v
\n
"
,
qa
.
ID
,
qa
.
CreatedAt
,
derefInt64
(
qa
.
UserID
),
derefString
(
qa
.
Username
),
derefString
(
qa
.
Question
),
derefString
(
qa
.
Answer
))
}
// 示例:插入新 QA
newQA
:=
QA
{
UserID
:
int64Ptr
(
101
),
Username
:
stringPtr
(
"alice"
),
Question
:
stringPtr
(
"What is AI?"
),
Answer
:
stringPtr
(
"AI is..."
),
}
newID
,
err
:=
store
.
WriteQA
(
ctx
,
newQA
)
if
err
!=
nil
{
log
.
Fatalf
(
"write QA: %v"
,
err
)
}
fmt
.
Printf
(
"Inserted QA with ID: %d
\n
"
,
newID
)
// 示例:更新 QA
updateQA
:=
QA
{
ID
:
newID
,
UserID
:
int64Ptr
(
101
),
Username
:
stringPtr
(
"alice_updated"
),
Question
:
stringPtr
(
"What is NLP?"
),
Answer
:
stringPtr
(
"NLP is..."
),
}
updatedID
,
err
:=
store
.
WriteQA
(
ctx
,
updateQA
)
if
err
!=
nil
{
log
.
Fatalf
(
"update QA: %v"
,
err
)
}
fmt
.
Printf
(
"Updated QA with ID: %d
\n
"
,
updatedID
)
}
// 辅助函数:处理指针类型的空值
func
int64Ptr
(
i
int64
)
*
int64
{
return
&
i
}
func
stringPtr
(
s
string
)
*
string
{
return
&
s
}
func
derefInt64
(
p
*
int64
)
interface
{}
{
if
p
==
nil
{
return
nil
}
return
*
p
}
func
derefString
(
p
*
string
)
interface
{}
{
if
p
==
nil
{
return
nil
}
return
*
p
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment