# Storage

Outdated

Applications have the option to use one of three storage types: a performant SQLite database, a key-value storage, or a bucket.

# D1

Cloudflare D1 is an open-source set set of patches for SQLite, designed to enhance performance and scalability. Drizzle ORM is utilized to interact with the database from the perspective of code. For inspection purposes, DB Browser for SQLite can be used.

# Schema

Database schema represents the single source of truth of database composition. It is defined in TypeScript thus types could be easily inhereted. Each table has its own file stored under the src/database/schema directory.

src
 ├── database
        ├── schema
              ├── user.ts
              ├── company.ts
              ├── address.ts
              ├── event.ts

A singular naming convention is used consistently for file names, table names, and column names. Snake case is required for all database naming. If naming primary or foreign keys, always put id at the end of the name. To ensure same debugging capabilities for each table, the first three columns must be id, createdAt and modifiedAt. They can be easily spreaded through Database.base, provided by Workers SDK.

// Address table
export const address = sqliteTable('address', {
  ...Database.base,
  street: text('street').notNull(),
  streetNo: integer('street_no').notNull(),
  city: text('city').notNull(),
  exists: integer('ip_authorization', { mode: 'boolean' }).notNull(),
  destroyedAt: integer('created_at', { mode: 'timestamp_ms' }).default(sql`(unixepoch('subsec'))`),
})

// Address relations
export const addressRelations = relations(address, ({ many }) => ({
  users: many(user),
}))

// User table
export const user = sqliteTable('user', {
  ...Database.base,
  name: text('name').notNull(),
  surname: text('surname').notNull(),
  addressId: text('address_id').notNull().references(() => address.id),
})

// User relations
export const userRelations = relations(user, ({ one }) => ({
  address: one(address, { fields: [user.addressId], references: [address.id] }),
}))

# Type Infering

Each service contains @types/db.ts file which is inteded as a provider of all types representing tables. Drizzle provides InferSelectModel and InferInsertModel functions that achieve desired outcome.

// For selecting
export type ApiKeySelectType = InferSelectModel<typeof tables.address>

// For inserting
export type ApiKeySelectType = InferInsertModel<typeof tables.address>

# Migration

Defined or modifies schema must be transformed into a SQL migration file. Drizzle handles this process by executing the pnpm db:generate command. The resulting migration file is given a random name and stored in the src/database/migrations directory. Additionally, a meta directory is created, which should be committed to source control but not modified manually.

src
 ├── database
        ├── schema
        ├── migrations
                ├── 0000_nosy_marvel_apes.sql
                ├── 0001_lucky_hydra.sql
                ├── 0002_light_rachel_grey.sql
                ├── meta
                     ├── _journal.json
                     ├── 0000_snapshot.json
                     ├── 0001_snapshot.json
                     ├── 0002_snapshot.json

Migration files could be then applied on the database by executing the pnpm db:migrate command.

# Seeding

// TODO: definici seedingu si vzdy resi dana service pro svou D1, definuje se seed funkce na service, kterou ma nasledne gateway k dispozici. // TODO: Provedeni seedu pote resi gateway pro vsechny services ktere maji definovanou funkci, resime to pomoci nitro tasks, na gateway se nadefinuje jednoduchy task, ktery pres cloudflare bindings na kazde service zavola seed funkci nitro task seed // TODO: Pro seeding muzeme vyuzit drizzle-seed, ktery ma vyhodu ze vzdy vygeneruje stejna data, samozrejme zde stale zustava moznost si napsat seed vlastni.

# KV

Cloudflare KV is a low-latency key-value data storage.

# R2

Cloudflare R2 is an object storage designed store large amounts of unstructured data without the costly egress bandwidth fees.