Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
fc95236
Initial commit
777777miSSU7777777 Nov 19, 2018
2de422f
Added json encode & decode for map
777777miSSU7777777 Nov 20, 2018
01fbd78
Added string & bytes file writing & reading
777777miSSU7777777 Nov 20, 2018
fda4df2
Changed dir struct & added comments to existing modules
777777miSSU7777777 Nov 20, 2018
ce5848a
Added comments for json util & marshal indent and fixedjson decode fu…
777777miSSU7777777 Nov 20, 2018
289dfef
Added inmemory service
777777miSSU7777777 Nov 20, 2018
be48fab
Added inmemory storage init & query service
777777miSSU7777777 Nov 20, 2018
253c4f4
Changed value to string type
777777miSSU7777777 Nov 20, 2018
b2c4cb2
The project was divided into client and server side for docker file c…
777777miSSU7777777 Nov 21, 2018
f4ddf5f
Now you need manually init in-memory storage
777777miSSU7777777 Nov 21, 2018
66a7458
Added handlers & entry point for server
777777miSSU7777777 Nov 21, 2018
21de01d
Query & In-Memory services moved to storage package dir
777777miSSU7777777 Nov 21, 2018
d9f60c6
Added logging & fixed storage package imports & refactored entry poin…
777777miSSU7777777 Nov 22, 2018
f3f9798
Added logging to json package & fixed nil assignment map panic in jso…
777777miSSU7777777 Nov 22, 2018
0fc2cab
Added logging to file package
777777miSSU7777777 Nov 22, 2018
0661dc0
Added logging to inmemory package & add behaviour if db file not exist
777777miSSU7777777 Nov 22, 2018
e964f87
Fixed saving to db with memory mode
777777miSSU7777777 Nov 22, 2018
9872c8a
Fixed logging in in-memory service
777777miSSU7777777 Nov 22, 2018
c8b30bb
Started work on keys command
777777miSSU7777777 Nov 22, 2018
6d62021
Keys with pattern feature completed
777777miSSU7777777 Nov 23, 2018
abb8101
Fixed crash on incorrect pattern in keys feature
777777miSSU7777777 Nov 23, 2018
576e95e
Added getter to storage & comment to Keys func
777777miSSU7777777 Nov 23, 2018
4af3fe8
Fixed 'set' query handle
777777miSSU7777777 Nov 23, 2018
d45617f
Removed forgotten query service from util package dir
777777miSSU7777777 Nov 24, 2018
9876dad
Removed forgotten in-memory service from util package dir
777777miSSU7777777 Nov 24, 2018
71042a5
Fixed imports in query handler
777777miSSU7777777 Nov 24, 2018
76519ad
Started working on client side and moved util package out
777777miSSU7777777 Nov 24, 2018
ba8aaec
Mov logger out of server & fixed imports for logger & added connectio…
777777miSSU7777777 Nov 24, 2018
9e479ae
Added exit command for client & server exit command handle
777777miSSU7777777 Nov 24, 2018
0eccdaa
Removed query service & instead of added sync map with interface & ad…
777777miSSU7777777 Nov 27, 2018
31e6b92
Added writing & reading of unknown length messages between server and…
777777miSSU7777777 Nov 29, 2018
3762e78
Removed indent from json encoder & added dump feature
777777miSSU7777777 Nov 30, 2018
1e6390e
Completed dump & restore feature and added .gitignore
777777miSSU7777777 Dec 2, 2018
f127519
Added collection util package & slice util with index func
777777miSSU7777777 Dec 3, 2018
cc9ec1a
Added hardcoded topic with subscribe & publish features
777777miSSU7777777 Dec 3, 2018
8675b95
Added functions with indent for pack to json
777777miSSU7777777 Dec 3, 2018
92ec5cd
Server's query handler reworked using regexp
777777miSSU7777777 Dec 3, 2018
13c4c38
Removed print for debug in server's query handler
777777miSSU7777777 Dec 3, 2018
834e03f
Server's connection handler reworked using regexp & subcribe/publish …
777777miSSU7777777 Dec 4, 2018
bb0b97d
Added regex util
777777miSSU7777777 Dec 4, 2018
8f2270d
Reworked connection & query handle using mix of regexp and str split
777777miSSU7777777 Dec 4, 2018
4b08f29
Refactored client's connection handler
777777miSSU7777777 Dec 4, 2018
967c20e
Fixed func signature in client
777777miSSU7777777 Dec 6, 2018
7e13475
Added comments to client's, server's dir's packages
777777miSSU7777777 Dec 6, 2018
50ea5fa
Added comments to util package's dir & fixed variables & funcs naming
777777miSSU7777777 Dec 6, 2018
617f140
Refactored variables naming
777777miSSU7777777 Dec 7, 2018
bd70dc1
Added regex for publish & (un)subcribe
777777miSSU7777777 Dec 7, 2018
3705fe2
Fixed cases when server/client crashes
777777miSSU7777777 Dec 7, 2018
1111dea
Variable naming fix
777777miSSU7777777 Dec 7, 2018
7c62633
Made request handling more confident against crashes
777777miSSU7777777 Dec 7, 2018
7365f71
Fixed keys feature
777777miSSU7777777 Dec 7, 2018
8bedb5b
Moved sync.Map from server's dir package to util
777777miSSU7777777 Dec 7, 2018
0a71b08
Moved HandleRequest func body to main to avoid pointless rune switch …
777777miSSU7777777 Dec 8, 2018
130f25a
Removed Index func from util because it unused
777777miSSU7777777 Dec 10, 2018
705080a
Added *.out files to gitignore
777777miSSU7777777 Dec 10, 2018
3c6533c
Added unit tests for util/file package
777777miSSU7777777 Dec 10, 2018
d75c4f8
Added unit tests for util/json package
777777miSSU7777777 Dec 10, 2018
d133685
Added unit tests for util/collection package
777777miSSU7777777 Dec 10, 2018
58e1b85
Added unit tests for util/regex package
777777miSSU7777777 Dec 10, 2018
dabf786
Added unit tests for util/sync package
777777miSSU7777777 Dec 10, 2018
731b66a
Fixed restore feature
777777miSSU7777777 Dec 10, 2018
85eee19
Updated unit tests in util/regex package
777777miSSU7777777 Dec 10, 2018
912b6aa
Made storage in in-memory service pointer instead value
777777miSSU7777777 Dec 12, 2018
90e4139
Added unit tests for storage/inmemory package
777777miSSU7777777 Dec 12, 2018
9311053
Made query handler more independent & fixed dependencies
777777miSSU7777777 Dec 12, 2018
a6262e8
Fixed keys feature in sync map
777777miSSU7777777 Dec 12, 2018
a76cb95
Fixed handle for keys feature in query handler
777777miSSU7777777 Dec 12, 2018
b4cd0ca
Added unit tests for query handler
777777miSSU7777777 Dec 12, 2018
2eb5afa
Changed prefix in client cmd from 'NonRelDb' to server's adr
777777miSSU7777777 Dec 12, 2018
a81cd62
Changed names for entrypoint files
777777miSSU7777777 Dec 12, 2018
33d9eaa
Fixed .gitignore for binaries & out & json files
777777miSSU7777777 Dec 12, 2018
bc5032b
Deleted old entry points files
777777miSSU7777777 Dec 13, 2018
587485d
Added VERSION file
777777miSSU7777777 Dec 14, 2018
a80ef8c
Added Dockerfile
777777miSSU7777777 Dec 14, 2018
9cef861
Fixed sync map tests
777777miSSU7777777 Dec 14, 2018
90e7408
Added Makefile
777777miSSU7777777 Dec 14, 2018
ba0a783
Fixed errors occured with golint
777777miSSU7777777 Dec 14, 2018
4dac520
Added common coverage.out & coverage html generation
777777miSSU7777777 Dec 14, 2018
6c965b2
Fixed tests for sync map
777777miSSU7777777 Dec 14, 2018
72e4664
Optimized Makefile
777777miSSU7777777 Dec 14, 2018
1e3eb5a
Refactored code style using goimports
777777miSSU7777777 Dec 14, 2018
2bd2bfc
Added goimports & golint to dockerfile and checks(go vet, goimports,…
777777miSSU7777777 Dec 14, 2018
0baa3c1
Deleted VERSION file because it's useless
777777miSSU7777777 Dec 14, 2018
c1081d3
Imporved & optimized Makefile
777777miSSU7777777 Dec 14, 2018
6bd307d
Fixed golint in check target
777777miSSU7777777 Dec 14, 2018
a6d5f80
Added requirements
777777miSSU7777777 Dec 14, 2018
3ee27ff
Fixed Dockerfile dependencies
777777miSSU7777777 Dec 14, 2018
ce2652b
Fixed checks in Makefile & Dockerfile
777777miSSU7777777 Dec 14, 2018
92efa4b
Now command must contain letters with same register
777777miSSU7777777 Dec 14, 2018
99ad964
Fixed restore regex
777777miSSU7777777 Dec 15, 2018
92df5c1
Removed unused mkdir from dockerfile
777777miSSU7777777 Dec 16, 2018
8e542db
Fixed checks in makefile & dockerfile
777777miSSU7777777 Dec 16, 2018
9bc9324
Changed ip flag to host flag
777777miSSU7777777 Dec 16, 2018
2103e55
Fixed server's location flag description
777777miSSU7777777 Dec 16, 2018
b6ca36c
Update README.md
777777miSSU7777777 Dec 16, 2018
2fb120b
Update README.md
777777miSSU7777777 Dec 16, 2018
574745a
Update README.md
777777miSSU7777777 Dec 17, 2018
d47ca3a
Divided clean into two targets, added docker clean before build & run…
777777miSSU7777777 Dec 17, 2018
1b25ee5
Update README.md
777777miSSU7777777 Dec 17, 2018
5ac6a96
Update README.md
777777miSSU7777777 Dec 17, 2018
2971d16
Update README.md
777777miSSU7777777 Dec 17, 2018
9d4f3ee
Fixed README.md
777777miSSU7777777 Dec 17, 2018
226e075
Update README.md
777777miSSU7777777 Dec 19, 2018
4b79df1
Update README.md
777777miSSU7777777 Dec 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
client/client
server/server
*.out
*.json
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
FROM golang:1.11-alpine3.8

EXPOSE 9090

# Preparation stage.
RUN apk add build-base

RUN apk update && apk upgrade && apk add git

RUN go get golang.org/x/tools/cmd/goimports

RUN go get -u golang.org/x/lint/golint

RUN go get github.com/stretchr/testify

ADD . /go/src/NonRelDB/

# Check stage.
WORKDIR /go/src/NonRelDB

RUN go vet ./...

RUN goimports ./

RUN golint ./...

# Build stage.
WORKDIR /go/src/NonRelDB/server

RUN go build server.go

WORKDIR /go/src/NonRelDB/client

RUN go build client.go

# Entrypoint bind.
ENTRYPOINT [ "/go/src/NonRelDB/server/server" ]

21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 777777miSSU7777777

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
CURRENT_DIR = $(shell pwd)

check:
go vet ./...

goimports ./

golint ./...

clean-binaries:
rm server/server && rm client/client

build-server:
go build -o server/server $(CURRENT_DIR)/server/server.go

build-client:
go build -o client/client $(CURRENT_DIR)/client/client.go

clean:
sudo docker system prune

build: clean
sudo docker build -t "nonreldb" .

run: clean
sudo docker run -d --net=host nonreldb

test:
echo "Running unit & integration tests"

go test ./... -coverprofile coverage.out

go tool cover -html=coverage.out




Binary file added Project.pdf
Binary file not shown.
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
## NonRelDB

NonRelDB is an in-memory database that persists on disk. The data model is key-value. Written on pure golang.

## Installation
First of all you need to install [git](https://git-scm.com/) and [docker](https://www.docker.com/)
Then you need to clone repository on your pc from github

git clone https://github.com/777777miSSU7777777/NonRelDB.git

In cloned repository you will find **Makefile** with following targets:

- **build-server** - builds server's executable binary file.
- **build-client** - builds client's executable binary file.
- **clean-binaries** - removes server's & client's binaries on local machine.
- **build** - copies server's & client's & dependencies src, adds go vet, goimports and golint. Runs checks and if no errors were occured, builds server's & client's binaries. Entrypoint is server with default configuration.
- **clean** - cleans docker's unused containers, networks, volumes and dangling images.
- **check** - runs subsequently go vet, goimports and golint on the project. Fails if any error occurs.
- **test** - runs unit & integration tests. Fails if any test don't pass.
- **run** - runs built docker container in detached mode.
## Usage
### Server's flags
- **-host -h** - defines host ip (default is 127.0.0.1)
- **-port -p** - defines host port (default is 9090)
- **-mode -m** - defines storage location (default is "memory"). Possible options are "memory" and "disk".
- **-location -l** - defines storage location on disk (default is "storage.json").
### Client's flags
- **-host -h** - defines host ip (default is 127.0.0.1)
- **-port -p** - defines host port (default is 9090)
- **--dump** - requests full database dump in json format on stdout.
Usage example

./client --dump > dump.json

- **--restore** - restores database from stdin.
Usage example


./client --restore < dump.json

### Commands
Commands can be entered only in one register (**GET** and **get** but not **Get**).

**List of supported commands**
- **GET** - returns the value if existing, otherwise message "Value with this key not found".
Example


GET 123


- **SET** - set the value if existing, otherwise creates new. Also returns message "Value has changed".
**Value must be in double quotes.*
Example


SET 123 "123"


- **DEL** - deletes value from storage and returns it's value if existing, otherwise message "Value with this key not found".
Example


DEL 123

- **KEYS** - returns all keys matching to entered regexp pattern, otherwise message "Keys with this pattern not found" or "Pattern is incorrect".
**Regex pattern must be in double quotes.*
Example

KEYS "/*"

- **SUBSCRIBE** - subscribes the client on specified channel.
Example

SUBSCRIBE redis

- **UNSUBSCRIBE** - unsubscribes the client from specified channel.
**Cannot use from client because after subscribe client turns into listening state.*
Example

UNSUBSCRIBE redis

- **PUBLISH** - sends the message to specified channel.
*\*Message must be in double quotes.*
Example

PUBLISH redis "Hello world"

## Project requirements

- There no verbose mode and flag because logger any way logs full user's request.
- Not implemented TAB completion of the commands in cli.

## Notice
- Server & client will crash with non-existing flag's values.
- Not implented -help flag.
63 changes: 63 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package main

import (
"NonRelDB/client/handler"
"NonRelDB/log"
"bufio"
"flag"
"fmt"
"net"
"os"
)

var host string
var port string
var dump bool
var restore bool
var location string

func init() {
flag.StringVar(&host, "host", "127.0.0.1", "Defines host ip")
flag.StringVar(&host, "h", "127.0.0.1", "Defines host ip")
flag.StringVar(&port, "port", "9090", "Defines host port")
flag.StringVar(&port, "p", "9090", "Defines host port")
flag.BoolVar(&dump, "dump", false, "Requests db dump in json format from server")
flag.BoolVar(&restore, "restore", false, "Restores db from dumped file")
flag.Parse()
}

// main entry point for client.
func main() {
c, err := net.Dial("tcp", host+":"+port)
defer c.Close()

if err != nil {
log.Error.Panicln(err.Error())
}

if dump {
fmt.Fprintf(c, "dump\n")
dbDump, err := bufio.NewReader(c).ReadString('\n')

if err != nil {
log.Error.Panicln(err.Error())
}

fmt.Println(dbDump)
return
}

if restore {
fmt.Fprintf(c, "restore\n")
dbRestore, err := bufio.NewReader(os.Stdin).ReadString('\n')

if err != nil {
log.Error.Panicln(err.Error())
}

fmt.Fprintf(c, dbRestore)
return
}

handler.HandleConnection(c)
}
65 changes: 65 additions & 0 deletions client/handler/handle_connection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package handler

import (
"NonRelDB/log"
"NonRelDB/util/regex"
"bufio"
"fmt"
"net"
"os"
"strings"
)

// SendRequest sends request to specified connection.
func SendRequest(req string, c net.Conn) {
fmt.Fprintf(c, req+"\n")
}

// HandleConnection handling communication with server.
func HandleConnection(c net.Conn) {
consoleReader := bufio.NewReader(os.Stdin)
netReader := bufio.NewReader(c)
for {
fmt.Printf("%s> ", c.RemoteAddr().String())
req, err := consoleReader.ReadString('\n')
req = strings.Trim(req, "\n")

if err != nil {
log.Error.Panicln(err.Error())
}

if regex.QueryReg.MatchString(req) {
SendRequest(req, c)
resp, err := netReader.ReadString('\n')

if err != nil {
log.Error.Panicln(err.Error())
}

fmt.Println(resp)

} else if regex.ExitReg.MatchString(req) {
fmt.Println("Good bye")
SendRequest(req, c)
return

} else if regex.TopicReg.MatchString(req) {
reqParts := strings.Split(req, " ")

if len(reqParts) == 2 {
if strings.ToLower(reqParts[0]) == "subscribe" {
SendRequest(req, c)
HandleTopic(c, *netReader, reqParts[1])
}
} else if len(reqParts) >= 3 {
if strings.ToLower(reqParts[0]) == "publish" {
SendRequest(req, c)
}
}

} else {
fmt.Println("Bad request")
continue
}
}
}
38 changes: 38 additions & 0 deletions client/handler/handle_topic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package handler

import (
"NonRelDB/log"
"bufio"
"fmt"
"net"
"os"
"os/signal"
"syscall"
)

// quit Handling Ctrl + C press.
func quit(c net.Conn, topic string) {
sign := make(chan os.Signal, 2)
signal.Notify(sign, os.Interrupt, syscall.SIGTERM)
go func() {
<-sign
fmt.Println("Ctrl+C pressed in Terminal")
fmt.Fprintf(c, "unsubscribe "+topic+"\n")
os.Exit(0)
}()
}

// HandleTopic listening messages from specified topic.
func HandleTopic(c net.Conn, r bufio.Reader, topic string) {
quit(c, topic)
fmt.Printf("Reading messages from %s... (press Ctrl + C to stop)\n", topic)
for {
msg, err := r.ReadString('\n')

if err != nil {
log.Error.Panicln(err.Error())
}

fmt.Print(msg)
}
}
Loading