48 lines
1.9 KiB
TypeScript
48 lines
1.9 KiB
TypeScript
import { BaseSchema } from '@adonisjs/lucid/schema'
|
|
|
|
/**
|
|
* Files of uploaders whose bodies are not fetched right away (ngPost, see
|
|
* CONCEPT.md D28): one row per file, from the headers alone. The row keeps
|
|
* the article range, so the file can be found again, and is the queue for
|
|
* worker:deferred, which fetches one body per file.
|
|
*/
|
|
export default class extends BaseSchema {
|
|
async up() {
|
|
this.schema.createTable('deferred_files', (table) => {
|
|
table.bigIncrements('id')
|
|
table.string('file_key', 40).notNullable().unique()
|
|
// File name from the subject (random for ngPost).
|
|
table.text('name').notNullable()
|
|
table.text('subject').notNullable()
|
|
table.text('poster').notNullable()
|
|
// Article numbers are counted in the group where the file was first seen.
|
|
table.text('group_name').notNullable()
|
|
table.bigInteger('first_article').notNullable()
|
|
table.text('first_message_id').notNullable()
|
|
table.bigInteger('last_article').notNullable()
|
|
table.integer('article_count').notNullable()
|
|
table.bigInteger('bytes').notNullable()
|
|
table.timestamp('posted_at', { useTz: true })
|
|
table.timestamp('first_seen_at', { useTz: true }).notNullable()
|
|
table.timestamp('last_seen_at', { useTz: true }).notNullable()
|
|
// pending → sampled (one body read) or expanded (sent to the body queue) or failed.
|
|
table.string('status', 16).notNullable().defaultTo('pending')
|
|
table.timestamp('processed_at', { useTz: true })
|
|
// From the sampled body.
|
|
table.text('yenc_name')
|
|
table.bigInteger('size')
|
|
table.integer('total_parts')
|
|
table.integer('sampled_part')
|
|
table.string('content_type', 16)
|
|
table.boolean('encrypted')
|
|
table.text('error')
|
|
table.index(['status', 'last_seen_at'])
|
|
table.index(['first_seen_at'])
|
|
})
|
|
}
|
|
|
|
async down() {
|
|
this.schema.dropTable('deferred_files')
|
|
}
|
|
}
|