Files
xian-favor/xian_favor/__pycache__/db.cpython-310.pyc

164 lines
14 KiB
Plaintext
Raw Normal View History

2026-04-14 17:27:37 +08:00
o
Q<06>i<EFBFBD>B<00>@spdZddlZddlZddlmZddlmZmZmZmZddl m
Z
ddl m Z m Z mZGdd <09>d <09>Ze<0F>ZdS)
u数据库操作<E6938D>N)<01>datetime)<04>Optional<61>List<73>Dict<63>Any)<01>contextmanager<65>)<03> DATABASE_URL<52> TODO_STATUS<55>PRIORITY_LEVELSc@sVeZdZdZefdefdd<04>Zdd<06>Zedd<08><00>Z d d
<EFBFBD>Z
dOdededededededededede ede fdd<1B>Z de deeeeffdd<1E>Z dPdeded!ed"ed#e d$e de eeeffd%d&<26>Zde defd'd(<28>Zde defd)d*<2A>ZdQd,ed-ede fd.d/<2F>Zde eeeffd0d1<64>Zd2e d,edefd3d4<64>ZdRd2e d,edefd5d6<64>Zde de efd7d8<64>Zde de efd9d:<3A>ZdSd;ed,ede fd<d=<3D>Zde eeeffd>d?<3F>Zd@e deeeeffdAdB<64>ZdRd@e d;ed,edefdCdD<64>Zd@e defdEdF<64>Z dTde d;edHede fdIdJ<64>Z!de de eeeffdKdL<64>Z"deeeffdMdN<64>Z#d S)U<>DatabaseuSQLite数据库管理<E7AEA1>db_pathcCs||_d|_dS)NF)r <00> _initialized)<02>selfr <00>r<00>F/home/xian/.openclaw/workspace-coder/works/xian-favor/xian_favor/db.py<70>__init__s
zDatabase.__init__cCs|jrdS|<00><01>d|_dS)u确保数据库已初始化NT)r<00>_init_db)rrrr<00> _ensure_inits
zDatabase._ensure_initccsN<00>tj|jdd<02>}tj|_|<01>d<03>|<01>d<04>z
|VW|<01><06>dS|<01><06>w)u获取数据库连接g>@)<01>timeoutzPRAGMA journal_mode=WALzPRAGMA busy_timeout=30000N)<07>sqlite3<65>connectr <00>Row<6F> row_factory<72>execute<74>close)r<00>connrrr<00>get_conns<02>

zDatabase.get_conncCs<>|<00><00><00>C}|<01><01>}|<02>d<01>|<02>d<02>|<02>d<03>|<02>d<04>|<02>d<05>|<02>d<06>|<02>d<07>|<02>d<08>|<02>d <09>|<02>d
<EFBFBD>|<01><03>Wd <00>d S1sJwYd S) u初始化数据库表aH
CREATE TABLE IF NOT EXISTS items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL DEFAULT 'text',
title TEXT,
content TEXT,
url TEXT,
source TEXT,
status TEXT DEFAULT 'pending',
priority TEXT DEFAULT 'medium',
due_date TEXT,
note TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
)
a
CREATE TABLE IF NOT EXISTS tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
color TEXT DEFAULT '#3498db',
created_at TEXT NOT NULL
)
a<>
CREATE TABLE IF NOT EXISTS item_tags (
item_id INTEGER NOT NULL,
tag_id INTEGER NOT NULL,
PRIMARY KEY (item_id, tag_id),
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE,
FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
)
a 
CREATE TABLE IF NOT EXISTS emails (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
name TEXT,
created_at TEXT NOT NULL
)
a<>
CREATE TABLE IF NOT EXISTS email_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
item_id INTEGER NOT NULL,
email TEXT NOT NULL,
sent_at TEXT NOT NULL,
success INTEGER DEFAULT 1,
FOREIGN KEY (item_id) REFERENCES items(id) ON DELETE CASCADE
)
z8CREATE INDEX IF NOT EXISTS idx_items_type ON items(type)z<CREATE INDEX IF NOT EXISTS idx_items_status ON items(status)zACREATE INDEX IF NOT EXISTS idx_items_created ON items(created_at)zCCREATE INDEX IF NOT EXISTS idx_item_tags_item ON item_tags(item_id)zACREATE INDEX IF NOT EXISTS idx_item_tags_tag ON item_tags(tag_id)N)r<00>cursorr<00>commit<69>rrrrrrr's







