<s> import operator <EOL> import pickle <EOL> try : <EOL> import simplejson as json <EOL> except ImportError : <EOL> import json <EOL> from peewee import * <EOL> from peewee import Node <EOL> from playhouse . fields import PickledField <EOL> try : <EOL> from playhouse . apsw_ext import APSWDatabase <EOL> def KeyValueDatabase ( db_name , ** kwargs ) : <EOL> return APSWDatabase ( db_name , ** kwargs ) <EOL> except ImportError : <EOL> def KeyValueDatabase ( db_name , ** kwargs ) : <EOL> return SqliteDatabase ( db_name , check_same_thread = False , ** kwargs ) <EOL> Sentinel = type ( '<STR_LIT>' , ( object , ) , { } ) <EOL> key_value_db = KeyValueDatabase ( '<STR_LIT>' , threadlocals = False ) <EOL> class JSONField ( TextField ) : <EOL> def db_value ( self , value ) : <EOL> return json . dumps ( value ) <EOL> def python_value ( self , value ) : <EOL> if value is not None : <EOL> return json . loads ( value ) <EOL> class KeyStore ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , value_field , ordered = False , database = None ) : <EOL> self . _value_field = value_field <EOL> self . _ordered = ordered <EOL> self . _database = database or key_value_db <EOL> self . _compiler = self . _database . compiler ( ) <EOL> self . model = self . create_model ( ) <EOL> self . key = self . model . key <EOL> self . value = self . model . value <EOL> self . _database . create_table ( self . model , True ) <EOL> self . _native_upsert = isinstance ( self . _database , SqliteDatabase ) <EOL> def create_model ( self ) : <EOL> class KVModel ( Model ) : <EOL> key = CharField ( max_length = <NUM_LIT:255> , primary_key = True ) <EOL> value = self . _value_field <EOL> class Meta : <EOL> database = self . _database <EOL> return KVModel <EOL> def query ( self , * select ) : <EOL> query = self . model . select ( * select ) . tuples ( ) <EOL> if self . _ordered : <EOL> query = query . order_by ( self . key ) <EOL> return query <EOL> def convert_node ( self , node ) : <EOL> if not isinstance ( node , Node ) : <EOL> return ( self . key == node ) , True <EOL> return node , False <EOL> def __contains__ ( self , key ) : <EOL> node , _ = self . convert_node ( key ) <EOL> return self . model . select ( ) . where ( node ) . exists ( ) <EOL> def __len__ ( self ) : <EOL> return self . model . select ( ) . count ( ) <EOL> def __getitem__ ( self , node ) : <EOL> converted , is_single = self . convert_node ( node ) <EOL> result = self . query ( self . value ) . where ( converted ) <EOL> item_getter = operator . itemgetter ( <NUM_LIT:0> ) <EOL> result = [ item_getter ( val ) for val in result ] <EOL> if len ( result ) == <NUM_LIT:0> and is_single : <EOL> raise KeyError ( node ) <EOL> elif is_single : <EOL> return result [ <NUM_LIT:0> ] <EOL> return result <EOL> def _upsert ( self , key , value ) : <EOL> self . model . insert ( ** { <EOL> self . key . name : key , <EOL> self . value . name : value } ) . upsert ( ) . execute ( ) <EOL> def __setitem__ ( self , node , value ) : <EOL> if isinstance ( node , Node ) : <EOL> update = { self . value . name : value } <EOL> self . model . update ( ** update ) . where ( node ) . execute ( ) <EOL> elif self . _native_upsert : <EOL> self . _upsert ( node , value ) <EOL> else : <EOL> try : <EOL> self . model . create ( key = node , value = value ) <EOL> except : <EOL> self . _database . rollback ( ) <EOL> ( self . model <EOL> . update ( ** { self . value . name : value } ) <EOL> . where ( self . key == node ) <EOL> . execute ( ) ) <EOL> def __delitem__ ( self , node ) : <EOL> converted , _ = self . convert_node ( node ) <EOL> self . model . delete ( ) . where ( converted ) . execute ( ) <EOL> def __iter__ ( self ) : <EOL> return self . query ( ) . execute ( ) <EOL> def keys ( self ) : <EOL> return map ( operator . itemgetter ( <NUM_LIT:0> ) , self . query ( self . key ) ) <EOL> def values ( self ) : <EOL> return map ( operator . itemgetter ( <NUM_LIT:0> ) , self . query ( self . value ) ) <EOL> def items ( self ) : <EOL> return iter ( self ) <EOL> def get ( self , k , default = None ) : <EOL> try : <EOL> return self [ k ] <EOL> except KeyError : <EOL> return default <EOL> def pop ( self , k , default = Sentinel ) : <EOL> with self . _database . transaction ( ) : <EOL> node , is_single = self . convert_node ( k ) <EOL> try : <EOL> res = self [ k ] <EOL> except KeyError : <EOL> if default is Sentinel : <EOL> raise <EOL> return default <EOL> del ( self [ node ] ) <EOL> return res <EOL> def clear ( self ) : <EOL> self . model . delete ( ) . execute ( ) <EOL> class PickledKeyStore ( KeyStore ) : <EOL> def __init__ ( self , ordered = False , database = None ) : <EOL> super ( PickledKeyStore , self ) . __init__ ( <EOL> PickledField ( ) , ordered , database ) <EOL> class JSONKeyStore ( KeyStore ) : <EOL> def __init__ ( self , ordered = False , database = None ) : <EOL> field = JSONField ( null = True ) <EOL> super ( JSONKeyStore , self ) . __init__ ( field , ordered , database ) </s>
