Skip to content

Instantly share code, notes, and snippets.

@spenceralan
Last active April 25, 2019 22:33
Show Gist options
  • Save spenceralan/7f4e2e1ec94be20cccf84ea1d2620f26 to your computer and use it in GitHub Desktop.
Save spenceralan/7f4e2e1ec94be20cccf84ea1d2620f26 to your computer and use it in GitHub Desktop.
Opal CoderPad Challenge
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