Skip to content

Commit 01070e1

Browse files
initial implementation
1 parent 949a7d8 commit 01070e1

14 files changed

+972
-647
lines changed

packages/attachments/src/AbstractAttachmentQueue.ts

Lines changed: 0 additions & 539 deletions
This file was deleted.
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import { AbstractPowerSyncDatabase, ILogger, Transaction } from '@powersync/common';
2+
import { AttachmentRecord, AttachmentState, attachmentFromSql } from './Schema.js';
3+
4+
export class AttachmentContext {
5+
db: AbstractPowerSyncDatabase;
6+
tableName: string;
7+
logger: ILogger;
8+
9+
constructor(db: AbstractPowerSyncDatabase, tableName: string = 'attachments', logger: ILogger) {
10+
this.db = db;
11+
this.tableName = tableName;
12+
this.logger = logger;
13+
}
14+
15+
watchActiveAttachments(onUpdate: () => void): AbortController {
16+
const abortController = new AbortController();
17+
this.db.watchWithCallback(
18+
/* sql */
19+
`
20+
SELECT
21+
*
22+
FROM
23+
${this.tableName}
24+
WHERE
25+
state = ?
26+
OR state = ?
27+
OR state = ?
28+
ORDER BY
29+
timestamp ASC
30+
`,
31+
[AttachmentState.QUEUED_UPLOAD, AttachmentState.QUEUED_DOWNLOAD, AttachmentState.QUEUED_DELETE],
32+
{
33+
onResult: () => {
34+
onUpdate();
35+
}
36+
},
37+
{
38+
signal: abortController.signal
39+
}
40+
);
41+
42+
return abortController;
43+
}
44+
45+
async getActiveAttachments(): Promise<any[]> {
46+
const attachments = await this.db.getAll(
47+
/* sql */
48+
`
49+
SELECT
50+
*
51+
FROM
52+
${this.tableName}
53+
WHERE
54+
state = ?
55+
OR state = ?
56+
OR state = ?
57+
ORDER BY
58+
timestamp ASC
59+
`,
60+
[AttachmentState.QUEUED_UPLOAD, AttachmentState.QUEUED_DOWNLOAD, AttachmentState.QUEUED_DELETE]
61+
);
62+
63+
return attachments.map(attachmentFromSql);
64+
}
65+
66+
async getArchivedAttachments(): Promise<AttachmentRecord[]> {
67+
const attachments = await this.db.getAll(
68+
/* sql */
69+
`
70+
SELECT
71+
*
72+
FROM
73+
${this.tableName}
74+
WHERE
75+
state = ?
76+
ORDER BY
77+
timestamp ASC
78+
`,
79+
[AttachmentState.ARCHIVED]
80+
);
81+
82+
return attachments.map(attachmentFromSql);
83+
}
84+
85+
async getAttachments(): Promise<AttachmentRecord[]> {
86+
const attachments = await this.db.getAll(
87+
/* sql */
88+
`
89+
SELECT
90+
*
91+
FROM
92+
${this.tableName}
93+
ORDER BY
94+
timestamp ASC
95+
`,
96+
[]
97+
);
98+
99+
return attachments.map(attachmentFromSql);
100+
}
101+
102+
upsertAttachment(attachment: AttachmentRecord, context: Transaction): void {
103+
context.execute(
104+
/* sql */
105+
`
106+
INSERT
107+
OR REPLACE INTO ${this.tableName} (
108+
id,
109+
filename,
110+
local_uri,
111+
size,
112+
media_type,
113+
timestamp,
114+
state,
115+
has_synced,
116+
meta_data
117+
)
118+
VALUES
119+
(?, ?, ?, ?, ?, ?, ?, ?, ?)
120+
`,
121+
[
122+
attachment.id,
123+
attachment.filename,
124+
attachment.localUri || null,
125+
attachment.size || null,
126+
attachment.mediaType || null,
127+
attachment.timestamp,
128+
attachment.state,
129+
attachment.hasSynced ? 1 : 0,
130+
attachment.metaData || null
131+
]
132+
);
133+
}
134+
135+
async deleteAttachment(attachmentId: string): Promise<void> {
136+
await this.db.writeTransaction((tx) =>
137+
tx.execute(
138+
/* sql */
139+
`
140+
DELETE FROM ${this.tableName}
141+
WHERE
142+
id = ?
143+
`,
144+
[attachmentId]
145+
)
146+
);
147+
}
148+
149+
async saveAttachments(attachments: AttachmentRecord[]): Promise<void> {
150+
if (attachments.length === 0) {
151+
return;
152+
}
153+
await this.db.writeTransaction(async (tx) => {
154+
for (const attachment of attachments) {
155+
this.upsertAttachment(attachment, tx);
156+
}
157+
});
158+
}
159+
}

0 commit comments

Comments
 (0)