1 import sqlite3 2 import os 3 from threading import Lock, BoundedSemaphore 4 5 6 class ConnPool: 7 8 def __init__(self, db_name, max_conn): 9 self.__MaxConn = max_conn # 最大连接数 10 self.__CurConn = 0 # 当前连接数 11 self.__FreeConn = 0 # 空闲连接数 12 self.__lock = Lock() # 锁 13 self.__connList = [] # 连接池 14 15 self.dbName = db_name # 数据库名称 16 self.init_conn() # 初始化 17 18 def init_conn(self): 19 for i in range(self.__MaxConn): 20 try: 21 conn = sqlite3.connect(os.path.abspath('.') + '\\' + self.dbName + '.db', check_same_thread=False) 22 if conn is not None: 23 self.__connList.append(conn) # 将获取到的数据库连接加入连接池 24 self.__FreeConn += 1 25 except Exception as e: 26 print("Get Sqlite Connection Failed: {0}".format(i) + e) 27 self.__sem = BoundedSemaphore(self.__FreeConn) # 初始化信号量 28 self.__MaxConn = self.__FreeConn 29 30 # 每当有请求时,从数据库连接池中返回一个可用连接,并更新使用和空闲连接数 31 def get_connection(self): 32 if 0 == len(self.__connList): 33 return None 34 self.__sem.acquire() # 消耗资源使计数器递减,为0时阻塞调用 35 self.__lock.acquire() # 加锁 36 conn = self.__connList.pop() # 从连接列表中弹出一个数据库连接 37 38 self.__FreeConn -= 1 # 空闲连接计数-1 39 self.__CurConn += 1 # 当前连接计数+1 40 41 self.__lock.release() # 释放锁 42 return conn 43 44 # 释放当前使用的连接 45 def release_connection(self, conn): 46 if conn is None: 47 return False 48 49 self.__lock.acquire() # 加锁 50 51 self.__connList.append(conn) # 归还数据库连接 52 self.__FreeConn += 1 53 self.__CurConn -= 1 54 55 self.__lock.release() # 释放锁 56 try: 57 self.__sem.release() # 归还资源使计数器递增 58 except ValueError: 59 print("超出计数器上限.") 60 return True 61 62 # 销毁数据库连接池 63 def destroy_pool(self): 64 self.__lock.acquire() # 加锁 65 if len(self.__connList) > 0: 66 for it in self.__connList: 67 it.close() 68 self.__CurConn = 0 69 self.__FreeConn = 0 70 self.__connList.clear() 71 self.__lock.release() # 释放锁 72 73 # 获取空闲的连接数 74 def get_free_conn(self): 75 return self.__FreeConn 76 77 # 析构函数 78 def __del__(self): 79 self.destroy_pool() 80 81 82 # 创建一个数据库资源管理类,传入一个类型为ConnPool对象,生成一个数据库连接,析构函数中释放此连接 83 class ConnPoolRAII: 84 def __init__(self, conn_pool: ConnPool): 85 self.connRAII = conn_pool.get_connection() 86 self.poolRAII = conn_pool 87 self.__lock = Lock() # 数据库操作锁 88 self.init_db() # 初始化数据库 89 90 # 数据库初始化 91 def init_db(self): 92 # 若用于存储下位机的表不存在,则进行初始化创建 93 if not self.is_exist('Client'): 94 self.operate('''create table Client( 95 ID integer primary key autoincrement, 96 Client_name text(10) not null, 97 IPAddress text(20) not null, 98 Status numeric default 0 99 )''') 100 101 # 检查指定表是否存在 102 def is_exist(self, table_name): 103 res = self.query('''select count(*) from sqlite_master where type='table' and name='{0}' 104 '''.format(table_name)) 105 if res.fetchone()[0] == 0: 106 return False 107 return True 108 109 # 为每一个客户机创建一个用于存储数据的表格 110 def create_table(self, client_name): 111 return self.operate(''' 112 create table {0}( 113 ID integer primary key autoincrement, 114 Weight real default 0, 115 Temperature real default 0, 116 Date integer not null 117 ); 118 '''.format(client_name)) 119 120 # 新增客户机函数 121 def add_client(self, ip): 122 client_name = 'Client{0}'.format(ip[ip.rfind('.') + 1:]) # 获取客户端名称,以Clientxxx为格式 123 res = self.query("select * from Client where IPAddress=='{0}'".format(client_name)) # 查询Client表中是否存在当前客户端信息 124 sql_insert = "insert into Client (Client_name, IPAddress) values ('{0}','{1}')".format(client_name, ip) 125 if res and (res.fetchone() is None): 126 if self.operate(sql_insert) and self.create_table(client_name): 127 print("创建表成功") # 测试用,后续改为日志 128 return True 129 else: 130 print("创建表失败,检查客户端是否已存在!") 131 return False 132 133 # 用于查询类操作,要求输入sql语句 134 def query(self, sql): 135 self.__lock.acquire() # 加锁 136 c = self.connRAII.cursor() # 获取cursor 137 try: 138 res = c.execute(sql) # 执行sql 139 self.__lock.release() # 释放锁 140 return res # 返回查询结果 141 except Exception as e: 142 print(e) 143 self.__lock.release() # 释放锁 144 return False # 返回False 145 146 # 增删改等操作,提供sql语句,返回bool值 147 def operate(self, sql): 148 self.__lock.acquire() # 加锁 149 c = self.connRAII.cursor() # 获取cursor 150 try: 151 c.execute(sql) # 执行sql 152 self.connRAII.commit() # 提交执行结果 153 self.__lock.release() # 释放锁 154 return True # 返回操作成功 155 except Exception as e: 156 print(e) # 打印错误信息 157 self.__lock.release() # 释放锁 158 return False # 返回False 159 160 # 析构函数 161 def __del__(self): 162 self.poolRAII.release_connection(self.connRAII)