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