From ac1054d833f8920155ae190c376fd937eae108ee Mon Sep 17 00:00:00 2001 From: zhoujie Date: Wed, 25 Jun 2025 17:42:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(ScanRows):=20=E6=96=B0=E5=A2=9E=20scanRows?= =?UTF-8?q?=20=E8=BD=ACmap=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mapping.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ mapping_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/mapping.go b/mapping.go index f3af3c3..ab8a315 100644 --- a/mapping.go +++ b/mapping.go @@ -340,3 +340,52 @@ func (b *Mapper) scanRow(target reflect.Value, rows *sql.Rows) error { // 扫描数据 return rows.Scan(dest...) } + +// ScanRowsToMap 扫描多行数据到map +// @param rows 数据库返回的行数据 +// @return 返回map数组和错误 +func (b *Mapper) ScanRowsToMap(rows *sql.Rows) ([]map[string]any, error) { + return b.ScanRowsToMapWithContext(context.Background(), rows) +} + +// ScanRowsToMapWithContext 扫描多行数据到map +// @param ctx 上下文 +// @param rows 数据库返回的行数据 +// @return 返回map数组和错误 +func (b *Mapper) ScanRowsToMapWithContext(ctx context.Context, rows *sql.Rows) ([]map[string]any, error) { + columns, err := rows.Columns() + if err != nil { + return nil, err + } + result := make([]map[string]any, 0) + + for rows.Next() { + // 检查上下文是否已取消 + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + } + + // 创建一个切片来存储列的值 + values := make([]any, len(columns)) + for i := range values { + values[i] = new(any) + } + + // 扫描行数据到切片中 + if err := rows.Scan(values...); err != nil { + return nil, err + } + + // 构建 结果映射 + rowMap := make(map[string]any, len(columns)) + for i := range values { + column := columns[i] + value := *(values[i].(*any)) + rowMap[column] = value + } + result = append(result, rowMap) + } + return result, err +} diff --git a/mapping_test.go b/mapping_test.go index dfe1519..c343baa 100644 --- a/mapping_test.go +++ b/mapping_test.go @@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "fmt" + //_ "github.com/taosdata/driver-go/v3/taosWS" "testing" "time" ) @@ -195,3 +196,47 @@ func TestScanRows(t *testing.T) { //marshal, _ := json.MarshalIndent(sdArray, "", " ") //fmt.Println(len(sdArray), string(marshal)) } + +func TestScanRowsToMap(t *testing.T) { + /* + 文档参考: https://docs.taosdata.com/reference/connector/go/#websocket-%E8%BF%9E%E6%8E%A5 + + go get github.com/taosdata/driver-go/v3 + + import _ "github.com/taosdata/driver-go/v3/taosWS" + + 超级表创建 + CREATE STABLE `super_dev` (`ts` TIMESTAMP , `app_sn` VARCHAR(500) , `ct` INT ) TAGS (`dev_id` VARCHAR(50), `dev_type` VARCHAR(50)) + + 批量插入 + INSERT INTO + `dev_SN001` USING `super_dev` (`dev_id`,`dev_type`) TAGS ('SN001','模拟设备') (`ts`,`app_sn`,`ct`) + VALUES ('2024-09-18T16:22:17+08:00','a0001',1),('2024-09-18T16:22:18+08:00','a0002',2) + `dev_SN002` USING `super_dev` (`dev_id`,`dev_type`) TAGS ('SN002','模拟设备') (`ts`,`app_sn`,`ct`) + VALUES ('2024-09-18T16:22:17+08:00','a0003',3) + + */ + + var taosUri = "root:taosdata@localhost:6041/test" + db, err := sql.Open("taosWS", taosUri) + if err != nil { + t.Fatal(err) + } + + rows, err := db.Query("select * from super_dev order by ts desc limit 100") + if err != nil { + t.Fatal(err) + } + defer func() { _ = rows.Close() }() + + tdMapper := NewMapper() + + toMap, err := tdMapper.ScanRowsToMap(rows) + if err != nil { + t.Fatal(err) + } + + indent, _ := json.MarshalIndent(toMap, "", " ") + fmt.Println(string(indent)) + fmt.Println("len:", len(toMap)) +}