123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- //go:build mipsle || riscv64
- // +build mipsle riscv64
- package database
- import (
- "encoding/json"
- "errors"
- "log"
- "os"
- "path/filepath"
- "strings"
- "imuslab.com/zoraxy/mod/database/dbinc"
- )
- /*
- OpenWRT or RISCV backend
- For OpenWRT or RISCV platform, we will use the filesystem as the database backend
- as boltdb or leveldb is not supported on these platforms, including boltDB and LevelDB
- in conditional compilation will create a build error on these platforms
- */
- func newDatabase(dbfile string, backendType dbinc.BackendType) (*Database, error) {
- dbRootPath := filepath.ToSlash(filepath.Clean(dbfile))
- dbRootPath = "fsdb/" + dbRootPath
- err := os.MkdirAll(dbRootPath, 0755)
- if err != nil {
- return nil, err
- }
- log.Println("Filesystem Emulated Key-value Database Service Started: " + dbRootPath)
- return &Database{
- Db: dbRootPath,
- BackendType: dbinc.BackendFSOnly,
- Backend: nil,
- }, nil
- }
- func (d *Database) dump(filename string) ([]string, error) {
- //Get all file objects from root
- rootfiles, err := filepath.Glob(filepath.Join(d.Db.(string), "/*"))
- if err != nil {
- return []string{}, err
- }
- //Filter out the folders
- rootFolders := []string{}
- for _, file := range rootfiles {
- if !isDirectory(file) {
- rootFolders = append(rootFolders, filepath.Base(file))
- }
- }
- return rootFolders, nil
- }
- func (d *Database) newTable(tableName string) error {
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- if !fileExists(tablePath) {
- return os.MkdirAll(tablePath, 0755)
- }
- return nil
- }
- func (d *Database) tableExists(tableName string) bool {
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- if _, err := os.Stat(tablePath); errors.Is(err, os.ErrNotExist) {
- return false
- }
- if !isDirectory(tablePath) {
- return false
- }
- return true
- }
- func (d *Database) dropTable(tableName string) error {
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- if d.tableExists(tableName) {
- return os.RemoveAll(tablePath)
- } else {
- return errors.New("table not exists")
- }
- }
- func (d *Database) write(tableName string, key string, value interface{}) error {
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- js, err := json.Marshal(value)
- if err != nil {
- return err
- }
- key = strings.ReplaceAll(key, "/", "-SLASH_SIGN-")
- return os.WriteFile(filepath.Join(tablePath, key+".entry"), js, 0755)
- }
- func (d *Database) read(tableName string, key string, assignee interface{}) error {
- if !d.keyExists(tableName, key) {
- return errors.New("key not exists")
- }
- key = strings.ReplaceAll(key, "/", "-SLASH_SIGN-")
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- entryPath := filepath.Join(tablePath, key+".entry")
- content, err := os.ReadFile(entryPath)
- if err != nil {
- return err
- }
- err = json.Unmarshal(content, &assignee)
- return err
- }
- func (d *Database) keyExists(tableName string, key string) bool {
- key = strings.ReplaceAll(key, "/", "-SLASH_SIGN-")
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- entryPath := filepath.Join(tablePath, key+".entry")
- return fileExists(entryPath)
- }
- func (d *Database) delete(tableName string, key string) error {
- if !d.keyExists(tableName, key) {
- return errors.New("key not exists")
- }
- key = strings.ReplaceAll(key, "/", "-SLASH_SIGN-")
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- entryPath := filepath.Join(tablePath, key+".entry")
- return os.Remove(entryPath)
- }
- func (d *Database) listTable(tableName string) ([][][]byte, error) {
- if !d.tableExists(tableName) {
- return [][][]byte{}, errors.New("table not exists")
- }
- tablePath := filepath.Join(d.Db.(string), filepath.Base(tableName))
- entries, err := filepath.Glob(filepath.Join(tablePath, "/*.entry"))
- if err != nil {
- return [][][]byte{}, err
- }
- var results [][][]byte = [][][]byte{}
- for _, entry := range entries {
- if !isDirectory(entry) {
- //Read it
- key := filepath.Base(entry)
- key = strings.TrimSuffix(key, filepath.Ext(key))
- key = strings.ReplaceAll(key, "-SLASH_SIGN-", "/")
- bkey := []byte(key)
- bval := []byte("")
- c, err := os.ReadFile(entry)
- if err != nil {
- break
- }
- bval = c
- results = append(results, [][]byte{bkey, bval})
- }
- }
- return results, nil
- }
- func (d *Database) close() {
- //Nothing to close as it is file system
- }
- func isDirectory(path string) bool {
- fileInfo, err := os.Stat(path)
- if err != nil {
- return false
- }
- return fileInfo.IsDir()
- }
- func fileExists(name string) bool {
- _, err := os.Stat(name)
- if err == nil {
- return true
- }
- if errors.Is(err, os.ErrNotExist) {
- return false
- }
- return false
- }
|