Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 198x 1x 197x 10x 197x 197x 197x 197x 197x 197x 197x | /**
* Validates that a table name is safe to interpolate into SQL.
*
* Allowed characters:
* - A–Z
* - a–z
* - 0–9
* - _ (underscore)
*
* Disallowed:
* - spaces
* - punctuation or symbols (.-;:!?@#$% etc.)
* - quotes (" ' `)
* - SQL injection attempts
* - Unicode characters (emoji, CJK, etc.)
*
* This ensures the table name can be safely used as a SQL identifier
* without quoting or escaping.
*/
export function sanitizeTableName(name: string): string {
if (!/^[A-Za-z0-9_]+$/.test(name)) {
throw new Error(
`Invalid table name "${name}". ` +
`Allowed characters: A-Z, a-z, 0-9, and _. ` +
`No spaces, punctuation, unicode, or special symbols are permitted.`
);
}
return name;
}
export const D1_SQL = {
get: (table: string) => /* sql */ `
SELECT value
FROM ${table}
WHERE key = ?
AND (expiration IS NULL OR expiration > unixepoch())
`,
getWithMetadata: (table: string) => /* sql */ `
SELECT value, metadata
FROM ${table}
WHERE key = ?
AND (expiration IS NULL OR expiration > unixepoch())
`,
list: (table: string) => /* sql */ `
SELECT key, expiration, metadata
FROM ${table}
WHERE (expiration IS NULL OR expiration > unixepoch())
AND key >= ?
AND key < ?
AND key > ?
ORDER BY key COLLATE BINARY
LIMIT ?
`,
put: (table: string) => /* sql */ `
INSERT INTO ${table} (key, value, expiration, metadata)
VALUES (?, ?, ?, ?)
ON CONFLICT(key) DO UPDATE SET
value = excluded.value,
expiration = excluded.expiration,
metadata = excluded.metadata
`,
delete: (table: string) => /* sql */ `
DELETE FROM ${table}
WHERE key = ?
`,
deleteExpired: (table: string) => /* sql */ `
DELETE FROM ${table}
WHERE expiration IS NOT NULL
AND expiration <= unixepoch()
`,
ensureTable: (table: string) => /* sql */ `
CREATE TABLE IF NOT EXISTS ${table} (
key TEXT NOT NULL COLLATE BINARY PRIMARY KEY,
value BLOB NOT NULL,
expiration INTEGER,
metadata BLOB
) WITHOUT ROWID;
CREATE INDEX IF NOT EXISTS ${table}_exp_idx
ON ${table}(expiration)
WHERE expiration IS NOT NULL;
`,
} as const;
|