#!/usr/bin/python # -*- coding: GBK -*- # ##@package # # @todo: ¼Èë·µÀû # Êý¾Ý¿â×Ö¶Î ÇþµÀspid Õ˺Åaccid ÏÉÓñgold ¶Ò»»ËùÔÚ·þserverid # # @author: Alee # @date 2019-1-22 ÏÂÎç03:23:30 # @version 1.0 # # @note: # #--------------------------------------------------------------------- import pymongo from pymongo.son_manipulator import SONManipulator import base64 from functools import wraps from time import (sleep) from lib import CommFunc class ObjectIdRemover(SONManipulator): def transform_outgoing(self, son, collection): if '_id' in son: del son['_id'] return son class EncodeStringManipulator(SONManipulator): def __init__(self, encoding): self.encoding = encoding def transform_incoming(self, son, collection): def transform_value(value): if isinstance(value, dict): return transform_dict(value) elif isinstance(value, list): return [transform_value(v) for v in value] elif isinstance(value, basestring): result, value = CommFunc.EncodingToUnicode(self.encoding, value) return value return value def transform_dict(object): for (key, value) in object.items(): object[key] = transform_value(value) return object def transform_list(container): for item in container: transform_dict(item) return container if isinstance(son, dict): return transform_dict(son) elif isinstance(son, list): return transform_list(son) return son def transform_outgoing(self, son, collection): def transform_value(value): if isinstance(value, dict): return transform_dict(value) elif isinstance(value, list): return [transform_value(v) for v in value] elif isinstance(value, basestring): result, value =CommFunc.UnicodeToEncoding(self.encoding, value) return value return value def transform_dict(object): for (key, value) in object.items(): object[key] = transform_value(value) return object def transform_list(container): for item in container: transform_dict(item) return container if isinstance(son, dict): return transform_dict(son) elif isinstance(son, list): return transform_list(son) return son class Base64StringManipulator(SONManipulator): def transform_incoming(self, son, collection): def transform_value(value): if isinstance(value, dict): return transform_dict(value) elif isinstance(value, list): return [transform_value(v) for v in value] elif isinstance(value, basestring): return base64.b64encode(value) return value def transform_dict(object): for (key, value) in object.items(): object[key] = transform_value(value) return object def transform_list(container): for item in container: transform_dict(item) return container if isinstance(son, dict): return transform_dict(son) elif isinstance(son, list): return transform_list(son) return son def transform_outgoing(self, son, collection): def transform_value(value): if isinstance(value, dict): return transform_dict(value) elif isinstance(value, list): return [transform_value(v) for v in value] elif isinstance(value, basestring): return base64.b64decode(value) return value def transform_dict(object): for (key, value) in object.items(): object[key] = transform_value(value) return object def transform_list(container): for item in container: transform_dict(item) return container if isinstance(son, dict): return transform_dict(son) elif isinstance(son, list): return transform_list(son) return son #ÓÃÓÚÐÞÊÎDBControllerµÄÊý¾Ý¿â²Ù×÷º¯Êý #¶ÏÏß×Ô¶¯ÖØÊÔ def reconnect_decorator(func): @wraps(func) def wrapper(*args, **kwds): MAX_RECONNECT = 10 RECONNECT_INTERVAL = 0.1 failCnt = 0 while True: try: #È¥µôself return func(*args, **kwds) except pymongo.errors.AutoReconnect, e: failCnt += 1 sleep(RECONNECT_INTERVAL) if failCnt > MAX_RECONNECT: raise e return wrapper class DBController: def __init__(self, host, port, dbName, user, pwd, encoding): self.host = host self.port = port self.dbName = dbName self.user = user self.pwd = pwd self.connected = False self.con = None self.db = None self.lastError = None self.translator = None #=========================================================================================== # if encoding == 'base64': # self.translator = Base64StringManipulator() # else: # self.translator = EncodeStringManipulator(encoding) #=========================================================================================== self.initialize() def initialize(self): if not self.connected: if not self.doConnect(self.host, self.port): return False authResult = self.doAuthentication(self.dbName, self.user, self.pwd) if self.db: self.db.add_son_manipulator(ObjectIdRemover()) return authResult return True def doConnect(self, ip, port): try: self.con = pymongo.Connection(ip, port) except TypeError, typeError: raise except pymongo.errors.ConnectionFailure, failure: self.lastError = failure return False except Exception, e: self.lastError = e return False except: self.lastError = 'Unknown exception occur!' return False self.connected = True return True def doAuthentication(self, dbName, user, pwd): if not self.connected or not self.con: self.lastError = 'Not connected yet!' return False self.db = self.con[dbName] authDB = self.con['admin'] try: return authDB.authenticate(user, pwd) # return self.db.authenticate(user, pwd) except TypeError, typeError: self.lastError = typeError return False except Exception, e: self.lastError = e return False except: self.lastError = 'Unknown exception occur!' return False def find_one(self, colName, spec, filter = None): result, recList = self.find(colName, spec, filter, 1) if not result: return False, None for rec in recList: return True, rec return True, None @reconnect_decorator def find(self, colName, spec = None, filter = None, maxCnt = 0, sortBy = None): if not self.connected: if not self.initialize(): return False, [] result = False resultDictList = [] col = self.db[colName] if self.translator: spec = self.translator.transform_incoming(spec, None) try: resultCollection = col.find(spec, filter, limit = maxCnt, sort = sortBy) if self.translator: resultDictList = self.translator.transform_outgoing(list(resultCollection), None) else: resultDictList = list(resultCollection) return True, resultDictList except TypeError, typeError: self.lastError = typeError return result, resultDictList except pymongo.errors.OperationFailure, err: self.lastError = err return result, resultDictList except Exception, e: self.lastError = e return result, resultDictList except: self.lastError = 'Unknown exception occur!' return result, resultDictList @reconnect_decorator def insert(self, colName, doc_or_docs, isSafe = True): if not self.connected: if not self.initialize(): return False col = self.db[colName] if self.translator: doc_or_docs = self.translator.transform_incoming(doc_or_docs, None) try: col.insert(doc_or_docs, safe = isSafe) except pymongo.errors.OperationFailure, err: self.lastError = err return False except Exception, e: self.lastError = e return False except: self.lastError = 'Unknown exception occur!' return False return True @reconnect_decorator def update(self, colName, spec, doc, isUpsert = False, isSafe = True, isMulti = False): if not self.connected: if not self.initialize(): return False col = self.db[colName] #ÐèÒªÏȶÔdoc½øÐд¦Àí£¬µ«Óɲ»ÄÜ¿ªÆôcollection.updateµÄmanipulate,ÒòΪÄÇ»áÓ¦ÓÃËùÓд¦Àí if self.translator: spec = self.translator.transform_incoming(spec, None) doc = self.translator.transform_incoming(doc, None) try: col.update(spec, doc, upsert = isUpsert, safe = isSafe, multi = isMulti) except TypeError, typeError: self.lastError = typeError return False except pymongo.errors.OperationFailure, err: self.lastError = err return False except Exception, e: self.lastError = e return False except: self.lastError = 'Unknown exception occur!' return False return True @reconnect_decorator def save(self, colName, doc, isSafe = True): if not self.connected: if not self.initialize(): return False col = self.db[colName] if self.translator: doc = self.translator.transform_incoming(doc, None) try: col.save(doc, safe = isSafe) except TypeError, typeError: self.lastError = typeError return False except pymongo.errors.OperationFailure, err: self.lastError = err return False except Exception, e: self.lastError = e return False except: self.lastError = 'Unknown exception occur!' return False return True @reconnect_decorator def remove(self, colName, spec = None, isSafe = True): if not self.connected: if not self.initialize(): return False col = self.db[colName] if self.translator: spec = self.translator.transform_incoming(spec, None) try: col.remove(spec, safe = isSafe) except pymongo.errors.OperationFailure, err: self.lastError = err return False except Exception, e: self.lastError = e return False except: self.lastError = 'Unknown exception occur!' return False return True @reconnect_decorator def drop(self, colName): if not self.connected: if not self.initialize(): return False col = self.db[colName] try: col.drop() except TypeError, typeError: self.lastError = typeError return False except Exception, e: self.lastError = e return False except: self.lastError = 'Unknown exception occur!' return False return True @reconnect_decorator def count(self, colName): if not self.connected: if not self.initialize(): return False, 0 col = self.db[colName] try: cnt = col.count() except pymongo.errors.OperationFailure, err: self.lastError = err return False, 0 except Exception, e: self.lastError = e return False, 0 except: self.lastError = 'Unknown exception occur!' return False, 0 return True, cnt def test_DBController(): fileIO = open("Bill.txt") # spid accid gold testColName = 'tagDoubleBill' dbController = DBController('localhost', 27017, "DoubleBillDB", 'sa', 'sa', None) print "¿ªÊ¼Â¼ÈëÊý¾Ý" cnt = 0 spidDict= {} #ÇþµÀSpID Õ˺ÅAccID ÏÉÓñGold ¶Ò»»ËùÔÚ·þServerID for line in fileIO.readlines(): try: spID, accID, gold = line.strip().split() except: print "Error:", line continue result, recs = dbController.find(testColName, {"SpID":spID, "AccID":accID}) if recs: print "ÖØ¸´²åÈë", spID, accID, gold continue doc = {"SpID":spID, "AccID":accID, "Gold":gold, "ServerID":""} result = dbController.insert(testColName, doc) if not result: print "²åÈëʧ°Ü", spID, accID, gold continue spidDict[spID] = 0 cnt += 1 print "¼ÈëÇþµÀ·µÀû½áÊø£¬×ܹ²%sÌõ, º¬Æ½Ì¨%s"%(cnt, spidDict.keys()) #¿ªÊ¼Â¼ÈëÊý¾Ý #¼ÈëÇþµÀ·µÀû½áÊø£¬×ܹ²681Ìõ, º¬Æ½Ì¨['kupai', 'uc', 'gionee', 'xiaomi', 'vivo', 'lenovo', 'meizu', 'yyb', 'oppo', 'qh360'] def test(): test_DBController() print 'test ok!' if __name__ == '__main__': test() import os os.system("pause")