golang编写一个类似sqlite的文件数据库实现增删改查动态改变表结构代码
代码语言:golang
所属分类:其他
代码描述:golang编写一个类似sqlite的文件数据库实现增删改查动态改变表结构代码,实现createtable、insert、update、select、delete,id自增、动态改变表结构等数据库特性,仅供学习。
代码标签: golang 编写 类似 sqlite 文件 数据库 增删 改查 代码 动态 改变 表 结构
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
package main //需要在go1.16以上版本运行 import ( "fmt" "os" "encoding/gob" "sync" "reflect" "bytes" ) type Database struct { filename string tables map[string]*Table mutex sync.RWMutex } type Table struct { Name string Schema map[string]string // 使用字符串来表示类型 Rows []map[string]interface{} NextID int } type SerializableDatabase struct { Tables map[string]*Table } func (db *Database) MarshalBinary() ([]byte, error) { sdb := SerializableDatabase{ Tables: db.tables, } var buf bytes.Buffer enc := gob.NewEncoder(&buf) err := enc.Encode(sdb) return buf.Bytes(), err } func (db *Database) UnmarshalBinary(data []byte) error { var sdb SerializableDatabase buf := bytes.NewBuffer(data) dec := gob.NewDecoder(buf) err := dec.Decode(&sdb) if err != nil { return err } db.tables = sdb.Tables return nil } func NewDatabase(filename string) *Database { db := &Database{ filename: filename, tables: make(map[string]*Table), } err := db.Load() if err != nil && !os.IsNotExist(err) { fmt.Printf("警告: 加载数据库失败: %v\n", err) } return db } func (db *Database) CreateTable(name string, schema map[string]reflect.Type) error { db.mutex.Lock() defer db.mutex.Unlock() if _, exists := db.tables[name]; exists { return fmt.Errorf("表 %s 已存在", name) } schemaStrings := make(map[string]string) for field, typ := range schema { schemaStrings[field] = typ.String() } schemaStrings["id"] = "int" db.tables[name] = &Table{ Name: name, Schema: schemaStrings, Rows: make([]map[string]interface{}, 0), NextID: 1, } return db.Save() } func (db *Database) AddField(tableName, fieldName string, fieldType reflect.Type) error { db.mutex.Lock() defer db.mutex.Unlock() table, exists := db.tables[tableName] if !exists { return fmt.Errorf("表 %s 不存在", tableName) } if _, exists := table.Schema[fieldName]; exists { return fmt.Errorf("字段 %s 已存在", fieldName) } table.Schema[fieldName] = fieldType.String() for i := range table.Rows { table.Rows[i][fieldName] = reflect.Zero(fieldType).Interface() } return db.Save() } func (db *Database) RemoveField(tableName, fieldName string) error { db.mutex.Lock() defer db.mutex.Unlock() table, exists := db.tables[tableName] if !exists { return fmt.Errorf("表 %s 不存在", tableName) } if fieldName == "id" { return fmt.Errorf("不能删除 id 字段") } if _, exists := table.Schema[fieldName]; !exists { return fmt.Errorf("字段 %s 不存在", fieldName) } delete(table.Schema, fieldName) for i := range table.Rows { delete(table.Rows[i], fieldName) } return db.Save() } func (db *Database) Insert(tableName string, values map[string]interface{}) error { db.mutex.Lock() defer db.mutex.Unlock() table, exists := db.tables[tableName] if !exists { return fmt.Errorf("表 %s 不存在", tableName) } newRow := make(map[string]interface{}) for field, typeStr := range table.Schema { if field == "id" { newRow[field] = table.NextID continue } value, exists := values[field] if !exists { newRow[field] = reflect.Zero(typeOf(typeStr)).Interface() } else if reflect.TypeOf(value).String() != typeStr { return fmt.Errorf("字段 %s 的类型不匹配", field) } else { newRow[field] = value } } table.Rows = append(table.Rows, newRow) table.NextID++ return db.Save() } func (db *Database) Update(tableName string, id int, updates map[string]interface{}) error { db.mutex.Lock() defer db.mutex.Unlock() table, exists := db.tables[tableName] if !exists { return fmt.Errorf("表 %s 不存在", tableName) } for i, row := range table.Rows { if row["id"].(int) == id { for field, value := range updates { if field == "id" { return fmt.Errorf("不能更新 id 字段") } if typeStr, exists.........完整代码请登录后点击上方下载按钮下载查看
网友评论0