import pandas as pd passwords = pd.read_csv('rockyou.txt',header=None,on_bad_lines='skip',encoding = "ISO-8859-1") passwords.dropna(inplace=True)
Membuat database SQlite
Adapun langkah selanjut nya yaitu memasukannya ke dalam record table
import sqlite3 from sqlite3 import Error class DB(): def __init__(self,db_file): self.db_file = db_file self.conn = None self.sql_buat_tabel = """ CREATE TABLE IF NOT EXISTS password ( id integer PRIMARY KEY, pwd text NOT NULL, keterangan text ); """ self.buka() self.buat_tabel() def buka(self): try: self.conn = sqlite3.connect(self.db_file) return self.conn except Error as e: print(e) return self.conn def buat_tabel(self): try: c = self.conn.cursor() c.execute(self.sql_buat_tabel) except Error as e: print(e) def masukan_data(self,info): sql = ''' INSERT INTO password(pwd,keterangan) VALUES(?,?) ''' cur = self.conn.cursor() cur.execute(sql, info) #self.conn.commit() def get(self): cur = self.conn.cursor() cur.execute("SELECT * FROM password") results = pd.DataFrame.from_records(data = cur.fetchall(),columns=['id','pwd','keterangan']) return results def update_data(self,info): sql = ''' UPDATE password SET keterangan = ? WHERE id = ? ''' cur = self.conn.cursor() cur.execute(sql, info) self.conn.commit()
Oiya untuk commit() nya saya off kan, karena akan disesuaikan dengan kebutuhan
def masukan_data(self,info): sql = ''' INSERT INTO password(pwd,keterangan) VALUES(?,?) ''' cur = self.conn.cursor() cur.execute(sql, info) #self.conn.commit()
kemudian kita akan memasukannya nya dengan aturan panjang minimal karakter 6 dan akan commit kalau sudah 1000 record
db = DB('rockyou.sqlite') for i,pwd in enumerate(passwords[0]): #password minimal panjang 6 karakter if len(pwd)>=6: data = (pwd,'') db.masukan_data(data) if (i%1000)==0: db.conn.commit() print("commit: ",i)
Sebenarya untuk insert data paling gampang dan cepet, bisa kalian lakukan Import CSV via Belajar Database Relational SQL Lite Bagian 3 DB Browser Sqlite
Selanjutnya, kalian bisa lihat function dari update_date() yang merupakan update dan langsung panggil commit()
def update_data(self,info): sql = ''' UPDATE password SET keterangan = ? WHERE id = ? ''' cur = self.conn.cursor() cur.execute(sql, info) self.conn.commit()
Update Record menggunakan Proses Threading di Sqlite
Inilah yang jadi panggal permasalahan, ketika saya akan melakukan update record menggunakan proses threading di Sqlite ternyata ada pesan error. Berikut ketika saya akan memanggil sebuah function dummy_hack() dan autologin() –> sengaja saya tidak lengkapi detail
def dummy_hack(db,record): pwd = record['pwd'] index = record['id'] #code hack dibawah ini sukses = autologin('@username',pwd) #selesai record_update = ('sudah dicek',int(index)) db.update_data(record_update) if sukses: stopall()
Kemudian kita panggil multi threading biar proses nya pararel.
import time import os import threading import pandas as pd results = db.get() #pakai pandas buat query --> #buat pisahkan record yang belum dicek/digunakan uncek = results.query("keterangan!='sudah dicek'") uncek.reset_index(inplace=True)
kemudian lakukan looping untuk setiap record dan lakukan threading!
for i in range(0,len(uncek)): if os.path.exists('stop.txt'): break record = uncek.loc[i] t = threading.Thread(target = dummy_hack, args = (db,record)) t.start() # t.join() time.sleep(0.5)
dan apa yang terjadi!
ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id 23508 and this is thread id 22640
Namanya juga Sqlite yang cocok untuk single user dan single connection! maka ketika ada multiple operation seperti update/insert/delete diatas dalam waktu yang bersamaan tentu akan error!
Solusi yang rumit bisa kalian baca dokumentasi berikut yaitu Threading Safe Mode
https://www.sqlite.org/threadsafe.html
Tapi males baca, euy
Sqlite3worker untuk Multi Threading pada Database Sqlite
Solusi paling gampang yaitu cari library saja dan ketemulah solusi menarik dari https://github.com/dashawn888/sqlite3worker, tentu saya buat class DB menjadi DB_Worker dengan tugas hanya update dan get saja.
class DB_Worker(): def __init__(self,db_file): self.db_file = db_file self.worker = Sqlite3Worker(self.db_file) def get(self): result = self.worker.execute("SELECT * FROM password") result = pd.DataFrame(result,columns=['id','pwd','keterangan']) return result def update_data(self,data): self.worker.execute("UPDATE password SET keterangan = ? WHERE id = ?", data)
Kita panggil ulang lagi class DB_Worker()
db = DB_Worker('rockyou.sqlite') results = db.get() uncek = results.query("keterangan!='cek'") uncek.reset_index(inplace=True)
dan tentunya lakukan multi threading tanpa masalah!
for i in range(0,len(uncek)): if os.path.exists('stop.txt'): break record = uncek.loc[i] t = threading.Thread(target = dummy_hack, args = (db,record)) t.start() time.sleep(0.5) db.worker.close()
kalau kurang kenceng! time.sleep(0.001) biar makin ngebut threading nya!
Kesimpulan
Beberapa kerjaan sebelumnya, saya terbiasa menggunakan MySql bila bekerja dengan Database yang mengharuskan Multi Threading maka dengan Sqlite3worker untuk Multi Threading pada Database Sqlite merupakan solusi yang layak kalian gunakan! tanpa perlu ribet!