Browse files

preparation for merge kvlite/sqlite branch with master

  • Loading branch information...
1 parent 120a643 commit e8c408a6e68dc8256dc02b0d8b6b86cab200b7c2 @ownport committed Sep 12, 2012
Showing with 21 additions and 305 deletions.
  1. +21 −305 kvlite.py
View
326 kvlite.py
@@ -38,14 +38,13 @@
POSSIBILITY OF SUCH DAMAGE."""
import os
-import cmd
import sys
import json
import zlib
import uuid
-import pprint
import sqlite3
import binascii
+import cPickle as pickle
__all__ = ['open', 'remove',]
@@ -55,10 +54,7 @@
print >> sys.stderr, 'Error! MySQLdb package is not installed, please install python-mysqldb'
sys.exit()
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
+
# TODO add test cases for serializers
# TODO add support user specific serializators
@@ -95,8 +91,6 @@ def dumps(v):
@staticmethod
def loads(v):
''' loads value '''
- if isinstance(v, unicode):
- v = str(v)
return pickle.loads(v)
# -----------------------------------------------------------------
@@ -106,6 +100,8 @@ def loads(v):
class CompressedJsonSerializer(object):
''' CompressedJsonSerializer '''
+ # TODO issue: sqlite doesn't support binary values
+
@staticmethod
def dumps(v):
''' dumps value '''
@@ -155,16 +151,10 @@ def remove(uri):
'''
remove collection by URI
'''
- backend, rest_uri = uri.split('://')
- if backend in SUPPORTED_BACKENDS:
- if backend == 'mysql':
- MysqlCollection(uri).remove()
- elif backend == 'sqlite':
- SqliteCollection(uri).remove()
- else:
- raise NotImplementedError('unknown backend: {}'.format(uri))
- else:
- raise RuntimeError('Unknown backend: {}'.format(backend))
+ manager = CollectionManager(uri)
+ params = manager.parse_uri(uri)
+ if params['collection'] in manager.collections():
+ manager.remove(params['collection'])
def get_uuid(amount=100):
''' return UUIDs '''
@@ -364,18 +354,15 @@ def get(self, k=None):
'''
if k:
if len(k) > 40:
- raise WronKeyValue()
+ raise RuntimeError('The length of key is more than 40 bytes')
SQL = 'SELECT k,v FROM %s WHERE k = ' % self.__collection
try:
self.__cursor.execute(SQL + "%s", binascii.a2b_hex(k))
- except TypeError, err:
- raise WronKeyValue(err)
+ except Exception, err:
+ raise RuntimeError(err)
result = self.__cursor.fetchone()
if result:
- try:
- v = self.__serializer.loads(result[1])
- except Exception, err:
- raise RuntimeError('key %s, %s' % (k, err))
+ v = self.__serializer.loads(result[1])
return (binascii.b2a_hex(result[0]), v)
else:
return (None, None)
@@ -392,20 +379,15 @@ def put(self, k, v):
SQL_INSERT = 'INSERT INTO %s (k,v) ' % self.__collection
SQL_INSERT += 'VALUES (%s,%s) ON DUPLICATE KEY UPDATE v=%s;;'
v = self.__serializer.dumps(v)
- try:
- self.__cursor.execute(SQL_INSERT, (binascii.a2b_hex(k), v, v))
- except TypeError, err:
- raise RuntimeError(err)
+ self.__cursor.execute(SQL_INSERT, (binascii.a2b_hex(k), v, v))
def delete(self, k):
''' delete document by k '''
if len(k) > 40:
- raise WronKeyValue()
+ raise RuntimeError('The length of key is more than 40 bytes')
+
SQL_DELETE = '''DELETE FROM %s WHERE k = ''' % self.__collection
- try:
- self.__cursor.execute(SQL_DELETE + "%s;", binascii.a2b_hex(k))
- except TypeError, err:
- raise WronKeyValue(err)
+ self.__cursor.execute(SQL_DELETE + "%s;", binascii.a2b_hex(k))
def keys(self):
''' return document keys in collection'''
@@ -445,6 +427,7 @@ def __init__(self, uri):
self.__conn = sqlite3.connect(params['db'])
self.__cursor = self.__conn.cursor()
+ self.__conn.text_factory = str
@staticmethod
def parse_uri(uri):
@@ -533,10 +516,7 @@ def put(self, k, v):
SQL_INSERT = 'INSERT OR REPLACE INTO %s (k,v) ' % self.__collection
SQL_INSERT += 'VALUES (?,?)'
v = self.__serializer.dumps(v)
- try:
- self.__cursor.execute(SQL_INSERT, (k, v))
- except TypeError, err:
- raise RuntimeError(err)
+ self.__cursor.execute(SQL_INSERT, (k, v))
def __get_many(self):
''' return all docs '''
@@ -567,8 +547,8 @@ def get(self, k=None):
SQL = 'SELECT k,v FROM %s WHERE k = ?;' % self.__collection
try:
self.__cursor.execute(SQL, (k,))
- except TypeError, err:
- raise WronKeyValue(err)
+ except Exception, err:
+ raise RuntimeError(err)
result = self.__cursor.fetchone()
if result:
try:
@@ -599,10 +579,7 @@ def delete(self, k):
if len(k) > 40:
raise RuntimeError('The key length is more than 40 bytes')
SQL_DELETE = '''DELETE FROM %s WHERE k = ?;''' % self.__collection
- try:
- self.__cursor.execute(SQL_DELETE, (k,))
- except TypeError, err:
- raise WronKeyValue(err)
+ self.__cursor.execute(SQL_DELETE, (k,))
@property
def count(self):
@@ -617,265 +594,4 @@ def close(self):
''' close connection to database '''
self.__conn.close()
-# -----------------------------------------------------------------
-# Console class
-# -----------------------------------------------------------------
-class Console(cmd.Cmd):
- def __init__(self):
- cmd.Cmd.__init__(self)
- self.prompt = "kvlite> "
- self.ruler = '-'
-
- self.__history_size = 20
- self.__history = list()
- self.__kvlite_colls = dict()
- self.__current_coll_name = 'kvlite'
- self.__current_coll = None
-
- def emptyline(self):
- return False
-
- def do_help(self, arg):
- ''' help <command>\tshow <command> help'''
- if arg:
- try:
- func = getattr(self, 'help_' + arg)
- except AttributeError:
- try:
- doc=getattr(self, 'do_' + arg).__doc__
- if doc:
- self.stdout.write("%s\n"%str(doc))
- return
- except AttributeError:
- pass
- self.stdout.write("%s\n"%str(self.nohelp % (arg,)))
- return
- else:
- names = [
- '', 'do_help', 'do_version', 'do_licence', 'do_history', 'do_exit', '',
- 'do_create', 'do_use', 'do_show', 'do_remove', 'do_import', 'do_export', '',
- 'do_hash', 'do_keys', 'do_items', 'do_get', 'do_put', 'do_delete', 'do_count', ''
- ]
- for name in names:
- if not name:
- print
- else:
- print getattr(self, name).__doc__
-
- def do_history(self,line):
- ''' history\t\tshow commands history '''
- for i, line in enumerate(self.__history):
- print "0%d. %s" % (i+1, line)
-
- def precmd(self, line):
- if len(self.__history) == self.__history_size:
- prev_line = self.__history.pop(0)
- if line and line not in self.__history:
- self.__history.append(line)
- return line
-
- def do_version(self, line):
- ''' version\t\tshow kvlite version'''
- print 'version: %s' % __version__
-
- def do_licence(self, line):
- ''' licence\t\tshow licence'''
- print __license__
- print
-
- def do_exit(self, line):
- ''' exit\t\t\texit from console '''
- return True
-
- def do_import(self, filename):
- ''' import <filename>\timport collection configuration from JSON file'''
- import os
-
- if not filename:
- print getattr(self, 'do_import').__doc__
- return
- filename = filename.rstrip().lstrip()
-
- if os.path.isfile(filename):
- for k, v in json_decode(open(filename).read()).items():
- self.__kvlite_colls[k] = v
- print 'Import completed'
- else:
- print 'Error! File %s does not exists' % filename
-
- def do_export(self, filename):
- ''' export <filename>\texport collection configurations to JSON file'''
- # TODO check if file exists. If yes, import about it
- if not filename:
- print getattr(self, 'do_import').__doc__
- return
- filename = filename.rstrip().lstrip()
- json_file = open(filename, 'w')
- json_file.write(json_encode(self.__kvlite_colls))
- json_file.close()
- print 'Export completed to file: %s' % filename
-
- def do_show(self, line):
- ''' show collections\tlist of available collections (defined in settings.py)'''
- if line == 'collections':
- for coll in self.__kvlite_colls:
- print ' %s' % coll
- else:
- print 'Unknown argument: %s' % line
-
- def do_use(self, collection_name):
- ''' use <collection>\tuse the collection as the default (current) collection'''
- if collection_name in self.__kvlite_colls:
- self.prompt = '%s>' % collection_name
- self.__current_coll_name = collection_name
- self.__current_coll = Collection(self.__kvlite_colls[self.__current_coll_name])
- return
- else:
- print 'Error! Unknown collection: %s' % collection_name
-
- def do_create(self, line):
- ''' create <name> <uri>\tcreate new collection (if not exists)'''
- try:
- name, uri = [i for i in line.split(' ') if i <> '']
- except ValueError:
- print getattr(self, 'do_create').__doc__
- return
-
- if name in self.__kvlite_colls:
- print 'Warning! Collection name already defined: %s, %s' % (name, self.__kvlite_colls[name])
- print 'If needed please change collection name'
- return
- try:
- if is_collection_exists(uri):
- self.__kvlite_colls[name] = uri
- print 'Connection exists, the reference added to collection list'
- return
- else:
- create_collection(uri)
- self.__kvlite_colls[name] = uri
- print 'Collection created and added to collection list'
- return
- except WrongURIException:
- print 'Error! Incorrect URI'
- return
- except ConnectionError, err:
- print 'Connection Error! Please check URI, %s' % str(err)
- return
-
- def do_remove(self, name):
- ''' remove <collection>\tremove collection'''
- if name not in self.__kvlite_colls:
- print 'Error! Collection name does not exist: %s' % name
- return
- try:
- if is_collection_exists(self.__kvlite_colls[name]):
- delete_collection(self.__kvlite_colls[name])
- del self.__kvlite_colls[name]
- print 'Collection %s deleted' % name
- return
- else:
- print 'Error! Collection does not exist, %s' % self.__kvlite_colls[name]
- except WrongURIException:
- print 'Error! Incorrect URI'
- return
- except ConnectionError, err:
- print 'Connection Error! Please check URI, %s' % str(err)
- return
-
- def do_hash(self, line):
- ''' hash [string]\tgenerate sha1 hash, random if string is not defined'''
- import hashlib
- import datetime
- if not line:
- str_now = str(datetime.datetime.now())
- print 'Random sha1 hash:', hashlib.sha1(str_now).hexdigest()
- else:
- line = line.rstrip().lstrip()
- print 'sha1 hash:', hashlib.sha1(line).hexdigest()
-
- def do_keys(self, line):
- ''' keys\t\t\tlist of keys '''
- if not self.__current_coll_name in self.__kvlite_colls:
- print 'Error! Unknown collection: %s' % self.__current_coll_name
- return
- for k,v in self.__current_coll.get():
- print k
-
- def do_items(self, line):
- ''' items\t\tlist of collection's items '''
- if not self.__current_coll_name in self.__kvlite_colls:
- print 'Error! Unknown collection: %s' % self.__current_coll_name
- return
- for k,v in self.__current_coll.get():
- print k
- pprint.pprint(v)
- print
-
- def do_count(self, args):
- ''' count\t\tshow the amount of entries in collection '''
- if self.__current_coll:
- print self.__current_coll.count()
-
- def do_get(self, key):
- ''' get <key>\t\tshow collection entry by key'''
- if not key:
- print getattr(self, 'do_get').__doc__
- return
- for key in [k for k in key.split(' ') if k <> '']:
- if self.__current_coll:
- k, v = self.__current_coll.get(key)
- print k
- pprint.pprint(v)
- print
- else:
- print 'Error! The collection is not selected, please use collection'
- return
-
- def do_put(self, line):
- ''' put <key> <value>\tstore entry to collection'''
- try:
- k,v = [i for i in line.split(' ',1) if i <> '']
- except ValueError:
- print getattr(self, 'do_put').__doc__
- return
-
- try:
- v = json_decode(v)
- except ValueError, err:
- print 'Value decoding error!', err
- return
-
- if self.__current_coll:
- try:
- self.__current_coll.put(k, v)
- self.__current_coll.commit()
- print 'Done'
- return
- except WronKeyValue, err:
- print 'Error! Incorrect key/value,', err
- return
- else:
- print 'Error! The collection is not selected, please use collection'
- return
-
-
- def do_delete(self, key):
- ''' delete <key>\t\tdelete entry by key '''
- key = key.rstrip().lstrip()
- if self.__current_coll.get(key) <> (None, None):
- self.__current_coll.delete(key)
- self.__current_coll.commit()
- print 'Done'
- return
- else:
- print 'Error! The key %s does not exist' % key
- return
-
-# ----------------------------------
-# main
-# ----------------------------------
-if __name__ == '__main__':
- console = Console()
- console.cmdloop()
-

0 comments on commit e8c408a

Please sign in to comment.