#!/usr/local/bin/python3 # -*- coding: utf-8 -*- '''leveldb helper''' import leveldb from openpyxl import Workbook from openpyxl import load_workbook from openpyxl import cell def exist(db_src, key): '''Safely check whether key exist or not''' _key_obj = bytes(key.encode('utf-8')) if isinstance(key, str) else key try: db_src.Get(_key_obj) return True except KeyError: return False def count(db_src, k_filter, v_filter): '''Count database items, support key filter and/or value filter, return total and valid.''' total, valid = 0, 0 for _k, _v in db_src.RangeIter(): total += 1 if k_filter: if _k.find(k_filter) == -1: continue if v_filter: if _v.find(v_filter) == -1: continue valid += 1 return total, valid def copy(db_src, db_dst, k_filter): '''copy db_src to db_dst, support key filter, return total and valid.''' total, valid = 0, 0 for _k, _v in db_src.RangeIter(): total += 1 if k_filter: if _k.find(k_filter) != -1: valid += 1 db_dst.Put(_k, _v, sync=True) else: valid += 1 db_dst.Put(_k, _v, sync=True) return total, valid def delete(db_src, db_dst): '''Delete db_src items in db_dst.''' for _k, _v in db_src.RangeIter(): db_dst.Delete(_k) def diff(db_src, db_dst, db_diff): '''Find differents between db_src and db_dst, save to db_diff, return diff count.''' diff_count = 0 for _k, _v in db_src.RangeIter(): if not exist(db_dst, _k): diff_count += 1 db_diff.Put(_k, _v) return diff_count def clean_copy(db_src, db_dst): '''copy db_src to db_dst, clean empty value, return total count.''' total = 0 for _k, _v in db_src.RangeIter(): if _v: db_dst.Put(_k, _v) total += 1 return total def dump(db_src): '''Dump database key and value items.''' _db = leveldb.LevelDB(db_src, create_if_missing=False) if isinstance(db_src, str) else db_src for _k, _v in _db.RangeIter(): print(_k.decode(), _v.decode()) def db_to_text(from_db, to_text): '''Transfer leveldb to text file.''' _db = leveldb.LevelDB(from_db, create_if_missing=False) if isinstance(from_db, str) else from_db with open(to_text, 'w', encoding='utf-8') as _f: for _k, _v in _db.RangeIter(): _f.write(_k.decode() + ',' + _v.decode() + '\n') def text_to_db(from_text, to_db, split_char): '''Transfer text file to leveldb, return total and invalid count.''' total, invalid = 0, 0 _split = split_char if split_char else ',' _db = leveldb.LevelDB(to_db, create_if_missing=True) if isinstance(to_db, str) else to_db with open(from_text, 'r', encoding='utf-8') as _f: lines = _f.readlines() total = len(lines) for line in lines: if not line: invalid += 1 continue # line = line.strip() if _split in line: _sub = line.split(_split, 1) _db.Put(_sub[0].encode('utf-8'), _sub[1].encode('utf-8')) else: _db.Put(line, '') return total, invalid def db_to_excel(from_db, to_excel): '''Transfer leveldb to Excel file, return total count.''' _db = leveldb.LevelDB(from_db, create_if_missing=False) if isinstance(from_db, str) else from_db _wb = Workbook() _ws = _wb.active total = 0 for _k, _v in _db.RangeIter(): _ws.append([_k.decode(), _v.decode()]) total += 1 _wb.save(to_excel) return total def excel_to_db(from_excel, to_db): '''Transfer Excel file to leveldb, return total count.''' _wb = load_workbook(from_excel, read_only=True) _ws = _wb.active _db = leveldb.LevelDB(to_db, create_if_missing=True) if isinstance(to_db, str) else to_db total = 0 for _row in _ws.iter_rows(min_row=2, min_col=1, max_col=1): if _row and _row[0] and _row[1]: _key, _value = '', '' if _row[0].data_type == cell.Cell.TYPE_STRING: _key = _row[0].value.encode('utf-8') _key = ''.join(_key.split()) if _row[1].data_type == cell.Cell.TYPE_STRING: _value = _row[0].value.encode('utf-8') _value = ''.join(_value.split()) _db.Put(_key, _value) total += 1 _wb.close() return total