From bae76e1e441552748789030fdb020a7c773e842b Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Wed, 30 Mar 2022 13:48:56 +0100 Subject: [PATCH 01/21] inital project skaffold --- example-databases/go/log/Makefile | 0 example-databases/go/log/README.md | 0 example-databases/go/log/cmd/main.go | 0 example-databases/go/log/go.mod | 3 +++ example-databases/go/log/pkg/server/dbserver.go | 0 5 files changed, 3 insertions(+) create mode 100644 example-databases/go/log/Makefile create mode 100644 example-databases/go/log/README.md create mode 100644 example-databases/go/log/cmd/main.go create mode 100644 example-databases/go/log/go.mod create mode 100644 example-databases/go/log/pkg/server/dbserver.go diff --git a/example-databases/go/log/Makefile b/example-databases/go/log/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/example-databases/go/log/README.md b/example-databases/go/log/README.md new file mode 100644 index 0000000..e69de29 diff --git a/example-databases/go/log/cmd/main.go b/example-databases/go/log/cmd/main.go new file mode 100644 index 0000000..e69de29 diff --git a/example-databases/go/log/go.mod b/example-databases/go/log/go.mod new file mode 100644 index 0000000..086a870 --- /dev/null +++ b/example-databases/go/log/go.mod @@ -0,0 +1,3 @@ +module github.com/null-channel/null-db + +go 1.17 diff --git a/example-databases/go/log/pkg/server/dbserver.go b/example-databases/go/log/pkg/server/dbserver.go new file mode 100644 index 0000000..e69de29 From 543e3de42bfa5132c178bfadc639392951c4a40a Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Wed, 30 Mar 2022 13:49:30 +0100 Subject: [PATCH 02/21] init server request methods --- .../go/log/pkg/server/dbserver.go | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/example-databases/go/log/pkg/server/dbserver.go b/example-databases/go/log/pkg/server/dbserver.go index e69de29..aba52da 100644 --- a/example-databases/go/log/pkg/server/dbserver.go +++ b/example-databases/go/log/pkg/server/dbserver.go @@ -0,0 +1,20 @@ +package server + +import "log" + +type DbServer struct { + l *log.Logger +} + +type InsertRequest struct { + Key string `json:"key"` + Value string `json:"value"` +} + +type GetRequest struct { + Key string `json:"key"` +} + +type DeleteRequest struct { + Key string `json:"key"` +} From 3bbdcc8fbf79638b63e51f04f7ce8465193252e7 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Wed, 30 Mar 2022 23:52:20 +0100 Subject: [PATCH 03/21] skaffold main.go --- example-databases/go/log/cmd/main.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/example-databases/go/log/cmd/main.go b/example-databases/go/log/cmd/main.go index e69de29..5d64240 100644 --- a/example-databases/go/log/cmd/main.go +++ b/example-databases/go/log/cmd/main.go @@ -0,0 +1,7 @@ +package main + +// var ( +// id, _ = shortid.Generate() +// serverid = fmt.Sprintf("[logdb-%s] ", id) +// l = log.New(os.Stdout, serverid, log.LstdFlags) +// ) From 9f49e3da603adc308c53e17643df55590e287e14 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Wed, 30 Mar 2022 23:53:03 +0100 Subject: [PATCH 04/21] add builder func --- example-databases/go/log/pkg/server/dbserver.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/example-databases/go/log/pkg/server/dbserver.go b/example-databases/go/log/pkg/server/dbserver.go index aba52da..4d12a7e 100644 --- a/example-databases/go/log/pkg/server/dbserver.go +++ b/example-databases/go/log/pkg/server/dbserver.go @@ -18,3 +18,8 @@ type GetRequest struct { type DeleteRequest struct { Key string `json:"key"` } + + +func NewDbServer(l *log.Logger) *DbServer{ + return &DbServer{l} +} From 6a86cc5c97ceb221e0b38d8a32f5afaa66017cf4 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Wed, 30 Mar 2022 23:53:34 +0100 Subject: [PATCH 05/21] create --- .../go/log/pkg/server/db/reader.go | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 example-databases/go/log/pkg/server/db/reader.go diff --git a/example-databases/go/log/pkg/server/db/reader.go b/example-databases/go/log/pkg/server/db/reader.go new file mode 100644 index 0000000..906fff5 --- /dev/null +++ b/example-databases/go/log/pkg/server/db/reader.go @@ -0,0 +1,66 @@ +package db + +import ( + "bufio" + "errors" + "log" + "os" + "reflect" + "strings" + "sync" +) + +// Represents a deleted value +const Tombstone = "~tombstone~" +var ErrorKeyNotFound = errors.New("key not found") + +type DB struct { + mu sync.RWMutex + l *log.Logger + logfile string +} + + +func ReverseSlice(data interface{}) { + value := reflect.ValueOf(data) + if value.Kind() != reflect.Slice { + log.Fatal("invalid data type") + } + valueLen := value.Len() + for i := 0; i <= int((valueLen-1)/2); i++ { + reverseIndex := valueLen -1 - i + tmp := value.Index(reverseIndex).Interface() + value.Index(reverseIndex).Set(value.Index(i)) + value.Index(i).Set(reflect.ValueOf(tmp )) } +} + +func (db *DB) Get(K string) (string, error) { + defer db.mu.RUnlock() + file , err := os.Open(db.logfile) + if err != nil{ + log.Printf("an error occured opening the file: %s",err.Error()) + return "", err + } + defer file.Close() + db.mu.RLock() + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + var data []string + for scanner.Scan() { + data = append(data,scanner.Text()) + } + ReverseSlice(data) + for _ , kv := range data { + key := strings.Split(kv,":") + if key[1] == Tombstone{ + return "", ErrorKeyNotFound + } + if key[0] == K { + return key[1] , nil + } + } + return "", ErrorKeyNotFound + + +} + From 9486240b652715cfeaa9b329668e828821151c0b Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 31 Mar 2022 14:56:58 +0100 Subject: [PATCH 06/21] move db out of pkg/server --- .../go/log/pkg/server/db/reader.go | 66 ------------------- 1 file changed, 66 deletions(-) delete mode 100644 example-databases/go/log/pkg/server/db/reader.go diff --git a/example-databases/go/log/pkg/server/db/reader.go b/example-databases/go/log/pkg/server/db/reader.go deleted file mode 100644 index 906fff5..0000000 --- a/example-databases/go/log/pkg/server/db/reader.go +++ /dev/null @@ -1,66 +0,0 @@ -package db - -import ( - "bufio" - "errors" - "log" - "os" - "reflect" - "strings" - "sync" -) - -// Represents a deleted value -const Tombstone = "~tombstone~" -var ErrorKeyNotFound = errors.New("key not found") - -type DB struct { - mu sync.RWMutex - l *log.Logger - logfile string -} - - -func ReverseSlice(data interface{}) { - value := reflect.ValueOf(data) - if value.Kind() != reflect.Slice { - log.Fatal("invalid data type") - } - valueLen := value.Len() - for i := 0; i <= int((valueLen-1)/2); i++ { - reverseIndex := valueLen -1 - i - tmp := value.Index(reverseIndex).Interface() - value.Index(reverseIndex).Set(value.Index(i)) - value.Index(i).Set(reflect.ValueOf(tmp )) } -} - -func (db *DB) Get(K string) (string, error) { - defer db.mu.RUnlock() - file , err := os.Open(db.logfile) - if err != nil{ - log.Printf("an error occured opening the file: %s",err.Error()) - return "", err - } - defer file.Close() - db.mu.RLock() - scanner := bufio.NewScanner(file) - scanner.Split(bufio.ScanLines) - var data []string - for scanner.Scan() { - data = append(data,scanner.Text()) - } - ReverseSlice(data) - for _ , kv := range data { - key := strings.Split(kv,":") - if key[1] == Tombstone{ - return "", ErrorKeyNotFound - } - if key[0] == K { - return key[1] , nil - } - } - return "", ErrorKeyNotFound - - -} - From e7dea0b45c75091f392f8d1bc9e434c714983e91 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 31 Mar 2022 14:57:11 +0100 Subject: [PATCH 07/21] move db out of pkg/server --- example-databases/go/log/pkg/db/reader.go | 88 +++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 example-databases/go/log/pkg/db/reader.go diff --git a/example-databases/go/log/pkg/db/reader.go b/example-databases/go/log/pkg/db/reader.go new file mode 100644 index 0000000..c390cf9 --- /dev/null +++ b/example-databases/go/log/pkg/db/reader.go @@ -0,0 +1,88 @@ +package db + +import ( + "bufio" + "errors" + "fmt" + "log" + "os" + "reflect" + "strings" + "sync" +) + +// Represents a deleted value +const Tombstone = "~tombstone~" + +var ErrorKeyNotFound = errors.New("key not found") + +type DB struct { + mu sync.RWMutex + l *log.Logger + logfile string +} + +func NewDB(l *log.Logger, lf string) *DB { + return &DB{ + l: l, + logfile: lf, + } +} + +func ReverseSlice(data interface{}) { + value := reflect.ValueOf(data) + if value.Kind() != reflect.Slice { + log.Fatal("invalid data type") + } + valueLen := value.Len() + for i := 0; i <= int((valueLen-1)/2); i++ { + reverseIndex := valueLen - 1 - i + tmp := value.Index(reverseIndex).Interface() + value.Index(reverseIndex).Set(value.Index(i)) + value.Index(i).Set(reflect.ValueOf(tmp)) + } +} + +func (db *DB) Get(K string) (string, error) { + defer db.mu.RUnlock() + file, err := os.Open(db.logfile) + if err != nil { + db.l.Printf("an error occured opening the file: %s", err.Error()) + return "", err + } + defer file.Close() + db.mu.RLock() + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + var data []string + for scanner.Scan() { + data = append(data, scanner.Text()) + } + ReverseSlice(data) + for _, kv := range data { + key := strings.Split(kv, ":") + if key[1] == Tombstone { + return "", ErrorKeyNotFound + } + if key[0] == K { + return key[1], nil + } + } + return "", ErrorKeyNotFound +} + +func (db *DB) Set(k, v string) error { + defer db.mu.Unlock() + db.mu.Lock() + file, err := os.OpenFile(db.logfile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + return err + } + defer file.Close() + text := fmt.Sprintf("%s:%s\n", k, v) + _, err = file.WriteString(text) + if err != nil { + return err + } + return nil +} From 03798d7932e5800dacd045920612552b64c088f9 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 31 Mar 2022 14:57:41 +0100 Subject: [PATCH 08/21] deps :package: --- example-databases/go/log/go.mod | 2 ++ example-databases/go/log/go.sum | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 example-databases/go/log/go.sum diff --git a/example-databases/go/log/go.mod b/example-databases/go/log/go.mod index 086a870..1dc89ba 100644 --- a/example-databases/go/log/go.mod +++ b/example-databases/go/log/go.mod @@ -1,3 +1,5 @@ module github.com/null-channel/null-db go 1.17 + +require github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 diff --git a/example-databases/go/log/go.sum b/example-databases/go/log/go.sum new file mode 100644 index 0000000..0c9ff01 --- /dev/null +++ b/example-databases/go/log/go.sum @@ -0,0 +1,2 @@ +github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w= +github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= From b6255e1c00369e75f76f2c2df06489d8f7ea4ece Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 31 Mar 2022 14:58:34 +0100 Subject: [PATCH 09/21] proof of concept set and get --- example-databases/go/log/cmd/main.go | 50 +++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/example-databases/go/log/cmd/main.go b/example-databases/go/log/cmd/main.go index 5d64240..3a272d3 100644 --- a/example-databases/go/log/cmd/main.go +++ b/example-databases/go/log/cmd/main.go @@ -1,7 +1,47 @@ package main -// var ( -// id, _ = shortid.Generate() -// serverid = fmt.Sprintf("[logdb-%s] ", id) -// l = log.New(os.Stdout, serverid, log.LstdFlags) -// ) +import ( + "fmt" + "log" + "os" + "sync" + + "github.com/null-channel/null-db/pkg/db" + "github.com/teris-io/shortid" +) + +var ( + createlogfile sync.Once + logfile = "log.db" + id, _ = shortid.Generate() + + // unique server id incase this ever becomes distributed?? + serverid = fmt.Sprintf("[logdb-%s] ", id) + l = log.New(os.Stdout, serverid, log.LstdFlags) +) + +func main() { + + // create log file once server starts up + createlogfile.Do(func() { + _, err := os.Create(logfile) + if err != nil { + fmt.Println(err) + } + }) + DB := db.NewDB(l, logfile) + err := DB.Set("hello", "world") + if err != nil { + l.Println(err) + } + + err = DB.Set("hello", "man") + if err != nil { + l.Println(err) + } + str, err := DB.Get("hello") + if err != nil { + l.Println(err) + } + l.Println(str) +} From b709c672edbd33ed591e184c877a0ef15b76ee6a Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 31 Mar 2022 15:37:21 +0100 Subject: [PATCH 10/21] nuke test lines since all operations work now --- example-databases/go/log/cmd/main.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/example-databases/go/log/cmd/main.go b/example-databases/go/log/cmd/main.go index 3a272d3..ac8b4ec 100644 --- a/example-databases/go/log/cmd/main.go +++ b/example-databases/go/log/cmd/main.go @@ -30,18 +30,4 @@ func main() { } }) DB := db.NewDB(l, logfile) - err := DB.Set("hello", "world") - if err != nil { - l.Println(err) - } - - err = DB.Set("hello", "man") - if err != nil { - l.Println(err) - } - str, err := DB.Get("hello") - if err != nil { - l.Println(err) - } - l.Println(str) } From 9cf77e7977bb7ce56100b89a34d0a1c71d75a7f6 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 31 Mar 2022 15:38:16 +0100 Subject: [PATCH 11/21] implement delete --- example-databases/go/log/pkg/db/reader.go | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/example-databases/go/log/pkg/db/reader.go b/example-databases/go/log/pkg/db/reader.go index c390cf9..1c824da 100644 --- a/example-databases/go/log/pkg/db/reader.go +++ b/example-databases/go/log/pkg/db/reader.go @@ -86,3 +86,37 @@ func (db *DB) Set(k, v string) error { } return nil } + +func (db *DB) Delete(K string) (string, error) { + file, err := os.Open(db.logfile) + if err != nil { + db.l.Printf("an error occured opening the file: %s", err.Error()) + return "", err + } + db.mu.Lock() + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + var data []string + for scanner.Scan() { + data = append(data, scanner.Text()) + } + ReverseSlice(data) + file.Close() + for _, kv := range data { + key := strings.Split(kv, ":") + if key[0] == K { + file, err := os.OpenFile(db.logfile, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + return "", err + } + text := fmt.Sprintf("%s:%s\n", K, Tombstone) + _, err = file.WriteString(text) + if err != nil { + return "", err + } + + } + } + defer db.mu.Unlock() + return "", ErrorKeyNotFound +} From 01d816b6f00d3d7318e2efbb1dc12474b0d7a314 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Fri, 1 Apr 2022 15:36:21 +0100 Subject: [PATCH 12/21] rename file --- .../go/log/pkg/server/dbserver.go | 25 ----- .../go/log/pkg/server/logserver.go | 91 +++++++++++++++++++ 2 files changed, 91 insertions(+), 25 deletions(-) delete mode 100644 example-databases/go/log/pkg/server/dbserver.go create mode 100644 example-databases/go/log/pkg/server/logserver.go diff --git a/example-databases/go/log/pkg/server/dbserver.go b/example-databases/go/log/pkg/server/dbserver.go deleted file mode 100644 index 4d12a7e..0000000 --- a/example-databases/go/log/pkg/server/dbserver.go +++ /dev/null @@ -1,25 +0,0 @@ -package server - -import "log" - -type DbServer struct { - l *log.Logger -} - -type InsertRequest struct { - Key string `json:"key"` - Value string `json:"value"` -} - -type GetRequest struct { - Key string `json:"key"` -} - -type DeleteRequest struct { - Key string `json:"key"` -} - - -func NewDbServer(l *log.Logger) *DbServer{ - return &DbServer{l} -} diff --git a/example-databases/go/log/pkg/server/logserver.go b/example-databases/go/log/pkg/server/logserver.go new file mode 100644 index 0000000..777f6d8 --- /dev/null +++ b/example-databases/go/log/pkg/server/logserver.go @@ -0,0 +1,91 @@ +package server + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + + "github.com/null-channel/null-db/pkg/db" +) + +type DbServer struct { + l *log.Logger + logdb *db.DB +} + +type InsertRequest struct { + Key string `json:"key"` + Value string `json:"value"` +} + +type GetRequest struct { + Key string `json:"key"` +} + +type DeleteRequest struct { + Key string `json:"key"` +} + +func NewDbServer(l *log.Logger, db *db.DB) *DbServer { + return &DbServer{l, db} +} + +func (s *DbServer) InsertHandler(rw http.ResponseWriter, r *http.Request) { + s.l.Println("Recived Insert request") + req := InsertRequest{} + err := json.NewDecoder(r.Body).Decode(&req) + if err != nil { + s.l.Println("unable to decode request") + http.Error(rw, "unable to decode request", 500) + return + } + err = s.logdb.Set(req.Key, req.Value) + if err != nil { + s.l.Println("unable to process request") + http.Error(rw, fmt.Sprintf("unable to process request reason %s", err), 404) + return + } + s.l.Printf("Set %s to value %s", req.Key, req.Value) + + rw.Write([]byte(req.Key)) +} + +func (s *DbServer) GetHandler(rw http.ResponseWriter, r *http.Request) { + s.l.Println("received Get request") + req := GetRequest{} + err := json.NewDecoder(r.Body).Decode(&req) + if err != nil { + s.l.Printf("unable to process get request for key %s", req.Key) + http.Error(rw, "unable to process request", http.StatusBadRequest) + return + + } + s.l.Printf("obtaining value for key %s", req.Key) + val, err := s.logdb.Get(req.Key) + if err != nil { + s.l.Println("unable to process request") + http.Error(rw, fmt.Sprintf("%s", err), 404) + return + } + rw.Write([]byte(val)) +} +func (s *DbServer) DeleteHandler(rw http.ResponseWriter, r *http.Request) { + s.l.Printf("received delete request") + req := DeleteRequest{} + err := json.NewDecoder(r.Body).Decode(&req) + if err != nil { + s.l.Println("unable to process request") + http.Error(rw, "unable to process", 500) + return + } + s.l.Printf("deleting key %s", req.Key) + resp, err := s.logdb.Delete(req.Key) + if err != nil { + s.l.Println("unable to process request") + http.Error(rw, fmt.Sprintf("%s", err), 404) + return + } + rw.Write([]byte(resp)) + +} From b56f57982abfa8229e7a8779fa819da4a83182c5 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Fri, 1 Apr 2022 15:36:39 +0100 Subject: [PATCH 13/21] update documentation --- example-databases/go/log/README.md | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/example-databases/go/log/README.md b/example-databases/go/log/README.md index e69de29..9c46546 100644 --- a/example-databases/go/log/README.md +++ b/example-databases/go/log/README.md @@ -0,0 +1,52 @@ +# Log based Key/Value store + +A go implementation of a log based key value store from the null channel's building a database series + +=> link: https://www.youtube.com/playlist?list=PL5JFPVMx5WzV_7j2RoTc7hkx0os4wDJTx + + +Pros: + - it works? + - fast writes + +Cons: + - reads are slow as the log file grows + + +## Todo's + + - [] implement log compaction + - [] implement partitioning + + + +## Usage + +Start the server using + +```bash +make run +``` + + +### adding a key + +```shell +curl -d '{"key":"hey","value":"world"}' -H "Content-Type: application/json" http://localhost:4000/set +``` + +### retreiving a value + +```shell +curl -d '{"key":"hey"}' -H "Content-Type: application/json" http://localhost:4000/get +``` + +### Deleting a value +```shell +curl -d '{"key":"hey"}' -H "Content-Type: application/json" http://localhost:4000/pop +``` + +## Clean up + +`make clean` + \ No newline at end of file From 943243c51ae8b460bc59fa79ca2fcae2d05d5249 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Fri, 1 Apr 2022 15:36:51 +0100 Subject: [PATCH 14/21] add make directives --- example-databases/go/log/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/example-databases/go/log/Makefile b/example-databases/go/log/Makefile index e69de29..332428e 100644 --- a/example-databases/go/log/Makefile +++ b/example-databases/go/log/Makefile @@ -0,0 +1,10 @@ +BINARY_NAME=nulldb-go + +build: + cd cmd && go build -o $(BINARY_NAME) + +run: build + cd cmd &&./$(BINARY_NAME) + +clean: + rm cmd/$(BINARY_NAME) \ No newline at end of file From 41ddf488e101f9ef171278ad69fdb53d074c1ba1 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Fri, 1 Apr 2022 15:37:01 +0100 Subject: [PATCH 15/21] deps :package: --- example-databases/go/log/go.mod | 5 ++++- example-databases/go/log/go.sum | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/example-databases/go/log/go.mod b/example-databases/go/log/go.mod index 1dc89ba..6d59820 100644 --- a/example-databases/go/log/go.mod +++ b/example-databases/go/log/go.mod @@ -2,4 +2,7 @@ module github.com/null-channel/null-db go 1.17 -require github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 +require ( + github.com/gorilla/mux v1.8.0 + github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 +) diff --git a/example-databases/go/log/go.sum b/example-databases/go/log/go.sum index 0c9ff01..16f1ef5 100644 --- a/example-databases/go/log/go.sum +++ b/example-databases/go/log/go.sum @@ -1,2 +1,4 @@ +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w= github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0= From 52fb1e11370efd8a43a6fdb07e9e4be9486b4a07 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Fri, 1 Apr 2022 15:37:27 +0100 Subject: [PATCH 16/21] add handlers --- example-databases/go/log/cmd/main.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/example-databases/go/log/cmd/main.go b/example-databases/go/log/cmd/main.go index ac8b4ec..f1eb940 100644 --- a/example-databases/go/log/cmd/main.go +++ b/example-databases/go/log/cmd/main.go @@ -3,10 +3,13 @@ package main import ( "fmt" "log" + "net/http" "os" "sync" + "github.com/gorilla/mux" "github.com/null-channel/null-db/pkg/db" + "github.com/null-channel/null-db/pkg/server" "github.com/teris-io/shortid" ) @@ -30,4 +33,15 @@ func main() { } }) DB := db.NewDB(l, logfile) + loghandler := server.NewDbServer(l, DB) + router := mux.NewRouter() + router.HandleFunc("/get", loghandler.GetHandler).Methods(http.MethodPost) + router.HandleFunc("/set", loghandler.InsertHandler).Methods(http.MethodPost) + router.HandleFunc("/pop", loghandler.DeleteHandler).Methods(http.MethodPost) + l.Println("starting server on port 4000") + http.Handle("/", router) + err := http.ListenAndServe(":4000", nil) + if err != nil { + l.Fatalf("unable to start server on 4000 %s", err.Error()) + } } From eec944e199b7ccbd7a4eaeedb23191e4c4ea86a1 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Fri, 1 Apr 2022 15:37:57 +0100 Subject: [PATCH 17/21] replace reverse function --- example-databases/go/log/pkg/db/reader.go | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/example-databases/go/log/pkg/db/reader.go b/example-databases/go/log/pkg/db/reader.go index 1c824da..90a1793 100644 --- a/example-databases/go/log/pkg/db/reader.go +++ b/example-databases/go/log/pkg/db/reader.go @@ -6,7 +6,6 @@ import ( "fmt" "log" "os" - "reflect" "strings" "sync" ) @@ -29,18 +28,13 @@ func NewDB(l *log.Logger, lf string) *DB { } } -func ReverseSlice(data interface{}) { - value := reflect.ValueOf(data) - if value.Kind() != reflect.Slice { - log.Fatal("invalid data type") - } - valueLen := value.Len() - for i := 0; i <= int((valueLen-1)/2); i++ { - reverseIndex := valueLen - 1 - i - tmp := value.Index(reverseIndex).Interface() - value.Index(reverseIndex).Set(value.Index(i)) - value.Index(i).Set(reflect.ValueOf(tmp)) +func ReverseSlice(data []string) []string { + m := len(data) - 1 + var out = []string{} + for i := m; i >= 0; i-- { + out = append(out, data[i]) } + return out } func (db *DB) Get(K string) (string, error) { @@ -58,7 +52,7 @@ func (db *DB) Get(K string) (string, error) { for scanner.Scan() { data = append(data, scanner.Text()) } - ReverseSlice(data) + data = ReverseSlice(data) for _, kv := range data { key := strings.Split(kv, ":") if key[1] == Tombstone { From 77dd755ecc787d260b64bc5d2988835792e4ec65 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 7 Apr 2022 00:18:41 +0100 Subject: [PATCH 18/21] rename reader -> db.go --- example-databases/go/log/pkg/db/{reader.go => db.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename example-databases/go/log/pkg/db/{reader.go => db.go} (100%) diff --git a/example-databases/go/log/pkg/db/reader.go b/example-databases/go/log/pkg/db/db.go similarity index 100% rename from example-databases/go/log/pkg/db/reader.go rename to example-databases/go/log/pkg/db/db.go From c63aa5f63617ae0374ea500eeeee31bbcde7c9da Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 7 Apr 2022 00:19:45 +0100 Subject: [PATCH 19/21] accept key as url param --- example-databases/go/log/cmd/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example-databases/go/log/cmd/main.go b/example-databases/go/log/cmd/main.go index f1eb940..1ac3140 100644 --- a/example-databases/go/log/cmd/main.go +++ b/example-databases/go/log/cmd/main.go @@ -35,7 +35,7 @@ func main() { DB := db.NewDB(l, logfile) loghandler := server.NewDbServer(l, DB) router := mux.NewRouter() - router.HandleFunc("/get", loghandler.GetHandler).Methods(http.MethodPost) + router.HandleFunc("/get/{key}", loghandler.GetHandler).Methods(http.MethodGet) router.HandleFunc("/set", loghandler.InsertHandler).Methods(http.MethodPost) router.HandleFunc("/pop", loghandler.DeleteHandler).Methods(http.MethodPost) l.Println("starting server on port 4000") From cad9cd8ba6c75b992dc58b8b7a938b9d28a749e6 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 7 Apr 2022 00:19:54 +0100 Subject: [PATCH 20/21] accept key as url param --- example-databases/go/log/pkg/server/logserver.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/example-databases/go/log/pkg/server/logserver.go b/example-databases/go/log/pkg/server/logserver.go index 777f6d8..13af97c 100644 --- a/example-databases/go/log/pkg/server/logserver.go +++ b/example-databases/go/log/pkg/server/logserver.go @@ -6,6 +6,7 @@ import ( "log" "net/http" + "github.com/gorilla/mux" "github.com/null-channel/null-db/pkg/db" ) @@ -53,16 +54,16 @@ func (s *DbServer) InsertHandler(rw http.ResponseWriter, r *http.Request) { func (s *DbServer) GetHandler(rw http.ResponseWriter, r *http.Request) { s.l.Println("received Get request") - req := GetRequest{} - err := json.NewDecoder(r.Body).Decode(&req) - if err != nil { - s.l.Printf("unable to process get request for key %s", req.Key) - http.Error(rw, "unable to process request", http.StatusBadRequest) + vars := mux.Vars(r) + key := vars["key"] + if key == "" { + s.l.Println("unable to process get request , no key supplied", ) + http.Error(rw, "a key must be supplied", http.StatusBadRequest) return } - s.l.Printf("obtaining value for key %s", req.Key) - val, err := s.logdb.Get(req.Key) + s.l.Printf("obtaining value for key %s", key) + val, err := s.logdb.Get(key) if err != nil { s.l.Println("unable to process request") http.Error(rw, fmt.Sprintf("%s", err), 404) From 0f8ba0b7ffd993e3817ae6fde968152056929426 Mon Sep 17 00:00:00 2001 From: Jubril Oyetunji Date: Thu, 7 Apr 2022 00:20:07 +0100 Subject: [PATCH 21/21] update documentation --- example-databases/go/log/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-databases/go/log/README.md b/example-databases/go/log/README.md index 9c46546..038aeec 100644 --- a/example-databases/go/log/README.md +++ b/example-databases/go/log/README.md @@ -38,7 +38,7 @@ curl -d '{"key":"hey","value":"world"}' -H "Content-Type: application/json" http ### retreiving a value ```shell -curl -d '{"key":"hey"}' -H "Content-Type: application/json" http://localhost:4000/get +curl http://localhost:4000/get/key ``` ### Deleting a value @@ -49,4 +49,4 @@ curl -d '{"key":"hey"}' -H "Content-Type: application/json" http://localhost:400 ## Clean up `make clean` - \ No newline at end of file +