119 lines
3.2 KiB
Python
119 lines
3.2 KiB
Python
import MySQLdb
|
|
import threading
|
|
|
|
class mysqlWorker:
|
|
"""
|
|
Instance of a pettirosso meme
|
|
"""
|
|
def __init__(self, wid, host, username, password, database):
|
|
"""
|
|
Create a pettirosso meme (mysql worker)
|
|
|
|
wid -- worker id
|
|
host -- hostname
|
|
username -- MySQL username
|
|
password -- MySQL password
|
|
database -- MySQL database name
|
|
"""
|
|
self.wid = wid
|
|
self.connection = MySQLdb.connect(host, username, password, database)
|
|
self.connection.autocommit(True)
|
|
self.ready = True
|
|
self.lock = threading.Lock()
|
|
|
|
class db:
|
|
"""
|
|
A MySQL db connection with multiple workers
|
|
"""
|
|
|
|
def __init__(self, host, username, password, database, workers):
|
|
"""
|
|
Create MySQL workers aka pettirossi meme
|
|
|
|
host -- hostname
|
|
username -- MySQL username
|
|
password -- MySQL password
|
|
database -- MySQL database name
|
|
workers -- Number of workers to spawn
|
|
"""
|
|
#self.lock = threading.Lock()
|
|
#self.connection = MySQLdb.connect(host, username, password, database)
|
|
|
|
self.workers = []
|
|
self.lastWorker = 0
|
|
self.workersNumber = workers
|
|
for i in range(0,self.workersNumber):
|
|
print("> Spawning MySQL pettirosso meme {}".format(i))
|
|
self.workers.append(mysqlWorker(i, host, username, password, database))
|
|
|
|
def getWorker(self):
|
|
"""
|
|
Return a worker object (round-robin way)
|
|
|
|
return -- worker object
|
|
"""
|
|
if self.lastWorker >= self.workersNumber-1:
|
|
self.lastWorker = 0
|
|
else:
|
|
self.lastWorker += 1
|
|
#print("Using worker {}".format(self.lastWorker))
|
|
return self.workers[self.lastWorker]
|
|
|
|
def execute(self, query, params = ()):
|
|
"""
|
|
Executes a query
|
|
|
|
query -- Query to execute. You can bind parameters with %s
|
|
params -- Parameters list. First element replaces first %s and so on. Optional.
|
|
"""
|
|
# Get a worker and acquire its lock
|
|
worker = self.getWorker()
|
|
worker.lock.acquire()
|
|
|
|
try:
|
|
# Create cursor, execute query and commit
|
|
cursor = worker.connection.cursor(MySQLdb.cursors.DictCursor)
|
|
cursor.execute(query, params)
|
|
return cursor.lastrowid
|
|
finally:
|
|
# Close the cursor and release worker's lock
|
|
if cursor:
|
|
cursor.close()
|
|
worker.lock.release()
|
|
|
|
def fetch(self, query, params = (), all = False):
|
|
"""
|
|
Fetch a single value from db that matches given query
|
|
|
|
query -- Query to execute. You can bind parameters with %s
|
|
params -- Parameters list. First element replaces first %s and so on. Optional.
|
|
all -- Fetch one or all values. Used internally. Use fetchAll if you want to fetch all values.
|
|
"""
|
|
# Get a worker and acquire its lock
|
|
worker = self.getWorker()
|
|
worker.lock.acquire()
|
|
|
|
try:
|
|
# Create cursor, execute the query and fetch one/all result(s)
|
|
cursor = worker.connection.cursor(MySQLdb.cursors.DictCursor)
|
|
cursor.execute(query, params)
|
|
if all == True:
|
|
return cursor.fetchall()
|
|
else:
|
|
return cursor.fetchone()
|
|
finally:
|
|
# Close the cursor and release worker's lock
|
|
if cursor:
|
|
cursor.close()
|
|
worker.lock.release()
|
|
|
|
def fetchAll(self, query, params = ()):
|
|
"""
|
|
Fetch all values from db that matche given query.
|
|
Calls self.fetch with all = True.
|
|
|
|
query -- Query to execute. You can bind parameters with %s
|
|
params -- Parameters list. First element replaces first %s and so on. Optional.
|
|
"""
|
|
return self.fetch(query, params, True)
|