"<22>zDatabase._init_db<64>textN<74>pending<6E>medium<75>type<70>title<6C>content<6E>url<72>source<63>status<75>priority<74>due_date<74>note<74>tags<67>returnc Cs<>|<00><00>t<01><02><00><03>} |dkr|tvrd}|tvrd}|<00><06><00>/} | <0C><07>} | <0A>d||||||||| | | f <0B>| j }|
r@|<00>
| ||
<EFBFBD>| <0C> <0B>|Wd<00>S1sPwYdS)u创建新条目<E69DA1>todor"r#z<>
INSERT INTO items (type, title, content, url, source, status, priority, due_date, note, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
N) rr<00>now<6F> isoformatr
r rrr<00> lastrowid<69>_add_tags_to_itemr)rr$r%r&r'r(r)r*r+r,r-r0rr<00>item_idrrr<00> create_itemts" 
<04>$<24>zDatabase.create_itemr4cCs||<00><00><00>0}|<02><01>}|<03>d|f<01>|<03><03>}|s Wd<00>dSt|<04>}|<00>||<01>|d<|Wd<00>S1s7wYdS)u获取单个条目z SELECT * FROM items WHERE id = ?Nr-)rrr<00>fetchone<6E>dict<63>_get_item_tags)rr4rr<00>row<6F>itemrrr<00>get_item<65>s
<10>$<24>zDatabase.get_item<65>2r<00>tag<61>keyword<72>limit<69>offsetcCs.|<00><00><00><>}|<07><01>}d} g}
g} |r| d7} | <0B>d<03>|
<EFBFBD>|<03>|r+| <0B>d<04>|
<EFBFBD>|<01>|r7| <0B>d<05>|
<EFBFBD>|<02>|rL| <0B>d<06>d|<04>d<07>} |
<EFBFBD>| | | g<03>| rW| dd <09>| <0B>7} | d
7} |
<EFBFBD>||g<02>|<08>| |
<EFBFBD>g} |<08><06>D]}t|<0E>}|<00>||d <00>|d <| <0A>|<0F>qn| Wd <00>S1s<>wYd S)u 列出条目z SELECT DISTINCT i.* FROM items izG JOIN item_tags it ON i.id = it.item_id JOIN tags t ON it.tag_id = t.idz
t.name = ?z
i.type = ?z i.status = ?z5(i.title LIKE ? OR i.content LIKE ? OR i.note LIKE ?)<29>%z WHERE z AND z, ORDER BY i.created_at DESC LIMIT ? OFFSET ?<3F>idr-N) rr<00>append<6E>extend<6E>joinr<00>fetchallr7r8)rr$r)r=r>r?r@rr<00>query<72>params<6D>
conditions<EFBFBD>keyword_pattern<72>itemsr9r:rrr<00>
list_items<EFBFBD>s>







    $<24>zDatabase.list_itemsc  s<>gd<01><01><00>fdd<03>|<02><00>D<00>}|sd|vrdSt<01><02><00><03>}|<00><04><00>S}|<05><05>}|rLd<06>dd<08>|<03><07>D<00><01>}|d 7}t|<03> <09><00>||g}|<06>
