-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdb.py
executable file
·162 lines (137 loc) · 5.31 KB
/
db.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import sqlite3
from collections import defaultdict
from datetime import date, datetime, timedelta
import aiosqlite
import asyncio
def get_date_list(today, days=30):
date = sorted([(datetime.strptime(today, '%Y-%m-%d') - timedelta(days=i)).strftime('%Y-%m-%d')
for i in range(1, days + 1)])
return date
class Database():
def __init__(self, path='usages.db'):
self.path = path
conn = sqlite3.connect(self.path)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS usages
(name VARCHAR(20) NOT NULL,
usage INT NOT NULL,
time DATETIME NOT NULL);''')
cursor.execute('''DROP INDEX IF EXISTS name_index;''')
cursor.execute('''DROP INDEX IF EXISTS time_index;''')
conn.commit()
cursor.close()
conn.close()
async def clear_async(self, month_like):
print('=' * 20, month_like, '=' * 20)
db = await aiosqlite.connect(self.path)
cursor = await db.execute(f'''
SELECT name, SUM(usage) FROM usages
WHERE time LIKE '{month_like}_%'
GROUP BY name;
''')
rows = await cursor.fetchall()
print('Rows to be deleted:', rows)
await cursor.close()
await db.close()
p = [(name, usage, month_like) for name, usage in rows if int(usage) > 0]
self.insert(p, auto_time=False)
async with aiosqlite.connect(self.path) as db:
await db.execute(f'''
DELETE FROM usages
WHERE time LIKE '{month_like}_%_%'
''')
await db.commit()
db = await aiosqlite.connect(self.path)
cursor = await db.execute(f'''
SELECT * FROM usages
WHERE time LIKE '{month_like}%'
''')
rows = await cursor.fetchall()
print('Now exsiting:', rows)
await cursor.close()
await db.close()
async with aiosqlite.connect(self.path) as db:
await db.execute('''vacuum;''')
await db.commit()
return rows
def clear(self, months=['2020-05']):
for month in months:
asyncio.run(self.clear_async(month))
async def insert_async(self, name_usage_list=[('test', 1)], auto_time=True):
async with aiosqlite.connect(self.path) as db:
if auto_time:
await db.executemany('''
INSERT INTO USAGES (NAME, USAGE, TIME)
VALUES (?, ?, datetime('now', 'localtime'));''', name_usage_list)
else:
await db.executemany('''
INSERT INTO USAGES (NAME, USAGE, TIME)
VALUES (?, ?, ?);''', name_usage_list)
await db.commit()
def insert(self, name_usage_list=[('user_test', 1)], auto_time=True):
asyncio.run(self.insert_async(name_usage_list,
auto_time=auto_time))
print('inserted!')
async def past_async(self, last_what='-7 days'):
magic_number = 1.0 / 59.9 / 1024 # GB-h
db = await aiosqlite.connect(self.path)
cursor = await db.execute(f'''
SELECT name, SUM(usage * {magic_number} ) FROM usages
WHERE time > datetime('now', '{last_what}', 'localtime')
GROUP BY name;
''')
rows = await cursor.fetchall()
await cursor.close()
await db.close()
return rows
def past(self, last_what='-7 days'):
'''Returns [(user, usage)] in GB-h.'''
return asyncio.run(self.past_async(last_what))
def past_1_hour(self):
return self.past('-1 hour')
def past_24_hours(self):
return self.past('-24 hours')
def past_3_days(self):
return self.past('-3 days')
def past_7_days(self):
return self.past('-7 days')
def get_all(self):
conn = sqlite3.connect(self.path)
cursor = conn.cursor()
cursor.execute('''
SELECT name, usage, time FROM usages;
''')
values = cursor.fetchall()
cursor.close()
conn.close()
return values
async def search_name_async(self, user):
"""Search the monthly report."""
magic_number = 1.0 / 59.9 / 1024 # GB-h
db = await aiosqlite.connect(self.path)
cursor = await db.execute(f'''
SELECT name, date(time), sum(usage * {magic_number} )
FROM usages
WHERE name = ? AND time > datetime("now", "-31 days")
GROUP BY name, date(time);''', (user.strip(),))
rows = await cursor.fetchall()
await cursor.close()
await db.close()
return rows
def search_name(self, user):
return asyncio.run(self.search_name(user))
def summary(self, user):
raw = self.search_name(user.strip())
date_l = get_date_list(str(date.today()))
res = defaultdict(float)
for d in date_l:
res[d] = 0
for (user, d, usage) in raw:
res[d] = usage
return res
if __name__ == "__main__":
import time
t = time.time()
db = Database()
db.clear([f'2020-{m:02d}' for m in range(4, 8)])
print(time.time() - t)