Convert CFBank to sqlite3

master^2
Kevin Zheng 2020-05-15 14:24:58 -07:00
parent 9838c555ed
commit 376dd8683e
3 changed files with 82 additions and 44 deletions

View File

@ -4,15 +4,15 @@ Created by: Joris Bontje <jbontje@suespammers.org>
This module stores bank account information.
"""
import os.path
import shelve
import Crossfire
import CFSqlDb as cfdb
class CFBank:
def __init__(self, bankfile):
self.bankdb_file = os.path.join(Crossfire.LocalDirectory(), bankfile)
self.bankdb = shelve.open(self.bankdb_file)
def __init__(self):
self.bankdb = cfdb.open()
def init_schema(self):
self.bankdb.execute("CREATE TABLE IF NOT EXISTS bank_accounts ('name' TEXT PRIMARY KEY, 'balance' INT);")
def __enter__(self):
return self
@ -20,60 +20,51 @@ class CFBank:
def __exit__(self, exc_type, exc_value, traceback):
self.close()
def ensure(self, user):
self.bankdb.execute("INSERT OR IGNORE INTO bank_accounts VALUES (?, 0)", (user,))
def deposit(self, user, amount):
if not user in self.bankdb:
self.bankdb[user] = amount
else:
balance = self.bankdb[user]
self.bankdb[user] = balance + amount
if amount > 0:
self.ensure(user)
self.bankdb.execute("UPDATE bank_accounts SET balance = balance + ? WHERE name=?", (amount, user))
def withdraw(self, user, amount):
if user in self.bankdb:
balance = self.getbalance(user)
if balance >= amount:
self.bankdb[user] = balance - amount
return 1
return 0
if self.getbalance(user) - amount < 0:
return 0
else:
self.bankdb.execute("UPDATE bank_accounts SET balance = balance - ? WHERE name=?", (amount, user))
return 1
def getbalance(self, user):
self._convert(user)
if user in self.bankdb:
return self.bankdb[user]
self.convert_legacy_balance(user)
c = self.bankdb.cursor()
c.execute("SELECT balance FROM bank_accounts WHERE name=?", (user,))
result = c.fetchone()
if result is not None:
return result[0]
else:
return 0
def remove_account(self, user):
if user in self.bankdb:
del self.bankdb[user]
Crossfire.Log(Crossfire.LogDebug,
"%s's bank account removed." % user)
return 1
else:
return 0
c.execute("DELETE FROM bank_accounts WHERE name=?", (user,))
def close(self):
self.bankdb.commit()
self.bankdb.close()
def _convert(self, name):
def convert_legacy_balance(self, name):
"""Move a player's balance from the player file to the bank."""
player = Crossfire.FindPlayer(name)
if player is None:
return 0
old_balance = _balance_legacy(player)
if old_balance > 0:
Crossfire.Log(Crossfire.LogInfo,
"Converting bank account for %s with %d silver" \
% (name, old_balance))
return
balance_str = player.ReadKey("balance")
try:
old_balance = int(balance_str)
Crossfire.Log(Crossfire.LogInfo, "Converting bank account for %s with %d silver" % (name, old_balance))
self.deposit(name, old_balance)
player.WriteKey("balance", "moved-to-bank-file", 1)
except ValueError:
pass
player.WriteKey("balance", None, 0)
def open():
return CFBank('ImperialBank_DB')
def _balance_legacy(player):
"""Return the balance of the given player's bank account."""
try:
balance_str = player.ReadKey("balance")
return int(balance_str)
except ValueError:
return 0
return CFBank()

View File

@ -0,0 +1,8 @@
import os.path
import sqlite3
import Crossfire
def open():
path = os.path.join(Crossfire.LocalDirectory(), 'crossfire.db')
return sqlite3.connect(path)

View File

@ -0,0 +1,39 @@
import os.path
import Crossfire
import CFBank
def convert_bdb(bank):
path = os.path.join(Crossfire.LocalDirectory(), 'ImperialBank_DB.db')
if os.path.isfile(path):
Crossfire.Log(Crossfire.LogInfo, "Converting ImperialBank_DB.db (BDB)")
import berkeleydb.dbshelve as shelve
accounts = shelve.open(path, 'r')
for account in accounts.keys():
name = account.decode('ascii')
balance = accounts[account]
bank.deposit(name, balance)
accounts.close()
bak_file = os.path.join(Crossfire.LocalDirectory(), 'ImperialBank_DB.db.bak')
os.rename(path, bak_file)
def convert(bank):
path = os.path.join(Crossfire.LocalDirectory(), 'ImperialBank_DB')
if os.path.isfile(path):
Crossfire.Log(Crossfire.LogInfo, "Converting ImperialBank_DB (DBM)")
import shelve
s = shelve.open(path, 'r')
for name, balance in s.iteritems():
bank.deposit(name, balance)
s.close()
bak_file = os.path.join(Crossfire.LocalDirectory(), 'ImperialBank_DB.bak')
os.rename(path, bak_file)
def main():
Crossfire.Log(Crossfire.LogInfo, "Initializing CFBank")
with CFBank.CFBank() as bank:
bank.init_schema()
convert_bdb(bank)
convert(bank)
main()