Last active
April 25, 2019 22:33
-
-
Save spenceralan/7f4e2e1ec94be20cccf84ea1d2620f26 to your computer and use it in GitHub Desktop.
Opal CoderPad Challenge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'minitest/autorun' | |
#The commands available are: | |
# SET <key> <value> // store the value for key | |
# GET <key> // return the current value for key | |
# DELETE <key> // remove the entry for key | |
# COUNT <value> // return the number of keys that have the given value | |
# BEGIN // start a transaction | |
# COMMIT // commit all transactions | |
# ROLLBACK // rollback current transaction | |
# ROLLBACK_ALL // rollback all transactions | |
# HELP // this list | |
# | |
class SimpleDb | |
attr_accessor :data_store | |
attr_accessor :transactions | |
attr_accessor :in_transaction | |
def initialize | |
self.data_store = {} | |
self.transaction = [] | |
self.in_transaction = false | |
end | |
def database | |
return data_store if in_transaction == false | |
transaction | |
end | |
def BEGIN | |
self.in_transaction = true | |
"Transaction (Level/Nest 1) Begin" | |
end | |
def SET(key, value) | |
if in_transaction | |
self.transactions << {key => value} | |
else | |
database[key] = value | |
end | |
end | |
def COMMIT | |
transactions.each do |transaction| | |
keys = transaction.keys | |
keys.each do |key| | |
data_store[key] = data[key] | |
end | |
end | |
self.in_transaction = false | |
end | |
def GET(key) | |
value = database[key] | |
return "Key not set." if value.nil? | |
value | |
end | |
def COUNT(value) | |
database.values.count(value) | |
end | |
def DELETE(key) | |
database.delete(key) | |
end | |
def ROLLBACK | |
self.transactions.pop | |
self.in_transaction = false | |
"Transaction rolled back." | |
end | |
def ROLLBACK_ALL | |
self.transactions = [] | |
self.in_transaction = false | |
"Transactions rolled back." | |
end | |
end | |
class SimpleDbTest < Minitest::Spec | |
before do | |
@simple_db = SimpleDb.new | |
end | |
describe "SimpleDb" do | |
describe "Simple commands" do | |
before do | |
@simple_db.SET("1","1") | |
end | |
it "should SET and GET data" do | |
assert_equal "1", @simple_db.GET("1") | |
end | |
it "should overwrite when SET is called for a key that already exists" do | |
@simple_db.SET("1","B") | |
assert_equal "B", @simple_db.GET("1") | |
end | |
it "should DELETE data" do | |
@simple_db.DELETE("1") | |
assert_equal "Key not set.", @simple_db.GET("1") | |
end | |
it "should return COUNT for num keys with value" do | |
assert_equal 1, @simple_db.COUNT("1") | |
@simple_db.SET("2", "1") | |
assert_equal 2, @simple_db.COUNT("1") | |
@simple_db.SET("3", "2") | |
assert_equal 2, @simple_db.COUNT("1") | |
end | |
end | |
describe "Transactions" do | |
before do | |
@simple_db.SET("1","1") | |
end | |
it "should allow transaction BEGIN" do | |
message = @simple_db.BEGIN | |
assert_equal "Transaction (Level/Nest 1) Begin", message | |
end | |
it "should allow transaction ROLLBACK" do | |
@simple_db.BEGIN | |
@simple_db.SET("3", "3") | |
message = @simple_db.ROLLBACK | |
assert_equal "Transaction rolled back.", message | |
assert_equal @simple_db.GET("3"), "Key not set." | |
end | |
it "should back out all transactions" do | |
@simple_db.BEGIN | |
@simple_db.SET("3", "3") | |
@simple_db.BEGIN | |
@simple_db.SET("4", "4") | |
message = @simple_db.ROLLBACK_ALL | |
assert_equal "Transactions rolled back.", message | |
assert_equal "1", @simple_db.GET("1") | |
assert_equal "Key not set.", @simple_db.GET("3") | |
end | |
it "should commit changes" do | |
@simple_db.BEGIN | |
@simple_db.SET("3", "3") | |
@simple_db.COMMIT | |
assert_equal "3", @simple_db.GET("3") | |
end | |
it "should commit all non rolled-back changes" do | |
@simple_db.BEGIN | |
@simple_db.SET("3", "3") | |
@simple_db.BEGIN | |
@simple_db.SET("4", "4") | |
@simple_db.ROLLBACK | |
@simple_db.COMMIT | |
assert_equal "3", @simple_db.GET("3") | |
assert_equal "Key not set.", @simple_db.GET("4") | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment