puffadder
Package puffadder
is a project database built from scratch that is designed to store and update current bank accounts.
The main features that allow this are:
-
Event source architecture so that you have a history of activity on each account.
-
Choice of homemade algorithm (btree, hash_table, ordered_array).
-
Transactions between accounts are atomic.
-
The database is durable, it stores each action to a file (like a commit log in other databases)
- Side note: I havn't looked into making sure it is flushed to permenated storeage like postgres (fsync)
Install
With a correctly configured Go toolchain:
go get -u github.com/zoomie/puffadder
Run
In the project direcotry run the following
go build .
./puffadder
Examples
Run the http server in main.go, open the data.puff file and run each of the following commands:
curl 'localhost:8090/create-account' -d 'accountName=joe'
curl 'localhost:8090/view-current-account?accountName=joe'
curl 'localhost:8090/add-money' -d 'accountName=joe&addAmount=100'
curl 'localhost:8090/withdraw-money' -d 'accountName=joe&subtractAmount=10'
curl 'localhost:8090/create-account' -d 'accountName=john'
curl 'localhost:8090/transfer' -d 'fromAccount=joe&toAccount=john&transferAmount=10'
The above commands will produce the following data.puff file.
joe-------:create--:---------0
joe-------:add-----:-------100
joe-------:withdraw:--------10
john------:create--:---------0
joe-------:withdraw:--------10
john------:add-----:--------10
Test example of how to create an account in code, can be found in server_test.go.
func createAccountSetUp(accountName string) (*httptest.ResponseRecorder, *http.Request) {
form := url.Values{}
form.Add("accountName", accountName)
body := strings.NewReader(form.Encode())
url := path.Join(baseURL, "create-account")
request, _ := http.NewRequest("POST", url, body)
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
recorder := httptest.NewRecorder()
return recorder, request
}
func TestCreateAccount(t *testing.T) {
channelSrv := setUp()
recorder, request := createAccountSetUp("joe")
channelSrv.createAccount(recorder, request)
response := recorder.Result()
if response.StatusCode != http.StatusOK {
t.Errorf("Creating account failed")
}
}
Structure
The server and entry point for the database is found in:
Algorithms that store value in memory:
The file that persists the data to disk and updates the current value using an algorithm:
Tests: