mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-08-13 00:19:21 +02:00
init commit
This commit is contained in:
240
mod/database/database.go
Normal file
240
mod/database/database.go
Normal file
@@ -0,0 +1,240 @@
|
||||
package database
|
||||
|
||||
/*
|
||||
ArOZ Online Database Access Module
|
||||
author: tobychui
|
||||
|
||||
This is an improved Object oriented base solution to the original
|
||||
aroz online database script.
|
||||
*/
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
Db *bolt.DB
|
||||
Tables sync.Map
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
func NewDatabase(dbfile string, readOnlyMode bool) (*Database, error) {
|
||||
db, err := bolt.Open(dbfile, 0600, nil)
|
||||
log.Println("Key-value Database Service Started: " + dbfile)
|
||||
|
||||
tableMap := sync.Map{}
|
||||
//Build the table list from database
|
||||
err = db.View(func(tx *bolt.Tx) error {
|
||||
return tx.ForEach(func(name []byte, _ *bolt.Bucket) error {
|
||||
tableMap.Store(string(name), "")
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
return &Database{
|
||||
Db: db,
|
||||
Tables: tableMap,
|
||||
ReadOnly: readOnlyMode,
|
||||
}, err
|
||||
}
|
||||
|
||||
/*
|
||||
Create / Drop a table
|
||||
Usage:
|
||||
err := sysdb.NewTable("MyTable")
|
||||
err := sysdb.DropTable("MyTable")
|
||||
*/
|
||||
|
||||
func (d *Database) UpdateReadWriteMode(readOnly bool) {
|
||||
d.ReadOnly = readOnly
|
||||
}
|
||||
|
||||
//Dump the whole db into a log file
|
||||
func (d *Database) Dump(filename string) ([]string, error) {
|
||||
results := []string{}
|
||||
|
||||
d.Tables.Range(func(tableName, v interface{}) bool {
|
||||
entries, err := d.ListTable(tableName.(string))
|
||||
if err != nil {
|
||||
log.Println("Reading table " + tableName.(string) + " failed: " + err.Error())
|
||||
return false
|
||||
}
|
||||
for _, keypairs := range entries {
|
||||
results = append(results, string(keypairs[0])+":"+string(keypairs[1])+"\n")
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
//Create a new table
|
||||
func (d *Database) NewTable(tableName string) error {
|
||||
if d.ReadOnly == true {
|
||||
return errors.New("Operation rejected in ReadOnly mode")
|
||||
}
|
||||
|
||||
err := d.Db.Update(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists([]byte(tableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
d.Tables.Store(tableName, "")
|
||||
return err
|
||||
}
|
||||
|
||||
//Check is table exists
|
||||
func (d *Database) TableExists(tableName string) bool {
|
||||
if _, ok := d.Tables.Load(tableName); ok {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//Drop the given table
|
||||
func (d *Database) DropTable(tableName string) error {
|
||||
if d.ReadOnly == true {
|
||||
return errors.New("Operation rejected in ReadOnly mode")
|
||||
}
|
||||
|
||||
err := d.Db.Update(func(tx *bolt.Tx) error {
|
||||
err := tx.DeleteBucket([]byte(tableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
Write to database with given tablename and key. Example Usage:
|
||||
type demo struct{
|
||||
content string
|
||||
}
|
||||
thisDemo := demo{
|
||||
content: "Hello World",
|
||||
}
|
||||
err := sysdb.Write("MyTable", "username/message",thisDemo);
|
||||
*/
|
||||
func (d *Database) Write(tableName string, key string, value interface{}) error {
|
||||
if d.ReadOnly == true {
|
||||
return errors.New("Operation rejected in ReadOnly mode")
|
||||
}
|
||||
|
||||
jsonString, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = d.Db.Update(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists([]byte(tableName))
|
||||
b := tx.Bucket([]byte(tableName))
|
||||
err = b.Put([]byte(key), jsonString)
|
||||
return err
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
Read from database and assign the content to a given datatype. Example Usage:
|
||||
|
||||
type demo struct{
|
||||
content string
|
||||
}
|
||||
thisDemo := new(demo)
|
||||
err := sysdb.Read("MyTable", "username/message",&thisDemo);
|
||||
*/
|
||||
|
||||
func (d *Database) Read(tableName string, key string, assignee interface{}) error {
|
||||
err := d.Db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(tableName))
|
||||
v := b.Get([]byte(key))
|
||||
json.Unmarshal(v, &assignee)
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Database) KeyExists(tableName string, key string) bool {
|
||||
resultIsNil := false
|
||||
err := d.Db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(tableName))
|
||||
v := b.Get([]byte(key))
|
||||
if v == nil {
|
||||
resultIsNil = true
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return false
|
||||
} else {
|
||||
if resultIsNil {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Delete a value from the database table given tablename and key
|
||||
|
||||
err := sysdb.Delete("MyTable", "username/message");
|
||||
*/
|
||||
func (d *Database) Delete(tableName string, key string) error {
|
||||
if d.ReadOnly == true {
|
||||
return errors.New("Operation rejected in ReadOnly mode")
|
||||
}
|
||||
|
||||
err := d.Db.Update(func(tx *bolt.Tx) error {
|
||||
tx.Bucket([]byte(tableName)).Delete([]byte(key))
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
//List table example usage
|
||||
//Assume the value is stored as a struct named "groupstruct"
|
||||
|
||||
entries, err := sysdb.ListTable("test")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, keypairs := range entries{
|
||||
log.Println(string(keypairs[0]))
|
||||
group := new(groupstruct)
|
||||
json.Unmarshal(keypairs[1], &group)
|
||||
log.Println(group);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
func (d *Database) ListTable(tableName string) ([][][]byte, error) {
|
||||
var results [][][]byte
|
||||
err := d.Db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte(tableName))
|
||||
c := b.Cursor()
|
||||
|
||||
for k, v := c.First(); k != nil; k, v = c.Next() {
|
||||
results = append(results, [][]byte{k, v})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (d *Database) Close() {
|
||||
d.Db.Close()
|
||||
return
|
||||
}
|
44
mod/database/doc.txt
Normal file
44
mod/database/doc.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
package database // import "imuslab.com/arozos/mod/database"
|
||||
|
||||
|
||||
TYPES
|
||||
|
||||
type Database struct {
|
||||
Db *bolt.DB
|
||||
ReadOnly bool
|
||||
}
|
||||
|
||||
func NewDatabase(dbfile string, readOnlyMode bool) (*Database, error)
|
||||
|
||||
func (d *Database) Close()
|
||||
|
||||
func (d *Database) Delete(tableName string, key string) error
|
||||
Delete a value from the database table given tablename and key
|
||||
|
||||
err := sysdb.Delete("MyTable", "username/message");
|
||||
|
||||
func (d *Database) DropTable(tableName string) error
|
||||
|
||||
func (d *Database) KeyExists(tableName string, key string) bool
|
||||
|
||||
func (d *Database) ListTable(tableName string) ([][][]byte, error)
|
||||
|
||||
func (d *Database) NewTable(tableName string) error
|
||||
|
||||
func (d *Database) Read(tableName string, key string, assignee interface{}) error
|
||||
|
||||
func (d *Database) UpdateReadWriteMode(readOnly bool)
|
||||
|
||||
func (d *Database) Write(tableName string, key string, value interface{}) error
|
||||
Write to database with given tablename and key. Example Usage: type demo
|
||||
struct{
|
||||
|
||||
content string
|
||||
|
||||
} thisDemo := demo{
|
||||
|
||||
content: "Hello World",
|
||||
|
||||
} err := sysdb.Write("MyTable", "username/message",thisDemo);
|
||||
|
Reference in New Issue
Block a user