daShangDao_kfzgw-info/csv/csvDll.go
2026-01-13 16:21:38 +08:00

844 lines
22 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
"log"
)
//
//var (
// headerOnce sync.Once
// fileHandle int64 = -1
//)
//
//// testwrite 函数 - 使用sync.Once确保表头只写入一次
//func testwrite(mgr *CSVManager, batchIndex int, wg *sync.WaitGroup) {
// defer wg.Done()
//
// fmt.Printf("协程 %d 开始执行...\n", batchIndex)
//
// // 1. 打开CSV文件 - 所有协程操作同一个文件
// filename := "csv/test_concurrent.csv"
// delimiter := ','
// hasHeader := true
//
// handleID, err := mgr.OpenCSVFile(filename, delimiter, hasHeader)
// if err != nil {
// fmt.Printf("协程 %d 打开文件失败: %v\n", batchIndex, err)
// return
// }
//
// fmt.Printf("协程 %d 成功打开文件句柄ID: %d\n", batchIndex, handleID)
//
// // 2. 使用sync.Once确保表头只写入一次
// headerOnce.Do(func() {
// header := []string{
// "ID", "Name",
// }
//
// err = mgr.WriteHeader(handleID, header)
// if err != nil {
// fmt.Printf("写入表头失败: %v\n", err)
// } else {
// fmt.Println("表头写入成功(仅第一次)")
// }
// })
//
// // 3. 生成并写入1000条数据
// batchSize := 1000
// //testData := generateTestData(batchIndex, batchSize)
//
// var rows [][]string
//
// for i := 0; i < batchSize; i++ {
// //rowIndex := batchIndex*batchSize + i + 1
// row := []string{
// fmt.Sprintf("%d", i),
// fmt.Sprintf("用户_%d", i),
// }
// rows = append(rows, row)
// // 批量写入数据
// _, err = mgr.AppendRows(handleID, rows)
// if err != nil {
// fmt.Printf("协程 %d 写入数据失败: %v\n", batchIndex, err)
// mgr.CloseHandle(handleID)
// return
// }
//
// fmt.Printf("协程 %d 成功写入 %d 条数据\n", batchIndex, i)
// rows = nil
// }
//
// //return rows
//
// // 4. 关闭句柄
// err = mgr.CloseHandle(handleID)
// if err != nil {
// fmt.Printf("协程 %d 关闭句柄失败: %v\n", batchIndex, err)
// } else {
// fmt.Printf("协程 %d 关闭句柄成功: %d\n", batchIndex, handleID)
// }
//
// fmt.Printf("协程 %d 执行完成\n", batchIndex)
//}
//
//// 生成测试数据
//func generateTestData(batchIndex, batchSize int) [][]string {
// var rows [][]string
//
// for i := 0; i < batchSize; i++ {
// rowIndex := batchIndex*batchSize + i + 1
// row := []string{
// fmt.Sprintf("%d", rowIndex),
// fmt.Sprintf("用户_%d", rowIndex),
// fmt.Sprintf("user%d@example.com", rowIndex),
// fmt.Sprintf("%d", 20+(rowIndex%50)),
// fmt.Sprintf("地址_%d", rowIndex),
// fmt.Sprintf("13800138%03d", rowIndex%1000),
// []string{"active", "inactive", "pending"}[rowIndex%3],
// fmt.Sprintf("%d", 50+(rowIndex%50)),
// []string{"A", "B", "C", "D"}[rowIndex%4],
// fmt.Sprintf("tag%d,tag%d", rowIndex, rowIndex+1),
// }
// rows = append(rows, row)
// }
//
// return rows
//}
//
//func main() {
// fmt.Println("开始多协程CSV写入测试...")
// fmt.Println("所有协程同时操作同一个文件test_concurrent.csv")
// fmt.Println("每个协程执行:打开文件 → 写入表头(仅第一次)→ 写入1000条数据 → 关闭文件")
// fmt.Println("启动10个协程总共写入10000条数据")
//
// // 获取CSV管理器
// mgr := GetManager()
//
// // 创建等待组
// var wg sync.WaitGroup
//
// // 启动10个协程每个协程执行完整的操作流程
// totalGoroutines := 4
//
// for i := 0; i < totalGoroutines; i++ {
// wg.Add(1)
// go testwrite(mgr, i, &wg)
// }
//
// // 等待所有协程完成
// wg.Wait()
//
// fmt.Println("\n所有协程执行完成")
// fmt.Println("测试文件test_concurrent.csv")
//}
//import "C"
//import (
// "bytes"
// "encoding/csv"
// "encoding/json"
// "fmt"
// "io"
// "net/http"
// "os"
// "path/filepath"
// "syscall"
// "unsafe"
//)
//
//// CsvDLL 代理DLL结构
//type csvDLL struct {
// dll *syscall.DLL
// openCSVFile *syscall.Proc // 打开/创建CSV文件
// readRows *syscall.Proc // 读取多行数据
// writeRows *syscall.Proc // 写入/覆盖行数据
// appendRows *syscall.Proc // 追加行数据
// getRowCount *syscall.Proc // 获取总行数
// findRows *syscall.Proc // 搜索行
// closeCSVFile *syscall.Proc // 关闭CSV文件
// mergeCSVFiles *syscall.Proc // 合并多个CSV文件
// getError *syscall.Proc // 获取错误信息
// updateCSVRowSafe *syscall.Proc
// createOpenCSVFile *syscall.Proc
// freeCString *syscall.Proc // 释放C字符串
//}
//
//// 初始化csvDLL
//func InitCsvDLL() (*csvDLL, error) {
// dllPath := filepath.Join("csv/dll", "csv.dll")
// if _, err := os.Stat(dllPath); os.IsNotExist(err) {
// return nil, fmt.Errorf("csv DLL 不存在: %s", dllPath)
// }
// if dll, err := syscall.LoadDLL(dllPath); err != nil {
// return nil, fmt.Errorf("加载csv DLL 失败: %s", err)
// } else {
// return &csvDLL{
// dll: dll,
// openCSVFile: dll.MustFindProc("OpenCSVFile"),
// updateCSVRowSafe: dll.MustFindProc("UpdateCSVRowSafe"),
// readRows: dll.MustFindProc("ReadRows"),
// writeRows: dll.MustFindProc("WriteRows"),
// appendRows: dll.MustFindProc("AppendRows"),
// getRowCount: dll.MustFindProc("GetRowCount"),
// findRows: dll.MustFindProc("FindRows"),
// closeCSVFile: dll.MustFindProc("CloseCSVFile"),
// mergeCSVFiles: dll.MustFindProc("MergeCSVFiles"),
// createOpenCSVFile: dll.MustFindProc("CreateOpenCSVFile"),
// getError: dll.MustFindProc("GetError"),
// freeCString: dll.MustFindProc("FreeCString"),
// }, nil
// }
//}
//
//// cStr 获取C字符串
//func (m *csvDLL) cStr(p uintptr) string {
// if p == 0 {
// return ""
// }
// b := []byte{}
// for i := uintptr(0); ; i++ {
// c := *(*byte)(unsafe.Pointer(p + i))
// if c == 0 {
// break
// }
// b = append(b, c)
// }
// s := string(b)
// if m.freeCString != nil {
// m.freeCString.Call(p)
// }
// return s
//}
//
//// 打开/创建CSV文件
//func (m *csvDLL) OpenCSVFile(filePath string, delimiter byte, hasHeader bool) (int64, error) {
// proc, err := m.dll.FindProc("OpenCSVFile")
// if err != nil {
// return -1, fmt.Errorf("找不到函数 OpenCSVFile: %v", err)
// }
// filePathPtr, _ := syscall.BytePtrFromString(filePath)
// hasHeaderInt := 0
// if hasHeader {
// hasHeaderInt = 1
// }
// info, _, _ := proc.Call(
// uintptr(unsafe.Pointer(filePathPtr)),
// uintptr(delimiter),
// uintptr(hasHeaderInt))
//
// return int64(info), nil
//}
//
//// CSV响应结构体
//type CSVResponses struct {
// Success bool `json:"success"`
// Message string `json:"message,omitempty"`
// Data CSVData `json:"data,omitempty"`
//}
//
//type CSVData struct {
// HandleID int64 `json:"handleID"`
//}
//
//func (m *csvDLL) CreateOpenCSVFile(filePath string, delimiter byte, hasHeader bool) (*CSVResponses, error) {
// proc, err := m.dll.FindProc("CreateOpenCSVFile")
// if err != nil {
// return nil, fmt.Errorf("找不到函数 CreateOpenCSVFile: %v", err)
// }
// filePathPtr, _ := syscall.BytePtrFromString(filePath)
// hasHeaderInt := 0
// if hasHeader {
// hasHeaderInt = 1
// }
// info, _, _ := proc.Call(
// uintptr(unsafe.Pointer(filePathPtr)),
// uintptr(delimiter),
// uintptr(hasHeaderInt))
// var csvResponse CSVResponses
// str := m.cStr(info)
// if err := json.Unmarshal([]byte(str), &csvResponse); err != nil {
// return nil, err
// }
// return &csvResponse, nil
//}
//
//func (m *csvDLL) UpdateCSVRowSafe(handleID int64, rowNum int, newRow []string) (*CSVResponses, error) {
// proc, err := m.dll.FindProc("UpdateCSVRowSafe")
// if err != nil {
// return nil, fmt.Errorf("找不到函数 UpdateCSVRowSafe: %v", err)
// }
// jsonString, _ := json.Marshal(newRow)
// newRowPtr, _ := syscall.BytePtrFromString(string(jsonString))
// info, _, _ := proc.Call(
// uintptr(handleID),
// uintptr(rowNum),
// uintptr(unsafe.Pointer(newRowPtr)))
// var csvResponse CSVResponses
// str := m.cStr(info)
// if err := json.Unmarshal([]byte(str), &csvResponse); err != nil {
// return nil, err
// }
// return &csvResponse, nil
//}
//
////// 读取多行数据
////func (m *csvDLL) ReadRows(handle int64) ([]string, error) {
//// proc, err := m.dll.FindProc("ReadRows")
//// if err != nil {
//// return nil, fmt.Errorf("找不到函数 ReadRows: %v", err)
//// }
////
////}
//
//// 写入/覆盖行数据
//func (m *csvDLL) WriteRows(handle int64, rowsData [][]string, header int) (int, error) {
// proc, err := m.dll.FindProc("WriteRows")
// if err != nil {
// return -1, fmt.Errorf("找不到函数 WriteRows: %v", err)
// }
// var buffer bytes.Buffer
// writer := csv.NewWriter(&buffer)
// // 写入所有行
// if err := writer.WriteAll(rowsData); err != nil {
// return -1, fmt.Errorf("序列化 CSV 数据失败: %v", err)
// }
// writer.Flush()
//
// // 转换为 C 字符串
// cStr := C.CString(buffer.String())
//
// ret, _, _ := proc.Call(
// uintptr(handle),
// uintptr(unsafe.Pointer(cStr)),
// uintptr(header))
//
// freeProc, _ := m.dll.FindProc("FreeCString")
// if freeProc != nil {
// defer freeProc.Call(uintptr(unsafe.Pointer(cStr)))
// }
// return int(ret), nil
//}
//
//// 定义请求结构体
//type OpenCSVRequest struct {
// FilePath string `json:"filePath"`
// Delimiter string `json:"delimiter"` // 可以是逗号、分号等字符
// HasHeader bool `json:"hasHeader"`
//}
//
//// 定义响应结构体
//type OpenCSVResponse struct {
// Success bool `json:"success"`
// Message string `json:"message"`
// Handle int64 `json:"handle,omitempty"`
// Error string `json:"error,omitempty"`
//}
//
//func handleOpenCSVFile(w http.ResponseWriter, r *http.Request) {
// // 设置响应头
// w.Header().Set("Content-Type", "application/json; charset=utf-8")
//
// // 只允许 POST 请求
// if r.Method != http.MethodPost {
// response := OpenCSVResponse{
// Success: false,
// Message: "只支持POST请求",
// }
// w.WriteHeader(http.StatusMethodNotAllowed)
// json.NewEncoder(w).Encode(response)
// return
// }
//
// // 1.初始化DLL管理器
// dll, err := InitCsvDLL()
// if err != nil {
// response := OpenCSVResponse{
// Success: false,
// Message: "初始化DLL失败",
// Error: err.Error(),
// }
// w.WriteHeader(http.StatusInternalServerError)
// json.NewEncoder(w).Encode(response)
// return
// }
//
// // 2.读取请求体
// body, err := io.ReadAll(r.Body)
// if err != nil {
// response := OpenCSVResponse{
// Success: false,
// Message: "读取请求体失败",
// Error: err.Error(),
// }
// w.WriteHeader(http.StatusInternalServerError)
// json.NewEncoder(w).Encode(response)
// return
// }
// defer r.Body.Close()
//
// // 3.解析JSON请求
// var req OpenCSVRequest
// if err := json.Unmarshal(body, &req); err != nil {
// response := OpenCSVResponse{
// Success: false,
// Message: "JSON解析失败",
// Error: err.Error(),
// }
// w.WriteHeader(http.StatusInternalServerError)
// json.NewEncoder(w).Encode(response)
// return
// }
//
// // 4.验证必填参数
// if req.FilePath == "" {
// response := OpenCSVResponse{
// Success: false,
// Message: "filePath参数不能为空",
// }
// w.WriteHeader(http.StatusBadRequest)
// json.NewEncoder(w).Encode(response)
// return
// }
//
// // 5. 处理分隔符参数
// delimiter := ','
// if req.Delimiter != "" {
// // 确保分隔符是单个字符
// if len(req.Delimiter) == 1 {
// delimiter = rune(req.Delimiter[0])
// } else {
// // 尝试解析常见分隔符的字符串表示
// switch req.Delimiter {
// case "comma", ",":
// delimiter = ','
// case "semicolon", ";":
// delimiter = ';'
// case "tab", "\t":
// delimiter = '\t'
// case "pipe", "|":
// delimiter = '|'
// default:
// response := OpenCSVResponse{
// Success: false,
// Message: "无效的分隔符,请使用单个字符或预定义的分隔符名称",
// }
// w.WriteHeader(http.StatusBadRequest)
// json.NewEncoder(w).Encode(response)
// return
// }
// }
// }
//
// // 6. 调用DLL函数
// handle, err := dll.OpenCSVFile(req.FilePath, byte(delimiter), req.HasHeader)
// if err != nil {
// response := OpenCSVResponse{
// Success: false,
// Message: "打开CSV文件失败",
// Error: err.Error(),
// }
// w.WriteHeader(http.StatusInternalServerError)
// json.NewEncoder(w).Encode(response)
// return
// }
//
// // 7. 返回成功响应
// response := OpenCSVResponse{
// Success: true,
// Message: "CSV文件打开成功",
// Handle: handle,
// }
// w.WriteHeader(http.StatusOK)
// json.NewEncoder(w).Encode(response)
//}
//
//// 解码从DLL读取的数据
//func decodeRowData(buffer []byte, maxBytes int) [][]string {
// var rows [][]string
// var currentRow []string
//
// offset := 0
// for offset < maxBytes {
// if offset+4 > maxBytes {
// break
// }
//
// // 读取单元格长度
// cellLen := int(uint32(buffer[offset]) |
// uint32(buffer[offset+1])<<8 |
// uint32(buffer[offset+2])<<16 |
// uint32(buffer[offset+3])<<24)
// offset += 4
//
// if cellLen == 0 {
// // 行结束
// if len(currentRow) > 0 {
// rows = append(rows, currentRow)
// currentRow = nil
// }
// continue
// }
//
// if offset+cellLen > maxBytes {
// break
// }
//
// // 读取单元格数据
// cell := string(buffer[offset : offset+cellLen])
// offset += cellLen
// currentRow = append(currentRow, cell)
// }
//
// return rows
//}
//func main() {
// 使用dll文件
//dll, err := InitCsvDLL()
//if err != nil {
//
//}
//file, err := dll.CreateOpenCSVFile("csv/taskLog.csv", ',', true)
//if err != nil {
//
//}
//newRow := []string{"9787115524539", "100.00", "1", "上传成功", ""}
//safe, err := dll.UpdateCSVRowSafe(file.Data.HandleID, 9, newRow)
//if err != nil {
//
//}
//marshal, _ := json.Marshal(safe)
//fmt.Println(string(marshal))
//file, err := GetManager().OpenCSVFile("csv/taskLog1.csv", ',', true)
//if err != nil {
// fmt.Println(err)
//}
//fmt.Println(file)
//handle, err := GetManager().getHandle(2)
//if err != nil {
// fmt.Println(err)
//}
// 获取指定数量的行
//row, err := handle.readRows(100)
//if err != nil {
// fmt.Println(err)
//}
//for _, i := range row {
// fmt.Println(i)
//}
//// 获取总行数
//row, err := handle.getTotalRows()
//if err != nil {
// fmt.Println(err)
//}
//fmt.Println(row)
//newRow := []string{
// "9787107267505", "20.00", "10", "上传成功", "877133619369",
//}
//
//row, err := GetManager().modifyRow(file, 1, newRow)
//if err != nil {
// fmt.Println(err)
//}
//fmt.Println(row)
//http.HandleFunc("/csv/openCSVFile", handleOpenCSVFile)
//port := "8080"
//server := &http.Server{
// Addr: ":" + port,
// Handler: nil,
//}
//
//// 4. 优雅关闭设置
//done := make(chan bool, 1)
//quit := make(chan os.Signal, 1)
//signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
//
//// 5. 优雅关闭协程
//go func() {
// <-quit
// fmt.Println("\n服务器正在关闭...")
//
// ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
// defer cancel()
//
// if err := server.Shutdown(ctx); err != nil {
// fmt.Printf("强制关闭服务器: %v\n", err)
// }
// close(done)
//}()
//
//// 启动服务器
//if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
// fmt.Printf("服务器启动失败: %s\n", err)
//}
//// 7. 等待关闭完成
//<-done
//fmt.Println("服务器已关闭")
//}
// 主函数 - 测试代码
func main() {
fmt.Println("=== CSV句柄管理器测试 ===") //7984
filename := "csv/test1.csv"
////dstFile := "csv/taskLog3.csv"
//fmt.Printf("1. 创建测试文件: %s\n", filename)
//
// 创建 Redis 客户端
rdb := redis.NewClient(&redis.Options{
Addr: "192.168.101.209:6379", // Redis 地址
Password: "", // 密码,没有则为空
DB: 0, // 使用的数据库编号
})
// 创建上下文
ctx := context.Background()
// 测试连接
pong, err := rdb.Ping(ctx).Result()
if err != nil {
log.Fatal("连接 Redis 失败:", err)
}
fmt.Println("连接成功:", pong)
key := "2006557053525397505_2010589232836288513_20260112_1"
//// 获取值
//val, err := rdb.Get(ctx, "1995373681100910593_2010521216979214337_20260112_1").Result()
//if err != nil {
// log.Fatal("获取键值失败:", err)
//}
//fmt.Println("key:", val)
handleID, err := GetManager().OpenCSVFile(filename, ',', true)
if err != nil {
fmt.Printf("打开文件失败: %v\n", err)
}
fmt.Printf("2. 打开文件成功句柄ID: %d\n", handleID)
// 测试写入表头
header := []string{"ID", "data"}
err = GetManager().WriteHeader(handleID, header)
if err != nil {
fmt.Printf("写入表头失败: %v\n", err)
} else {
fmt.Println("写入表头成功")
}
// 获取列表所有元素
listValues, err := rdb.LRange(ctx, key, 0, -1).Result()
if err != nil {
log.Fatal("获取列表失败:", err)
}
fmt.Printf("列表包含 %d 个元素:\n", len(listValues))
for i, value := range listValues {
fmt.Printf(" [%d] %s\n", i, value)
rowsData := [][]string{
{fmt.Sprintf("%d", i), value},
}
totalRows, err := GetManager().WriteRows(handleID, rowsData)
if err != nil {
fmt.Printf("批量写入数据失败: %v\n", err)
} else {
fmt.Printf("批量写入数据成功,行数: %d\n", totalRows)
}
}
// 3. 也可以检查键是否存在
exists, err := rdb.Exists(ctx, key).Result()
if err != nil {
log.Fatal("检查键是否存在失败:", err)
}
if exists == 0 {
fmt.Printf("键 '%s' 不存在\n", key)
} else {
fmt.Printf("键 '%s' 存在\n", key)
}
// 关闭连接
defer rdb.Close()
//
//// 2. 创建目标文件(部分数据)
//dstHandle, err := GetManager().OpenCSVFile(dstFile, ',', true)
//if err != nil {
// fmt.Printf("创建目标文件失败: %v", err)
//}
//// 合并
//totalRows, err := GetManager().MergeCSVFilesSimple(handleID, dstHandle, true)
//if err != nil {
// fmt.Printf("合并文件失败: %v", err)
//}
//fmt.Println(totalRows)
//for i := 0; i < 10000; i++ {
// // 打开CSV文件
// handleID, err := GetManager().OpenCSVFile(filename, ',', true)
// if err != nil {
// fmt.Printf("打开文件失败: %v\n", err)
// }
//
// fmt.Printf("2. 打开文件成功句柄ID: %d\n", handleID)
//
// // 测试写入表头
// header := []string{"ID", "Name", "Age", "Email"}
// err = GetManager().WriteHeader(handleID, header)
// if err != nil {
// fmt.Printf("写入表头失败: %v\n", err)
// } else {
// fmt.Println("写入表头成功")
// }
//
// //// 写入测试数据
// //rowsData := [][]string{
// // {"1", fmt.Sprintf("张三", i), "25", "zhangsan@example.com"},
// // {"2", "李四", "30", "lisi@example.com"},
// // {"3", "王五", "28", "wangwu@example.com"},
// // {"4", "赵六", "35", "zhaoliu@example.com"},
// //}
//
// // 写入测试数据
// rowsData := [][]string{
// {fmt.Sprintf("%d", i+100), "张三", fmt.Sprintf("%d", i+1000), fmt.Sprintf("%d", i+10000)},
// }
//
// totalRows, err := GetManager().WriteRows(handleID, rowsData)
// if err != nil {
// fmt.Printf("批量写入数据失败: %v\n", err)
// } else {
// fmt.Printf("批量写入数据成功,行数: %d\n", totalRows)
// }
//
// GetManager().CloseHandle(handleID)
//}
//// 测试写入表头
//header := []string{"ID", "Name", "Age", "Email"}
//err = GetManager().WriteHeader(handleID, header)
//if err != nil {
// fmt.Printf("写入表头失败: %v\n", err)
//} else {
// fmt.Println("写入表头成功")
//}
//// 写入测试数据
//rowsData := [][]string{
// {"1", "张三", "25", "zhangsan@example.com"},
// {"2", "李四", "30", "lisi@example.com"},
// {"3", "王五", "28", "wangwu@example.com"},
// {"4", "赵六", "35", "zhaoliu@example.com"},
//}
//
//totalRows, err := GetManager().WriteRows(handleID, rowsData)
//if err != nil {
// fmt.Printf("批量写入数据失败: %v\n", err)
//} else {
// fmt.Printf("批量写入数据成功,行数: %d\n", totalRows)
//}
//
//// 获取写入后的总行数
//totalRows, err = GetManager().GetTotalRows(handleID)
//if err != nil {
// fmt.Printf("获取总行数失败: %v\n", err)
//} else {
// fmt.Printf("写入后总行数: %d\n", totalRows)
//}
//// ============ 测试修改行功能 ============
//
//fmt.Println("\n3. 测试修改行功能")
//
//// 修改第1行数据索引0
//newRow1 := []string{"1", "张三已修改1", "26", "zhangsan_updated@example.com"}
//err = GetManager().UpdateRow(handleID, 0, newRow1)
//if err != nil {
// fmt.Printf("修改第1行数据失败: %v\n", err)
//} else {
// fmt.Println("修改第1行数据成功")
//}
//
//// 修改第3行数据索引2
//newRow3 := []string{"3", "王五(已修改)", "29", "wangwu_updated@example.com"}
//err = GetManager().UpdateRow(handleID, 2, newRow3)
//if err != nil {
// fmt.Printf("修改第3行数据失败: %v\n", err)
//} else {
// fmt.Println("修改第3行数据成功")
//}
//
//// 获取修改后的行数据
//fmt.Println("\n4. 获取修改后的行数据")
//获取第1行
//row1, err := GetManager().GetRow(handleID, 10)
//if err != nil {
// fmt.Printf("获取第1行失败: %v\n", err)
//} else {
// fmt.Printf("第1行数据: %v\n", row1)
//}
//// 获取第3行
//row3, err := GetManager().GetRow(handleID, 2)
//if err != nil {
// fmt.Printf("获取第3行失败: %v\n", err)
//} else {
// fmt.Printf("第3行数据: %v\n", row3)
//}
//// ============ 测试批量修改功能 ============
//
//fmt.Println("\n5. 测试批量修改功能")
//
//updates := map[int64][]string{
// 1: {"2", "李四(批量修改)", "31", "lisi_batch@example.com"},
// 3: {"4", "赵六(批量修改)", "36", "zhaoliu_batch@example.com"},
//}
//
//updatedCount, err := GetManager().UpdateRows(handleID, updates)
//if err != nil {
// fmt.Printf("批量修改失败: %v\n", err)
//} else {
// fmt.Printf("批量修改成功,修改了%d行\n", updatedCount)
//}
//
//// 验证批量修改结果
//row2, err := GetManager().GetRow(handleID, 1)
//if err != nil {
// fmt.Printf("获取第2行失败: %v\n", err)
//} else {
// fmt.Printf("第2行数据批量修改后: %v\n", row2)
//}
//
//row4, err := GetManager().GetRow(handleID, 3)
//if err != nil {
// fmt.Printf("获取第4行失败: %v\n", err)
//} else {
// fmt.Printf("第4行数据批量修改后: %v\n", row4)
//}
//
//// 获取最终总行数
//finalTotalRows, err := GetManager().GetTotalRows(handleID)
//if err != nil {
// fmt.Printf("获取最终总行数失败: %v\n", err)
//} else {
// fmt.Printf("最终总行数: %d\n", finalTotalRows)
//}
// 清理
//GetManager().closeAllHandles()
fmt.Println("\n测试完成")
}