Golang中如何加载包含多个文件的embed库
Golang中如何加载包含多个文件的embed库
//go:embed sqls/allquery.sql
我正在使用第三方库 sqload,它目前仅支持单个文件。
如何实现支持多个文件?
4 回复
谢谢。我之前尝试通过添加 *.SQL 并使用单个变量来实现。
更多关于Golang中如何加载包含多个文件的embed库的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
您也可以使用通配符进行嵌入,例如 ./*.sql。
此时变量必须是 embed.FS 类型。
除非我误解了你的问题(因为我不熟悉 sqload 库),否则这很简单,只需嵌入多个文件并使用它们即可。
//go:embed sqls/allquery.sql
var allQuery string
//go:embed sqls/someotherquery.sql
var someOtherQuery string
var q1 = sqload.MustLoadFromString[struct {
...
}](allQuery)
var q2 = sqload.MustLoadFromString[struct {
...
}](someOtherQuery)
在Golang中加载包含多个文件的embed库,可以使用//go:embed指令配合通配符模式。以下是几种实现方式:
1. 使用通配符嵌入整个目录
import "embed"
//go:embed sqls/*.sql
var sqlFiles embed.FS
// 读取所有SQL文件
func loadAllSQLFiles() error {
entries, err := sqlFiles.ReadDir("sqls")
if err != nil {
return err
}
for _, entry := range entries {
if !entry.IsDir() {
data, err := sqlFiles.ReadFile("sqls/" + entry.Name())
if err != nil {
return err
}
fmt.Printf("Loaded %s: %s\n", entry.Name(), string(data))
}
}
return nil
}
2. 嵌入特定文件列表
import "embed"
//go:embed sqls/query1.sql sqls/query2.sql sqls/query3.sql
var sqlFiles embed.FS
// 读取特定文件
func getSQLContent(filename string) (string, error) {
data, err := sqlFiles.ReadFile(filename)
if err != nil {
return "", err
}
return string(data), nil
}
3. 嵌入子目录及其所有内容
import "embed"
//go:embed sqls
var sqlDir embed.FS
// 递归读取所有文件
func walkSQLFiles() error {
return fs.WalkDir(sqlDir, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if !d.IsDir() {
data, err := sqlDir.ReadFile(path)
if err != nil {
return err
}
fmt.Printf("File: %s\nContent: %s\n", path, string(data))
}
return nil
})
}
4. 为sqload库创建适配器
如果sqload只支持单个文件,可以创建一个包装器:
import (
"embed"
"strings"
"github.com/thirdparty/sqload"
)
//go:embed sqls/*.sql
var sqlFS embed.FS
type MultiFileLoader struct {
fs embed.FS
dir string
}
func NewMultiFileLoader(fs embed.FS, dir string) *MultiFileLoader {
return &MultiFileLoader{fs: fs, dir: dir}
}
func (m *MultiFileLoader) LoadAll() (map[string]string, error) {
queries := make(map[string]string)
entries, err := m.fs.ReadDir(m.dir)
if err != nil {
return nil, err
}
for _, entry := range entries {
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".sql") {
data, err := m.fs.ReadFile(m.dir + "/" + entry.Name())
if err != nil {
return nil, err
}
// 使用文件名(不含扩展名)作为key
name := strings.TrimSuffix(entry.Name(), ".sql")
queries[name] = string(data)
// 如果需要,也可以直接初始化sqload
// loader := sqload.New(string(data))
}
}
return queries, nil
}
// 使用示例
func main() {
loader := NewMultiFileLoader(sqlFS, "sqls")
queries, err := loader.LoadAll()
if err != nil {
panic(err)
}
// 现在可以使用queries map中的SQL语句
for name, sql := range queries {
fmt.Printf("Query %s: %s\n", name, sql)
}
}
5. 合并多个SQL文件为单个字符串
如果sqload必须使用单个字符串:
import (
"embed"
"strings"
)
//go:embed sqls/*.sql
var sqlFS embed.FS
func combineSQLFiles() (string, error) {
var builder strings.Builder
entries, err := sqlFS.ReadDir("sqls")
if err != nil {
return "", err
}
for _, entry := range entries {
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".sql") {
data, err := sqlFS.ReadFile("sqls/" + entry.Name())
if err != nil {
return "", err
}
builder.WriteString("-- " + entry.Name() + "\n")
builder.Write(data)
builder.WriteString("\n\n")
}
}
return builder.String(), nil
}
// 然后使用合并后的字符串初始化sqload
// combinedSQL, _ := combineSQLFiles()
// loader := sqload.New(combinedSQL)
这些方法提供了从嵌入多个文件到适应单文件库的不同解决方案。选择哪种方式取决于你的具体需求和对sqload库的使用方式。