d
|<07>d <0B>|<08>d|vrd|<06>
d |f<01>|drd|<00> |||d<00>|<05> <0C>|j d kWd<00>S1swwYdS)u 更新条目) r$r%r&r'r(r)r*r+r,csi|] \}}|<01>vr||<02>qSrr)<03>.0<EFBFBD>k<>v<><01>allowed_fieldsrr<00>
<dictcomp><3E>sz(Database.update_item.<locals>.<dictcomp>r-Fz, css<00>|]}|<01>d<00>VqdS)z = ?Nr)rMrNrrr<00> <genexpr><3E>s<02>z'Database.update_item.<locals>.<genexpr>z, updated_at = ?zUPDATE items SET z WHERE id = ?z'DELETE FROM item_tags WHERE item_id = ?rN)rKrr0r1rrrE<00>keys<79>list<73>valuesrr3r<00>rowcount) rr4<00>kwargs<67> update_fieldsr0rr<00>
set_clauserVrrPr<00> update_item<65>s&  
$<24>zDatabase.update_itemcC<00>T|<00><00><00>}|<02><01>}|<03>d|f<01>|<02><03>|jdkWd<00>S1s#wYdS)u 删除条目zDELETE FROM items WHERE id = ?rN<>rrrrrW<00>rr4rrrrr<00> delete_item<65><00>
$<24>zDatabase.delete_item<65>#3498db<64>name<6D>colorc C<00><>t<00><01><00><02>}|<00><03><00><}|<04><04>}z|<05>d|||f<03>|<04><06>|jWWd<00>Stj yE|<05>d|f<01>|<05>
<EFBFBD>dYWd<00>Sw1sIwYdS)u 创建标签z;INSERT INTO tags (name, color, created_at) VALUES (?, ?, ?)N<>"SELECT id FROM tags WHERE name = ?rB<00> rr0r1rrrrr2r<00>IntegrityErrorr6)rrbrcr0rrrrr<00>
create_tag<EFBFBD><00> 
<04><10><10><14>zDatabase.create_tagcC<00>P|<00><00><00>}|<01><01>}|<02>d<01>dd<03>|<02><03>D<00>Wd<00>S1s!wYdS)u列出所有标签z<E7ADBE>
SELECT t.*, COUNT(it.item_id) as item_count
FROM tags t
LEFT JOIN item_tags it ON t.id = it.tag_id
GROUP BY t.id
ORDER BY t.name
cS<00>g|]}t|<01><01>qSr<00>r7<00>rMr9rrr<00>
<listcomp> <00>z&Database.list_tags.<locals>.<listcomp>N<>rrrrFr rrr<00> list_tagss

$<24>zDatabase.list_tags<67>tag_idcCs<>|<00><00><00>2}|<03><01>}|<04>d||f<02>|<04><03>r Wd<00>dS|<04>d||f<02>|<03><04>|jdkWd<00>S1s9wYdS)u更新标签名称z.SELECT id FROM tags WHERE name = ? AND id != ?NFz%UPDATE tags SET name = ? WHERE id = ?r)rrrr6rrW<00>rrrrbrrrrr<00>
update_tag s
<10>$<24>zDatabase.update_tagcCsl|<00><00><00>(}|<03><01>}|r|<04>d|f<01>n |r|<04>d|f<01>|<03><03>|jdkWd<00>S1s/wYdS)u 删除标签zDELETE FROM tags WHERE name = ?zDELETE FROM tags WHERE id = ?rNr]rsrrr<00>
delete_tags
$<24>zDatabase.delete_tagc Csz|<01><00>}|D]4}|<05><01>}|sq|<04>d|f<01>|<04><03>}|r!|d}nt<04><05><00><06>}|<04>d||f<02>|j}|<04>d||f<02>qdS)u为条目添加标签rerBzCINSERT INTO tags (name, color, created_at) VALUES (?, '#3498db', ?)z?INSERT OR IGNORE INTO item_tags (item_id, tag_id) VALUES (?, ?)N)r<00>striprr6rr0r1r2) rrr4r-r<00>tag_namer9rrr0rrrr3&s$
 <04><06><04>zDatabase._add_tags_to_itemcCs(|<01><00>}|<03>d|f<01>dd<03>|<03><02>D<00>S)u获取条目的标签z<E7ADBE>
