Skip to content

Commit

Permalink
flags
Browse files Browse the repository at this point in the history
  • Loading branch information
chirst committed Jun 29, 2024
1 parent 8d8af2a commit 10595ea
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}",
"program": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ literal --> rparen2
colSep2 --> rparen2
```

## Flags
Run `cdb -h` for command line flags.

## Architecture
```mermaid
---
Expand Down
14 changes: 8 additions & 6 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ type dbCatalog interface {
}

type DB struct {
vm executor
catalog dbCatalog
vm executor
catalog dbCatalog
UseMemory bool
}

func New(useMemory bool) (*DB, error) {
kv, err := kv.New(useMemory)
func New(useMemory bool, filename string) (*DB, error) {
kv, err := kv.New(useMemory, filename)
if err != nil {
return nil, err
}
return &DB{
vm: vm.New(kv),
catalog: kv.GetCatalog(),
vm: vm.New(kv),
catalog: kv.GetCatalog(),
UseMemory: useMemory,
}, nil
}

Expand Down
4 changes: 2 additions & 2 deletions db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

func TestExecute(t *testing.T) {
t.Run("create, select schema, insert, select", func(t *testing.T) {
db, err := New(true)
db, err := New(true, "")
if err != nil {
t.Fatal(err.Error())
}
Expand Down Expand Up @@ -58,7 +58,7 @@ func TestExecute(t *testing.T) {
})

t.Run("bulk insert", func(t *testing.T) {
db, err := New(true)
db, err := New(true, "")
if err != nil {
t.Fatal(err.Error())
}
Expand Down
4 changes: 2 additions & 2 deletions kv/kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ type KV struct {
catalog *catalog
}

func New(useMemory bool) (*KV, error) {
pager, err := pager.New(useMemory)
func New(useMemory bool, filename string) (*KV, error) {
pager, err := pager.New(useMemory, filename)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions kv/kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

func TestKv(t *testing.T) {
t.Run("get", func(t *testing.T) {
kv, _ := New(true)
kv, _ := New(true, "")
k := []byte{1}
v := []byte{'n', 'e', 'd'}
kv.Set(1, k, v)
Expand All @@ -24,7 +24,7 @@ func TestKv(t *testing.T) {
})

t.Run("set page split", func(t *testing.T) {
kv, _ := New(true)
kv, _ := New(true, "")
var rk []byte
var rv []byte
ri := 178
Expand Down Expand Up @@ -58,7 +58,7 @@ func TestKv(t *testing.T) {
})

t.Run("test bulk insert and get", func(t *testing.T) {
kv, _ := New(true)
kv, _ := New(true, "")
amount := 500_000
kv.BeginWriteTransaction()
for i := 1; i <= amount; i += 1 {
Expand Down
10 changes: 9 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package main

import (
"flag"
"log"

"github.com/chirst/cdb/db"
"github.com/chirst/cdb/pager"
"github.com/chirst/cdb/repl"
)

const fFlagHelp = "Specify the database file name"
const mFlagHelp = "Run the database in memory with no persistence"

func main() {
db, err := db.New(false)
dbfName := flag.String("f", pager.DefaultDBFileName, fFlagHelp)
isMemory := flag.Bool("m", false, mFlagHelp)
flag.Parse()
db, err := db.New(*isMemory, *dbfName)
if err != nil {
log.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

func TestBulk(t *testing.T) {
d, _ := db.New(true)
d, _ := db.New(true, "")
r := d.Execute("CREATE TABLE test (id INTEGER, junk TEXT)")
if r.Err != nil {
t.Fatal(r.Err.Error())
Expand Down
15 changes: 9 additions & 6 deletions pager/pager.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ import (
// +---------+

const (
// journalFileName is the name of the file the rollback journal uses.
journalFileName = "journal.db"
// dbFileName is the name of the file the database uses.
dbFileName = "db.db" // TODO make dynamic
// journalSuffix is the suffix of the filename the rollback journal uses.
// If the database file is called cdb.db a journal will be called
// cdb-journal.db
journalSuffix = "-journal"
// DefaultDBFileName is the default name of the file the database uses. The
// file extension is .db.
DefaultDBFileName = "cdb"
// pageCacheSize is maximum amount of pages that can be cached in memory.
pageCacheSize = 1000
)
Expand Down Expand Up @@ -124,13 +127,13 @@ type Pager struct {
// New creates a new pager. The useMemory flag means the database will not
// create a file or persist changes to disk. This is useful for testing
// purposes.
func New(useMemory bool) (*Pager, error) {
func New(useMemory bool, filename string) (*Pager, error) {
var s storage
var err error
if useMemory {
s = newMemoryStorage()
} else {
s, err = newFileStorage()
s, err = newFileStorage(filename)
}
if err != nil {
return nil, err
Expand Down
10 changes: 5 additions & 5 deletions pager/pager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

func TestPageHelpers(t *testing.T) {
pager, err := New(true)
pager, err := New(true, "")
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -88,7 +88,7 @@ func TestPageHelpers(t *testing.T) {

func TestPageSet(t *testing.T) {
t.Run("set", func(t *testing.T) {
pager, err := New(true)
pager, err := New(true, "")
if err != nil {
t.Fatal(err)
}
Expand All @@ -115,7 +115,7 @@ func TestPageSet(t *testing.T) {
})

t.Run("set update", func(t *testing.T) {
pager, err := New(true)
pager, err := New(true, "")
if err != nil {
t.Fatal(err)
}
Expand All @@ -136,7 +136,7 @@ func TestPageSet(t *testing.T) {
func TestGet(t *testing.T) {

t.Run("get", func(t *testing.T) {
pager, err := New(true)
pager, err := New(true, "")
if err != nil {
t.Fatal(err)
}
Expand All @@ -157,7 +157,7 @@ func TestGet(t *testing.T) {
})

t.Run("get not found", func(t *testing.T) {
pager, err := New(true)
pager, err := New(true, "")
if err != nil {
t.Fatal(err)
}
Expand Down
48 changes: 35 additions & 13 deletions pager/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,40 +53,62 @@ func (mf *memoryStorage) DeleteJournal() error {
}

type fileStorage struct {
file *os.File
file *os.File
journalName string
dbFileName string
}

func newFileStorage() (storage, error) {
jfl, err := os.OpenFile(journalFileName, os.O_RDWR, 0644)
func newFileStorage(filename string) (storage, error) {
dName := getFileName(filename)
jName := getJournalName(filename)
jfl, err := os.OpenFile(jName, os.O_RDWR, 0644)
// if journal file doesn't exist open normal db file
if err != nil && os.IsNotExist(err) {
fl, err := os.OpenFile(dbFileName, os.O_RDWR|os.O_CREATE, 0644)
fl, err := os.OpenFile(dName, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return nil, fmt.Errorf("error opening db file: %w", err)
}
return &fileStorage{
file: fl,
file: fl,
dbFileName: dName,
journalName: jName,
}, nil
}
// if journal file has an error
if err != nil {
return nil, fmt.Errorf("error opening journal: %w", err)
}
// if no error opening journal use journal as main file
fl, err := os.OpenFile(dbFileName, os.O_RDWR|os.O_CREATE, 0644)
fl, err := os.OpenFile(dName, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return nil, fmt.Errorf("error opening db file to restore journal: %w", err)
}
_, err = io.Copy(fl, jfl)
if err != nil {
return nil, fmt.Errorf("error copying journal to db file: %w", err)
}
os.Remove(journalFileName)
os.Remove(jName)
return &fileStorage{
file: fl,
file: fl,
dbFileName: dName,
journalName: jName,
}, nil
}

func getFileName(filename string) string {
if filename == "" {
return fmt.Sprintf("%s.db", DefaultDBFileName)
}
return fmt.Sprintf("%s.db", filename)
}

func getJournalName(filename string) string {
if filename == "" {
return fmt.Sprintf("%s%s.db", DefaultDBFileName, journalSuffix)
}
return fmt.Sprintf("%s%s.db", filename, journalSuffix)
}

func (s *fileStorage) WriteAt(p []byte, off int64) (n int, err error) {
return s.file.WriteAt(p, off)
}
Expand All @@ -96,20 +118,20 @@ func (s *fileStorage) ReadAt(p []byte, off int64) (n int, err error) {
}

func (s *fileStorage) CreateJournal() error {
f, err := os.OpenFile(journalFileName, os.O_RDWR|os.O_CREATE, 0644)
f, err := os.OpenFile(s.journalName, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return err
return fmt.Errorf("error creating journal %w", err)
}
if f.Close() != nil {
return err
return fmt.Errorf("error closing journal %w", err)
}
return nil
}

func (s *fileStorage) DeleteJournal() error {
err := os.Remove(journalFileName)
err := os.Remove(s.journalName)
if err != nil {
return err
return fmt.Errorf("error deleting journal %w", err)
}
return nil
}
9 changes: 9 additions & 0 deletions repl/repl.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ const (
emptyHeaderValue = "<anonymous>"
)

// ansi are codes that will color terminal output
const (
ansiWarn = "\033[33m"
ansiReset = "\033[0m"
)

type repl struct {
db *db.DB
}
Expand All @@ -27,6 +33,9 @@ func New(db *db.DB) *repl {

func (r *repl) Run() {
fmt.Println("Welcome to cdb. Type .exit to exit")
if r.db.UseMemory {
fmt.Println(ansiWarn + "WARN database is running in memory and will not persist changes" + ansiReset)
}
reader := bufio.NewScanner(os.Stdin)
for r.getInput(reader) {
input := reader.Text()
Expand Down
2 changes: 1 addition & 1 deletion vm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func TestExec(t *testing.T) {
kv, err := kv.New(true)
kv, err := kv.New(true, "")
if err != nil {
log.Fatal(err.Error())
}
Expand Down

0 comments on commit 10595ea

Please sign in to comment.