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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
# File 'lib/heathrow/migrations/001_initial_schema.rb', line 9
def self.up(db)
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS schema_version (
version INTEGER PRIMARY KEY,
applied_at INTEGER NOT NULL
);
SQL
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
source_id INTEGER NOT NULL,
external_id TEXT NOT NULL,
thread_id TEXT,
parent_id INTEGER,
sender TEXT NOT NULL,
sender_name TEXT,
recipients TEXT NOT NULL,
cc TEXT,
bcc TEXT,
subject TEXT,
content TEXT NOT NULL,
html_content TEXT,
timestamp INTEGER NOT NULL,
received_at INTEGER NOT NULL,
read BOOLEAN DEFAULT 0,
starred BOOLEAN DEFAULT 0,
archived BOOLEAN DEFAULT 0,
labels TEXT,
attachments TEXT,
metadata TEXT,
UNIQUE(source_id, external_id),
FOREIGN KEY(source_id) REFERENCES sources(id) ON DELETE CASCADE,
FOREIGN KEY(parent_id) REFERENCES messages(id) ON DELETE SET NULL
);
SQL
db.exec "CREATE INDEX IF NOT EXISTS idx_messages_source ON messages(source_id)"
db.exec "CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(timestamp DESC)"
db.exec "CREATE INDEX IF NOT EXISTS idx_messages_thread ON messages(thread_id)"
db.exec "CREATE INDEX IF NOT EXISTS idx_messages_read ON messages(read)"
db.exec "CREATE INDEX IF NOT EXISTS idx_messages_sender ON messages(sender)"
db.exec <<-SQL
CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
subject,
content,
sender,
content='messages',
content_rowid='id'
);
SQL
db.exec <<-SQL
CREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN
INSERT INTO messages_fts(rowid, subject, content, sender)
VALUES (new.id, new.subject, new.content, new.sender);
END;
SQL
db.exec <<-SQL
CREATE TRIGGER IF NOT EXISTS messages_ad AFTER DELETE ON messages BEGIN
DELETE FROM messages_fts WHERE rowid = old.id;
END;
SQL
db.exec <<-SQL
CREATE TRIGGER IF NOT EXISTS messages_au AFTER UPDATE ON messages BEGIN
UPDATE messages_fts
SET subject = new.subject, content = new.content, sender = new.sender
WHERE rowid = new.id;
END;
SQL
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS sources (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
plugin_type TEXT NOT NULL,
enabled BOOLEAN DEFAULT 1,
config TEXT NOT NULL,
capabilities TEXT NOT NULL,
last_sync INTEGER,
last_error TEXT,
message_count INTEGER DEFAULT 0,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
SQL
db.exec "CREATE INDEX IF NOT EXISTS idx_sources_enabled ON sources(enabled)"
db.exec "CREATE INDEX IF NOT EXISTS idx_sources_plugin_type ON sources(plugin_type)"
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS views (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
key_binding TEXT UNIQUE,
filters TEXT NOT NULL,
sort_order TEXT DEFAULT 'timestamp DESC',
is_remainder BOOLEAN DEFAULT 0,
show_count BOOLEAN DEFAULT 1,
color INTEGER,
icon TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
SQL
db.exec "CREATE INDEX IF NOT EXISTS idx_views_key_binding ON views(key_binding)"
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
primary_email TEXT,
identities TEXT,
phone TEXT,
avatar_url TEXT,
tags TEXT,
notes TEXT,
message_count INTEGER DEFAULT 0,
last_contact INTEGER,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
SQL
db.exec "CREATE INDEX IF NOT EXISTS idx_contacts_email ON contacts(primary_email)"
db.exec "CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(name)"
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS drafts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
source_id INTEGER,
reply_to_id INTEGER,
recipients TEXT NOT NULL,
cc TEXT,
bcc TEXT,
subject TEXT,
content TEXT NOT NULL,
attachments TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
FOREIGN KEY(source_id) REFERENCES sources(id) ON DELETE SET NULL,
FOREIGN KEY(reply_to_id) REFERENCES messages(id) ON DELETE SET NULL
);
SQL
db.exec "CREATE INDEX IF NOT EXISTS idx_drafts_updated ON drafts(updated_at DESC)"
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS filters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
enabled BOOLEAN DEFAULT 1,
priority INTEGER DEFAULT 0,
conditions TEXT NOT NULL,
actions TEXT NOT NULL,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
SQL
db.exec "CREATE INDEX IF NOT EXISTS idx_filters_enabled ON filters(enabled)"
db.exec "CREATE INDEX IF NOT EXISTS idx_filters_priority ON filters(priority DESC)"
db.exec <<-SQL
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at INTEGER NOT NULL
);
SQL
db.exec "INSERT INTO schema_version (version, applied_at) VALUES (?, ?)",
[VERSION, Time.now.to_i]
end
|