SELECT t.name FROM tags t
JOIN item_tags it ON t.id = it.tag_id
WHERE it.item_id = ?
ORDER BY t.name
cSsg|]}|d<00>qS)rbrrmrrrrnEroz+Database._get_item_tags.<locals>.<listcomp>)rrrF)rrr4rrrrr8<s
<04>zDatabase._get_item_tags<67>emailc Crd)u 创建邮箱z=INSERT INTO emails (email, name, created_at) VALUES (?, ?, ?)Nz%SELECT id FROM emails WHERE email = ?rBrf)rrxrbr0rrrrr<00> create_emailIrizDatabase.create_emailcCrj)u列出所有邮箱z-SELECT * FROM emails ORDER BY created_at DESCcSrkrrlrmrrrrn]roz(Database.list_emails.<locals>.<listcomp>Nrpr rrr<00> list_emailsXs

$<24>zDatabase.list_emails<6C>email_idcCsZ|<00><00><00>}|<02><01>}|<03>d|f<01>|<03><03>}|rt|<04>ndWd<00>S1s&wYdS)u获取单个邮箱z!SELECT * FROM emails WHERE id = ?N)rrrr6r7)rr{rrr9rrr<00> get_email_s
$<24>zDatabase.get_emailcCs<>t<00><01><00><02>}|<00><03><00>O}|<05><04>}|r&|<06>d||f<02>|<06><06>r& Wd<00>dS|r4|r4|<06>d|||f<03>n|r?|<06>d||f<02>n
|rI|<06>d||f<02>|<05><07>|jdkWd<00>S1s\wYdS)u 更新邮箱z1SELECT id FROM emails WHERE email = ? AND id != ?NFz2UPDATE emails SET email = ?, name = ? WHERE id = ?z(UPDATE emails SET email = ? WHERE id = ?z'UPDATE emails SET name = ? WHERE id = ?r) rr0r1rrrr6rrW)rr{rxrbr0rrrrr<00> update_emailgs" 
<10>$<24>zDatabase.update_emailcCr\)u 删除邮箱zDELETE FROM emails WHERE id = ?rNr])rr{rrrrr<00> delete_emailzr`zDatabase.delete_emailT<6C>successcCsjt<00><01><00><02>}|<00><03><00>!}|<05><04>}|<06>d||||rdndf<04>|<05><06>|jWd<00>S1s.wYdS)u记录邮件发送z{
INSERT INTO email_logs (item_id, email, sent_at, success)
VALUES (?, ?, ?, ?)
rrN)rr0r1rrrrr2)rr4rxrr0rrrrr<00>log_email_send<6E>s 
<04>$<24>zDatabase.log_email_sendcCsT|<00><00><00>}|<02><01>}|<03>d|f<01>dd<03>|<03><03>D<00>Wd<00>S1s#wYdS)u!获取收藏的邮件发送记录z<E5BD95>
SELECT * FROM email_logs
WHERE item_id = ?
ORDER BY sent_at DESC
cSrkrrlrmrrrrn<00>roz+Database.get_email_logs.<locals>.<listcomp>Nrpr^rrr<00>get_email_logs<67>s
<04>$<24>zDatabase.get_email_logscCs<>|<00><00>|<00><01><00>J}|<01><02>}i}|<02>d<01>|<02><04>d|d<|<02>d<04>dd<06>|<02><05>D<00>|d<|<02>d<08>d d<06>|<02><05>D<00>|d
<|<02>d <0B>|<02><04>d|d <|Wd <00>S1sUwYd S)u获取统计信息z#SELECT COUNT(*) as count FROM items<6D>count<6E>totalz7SELECT type, COUNT(*) as count FROM items GROUP BY typecS<00>i|] }|d|d<00>qS)r$r<>rrmrrrrR<00><00>z"Database.stats.<locals>.<dictcomp><3E>by_typezOSELECT status, COUNT(*) as count FROM items WHERE type = 'todo' GROUP BY statuscSr<>)r)r<>rrmrrrrR<00>r<><00> todo_statusz"SELECT COUNT(*) as count FROM tagsr-N)rrrrr6rF)rrr<00>statsrrrr<><00>s




$<24>zDatabase.stats)
r!NNNNr"r#NNN)NNNNr<r)ra)NN)N)T)$<24>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__doc__r <00>strrrrrrr<00>intr5rrrr;rL<00>boolr[r_rhrqrtrur3r8ryrzr|r}r~r<>r<>r<>rrrrr sp
 M<10><02><02><02><02><02><02><02>
<EFBFBD> <10><02><02><02>
<EFBFBD>,
    
  r )r<>r<00>jsonr<00>typingrrrr<00>
contextlibr<00>configr r
r r <00>dbrrrr<00><module>s  
.