Added basic post creation.

This commit is contained in:
2023-06-06 01:30:46 +02:00
parent de757efc6e
commit 9a9b92a6b1
21 changed files with 556 additions and 23 deletions

View File

@@ -1,4 +1,16 @@
exports.up = async function(knex) {
import fs from 'fs';
export async function up(knex) {
const nanoidFn = await fs.promises.readFile('./migrations/nanoid.sql', 'utf8'); // from https://github.com/viascom/nanoid-postgres
await knex.raw(nanoidFn);
await knex.raw(`
CREATE FUNCTION shack_id(length smallint DEFAULT 8) RETURNS TEXT AS $$
SELECT nanoid(length, '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
$$ LANGUAGE SQL STABLE;
`);
await knex.schema.createTable('users', (table) => {
table.increments('id');
@@ -63,7 +75,9 @@ exports.up = async function(knex) {
});
await knex.schema.createTable('posts', (table) => {
table.increments('id');
table.text('id', 8)
.primary()
.defaultTo(knex.raw('shack_id()'));
table.text('title')
.notNullable();
@@ -86,12 +100,39 @@ exports.up = async function(knex) {
.defaultTo(knex.fn.now());
});
await knex.raw(`ALTER TABLE posts ADD CONSTRAINT post_content CHECK (body IS NOT NULL OR url IS NOT NULL)`);
};
await knex.raw('ALTER TABLE posts ADD CONSTRAINT post_content CHECK (body IS NOT NULL OR url IS NOT NULL)');
exports.down = async function(knex) {
await knex.schema.createTable('comments', (table) => {
table.text('id', 8)
.primary()
.defaultTo(knex.raw('shack_id()'));
table.text('post_id', 8)
.notNullable()
.references('id')
.inTable('posts');
table.integer('user_id')
.notNullable()
.references('id')
.inTable('users');
table.text('body');
table.datetime('created_at')
.notNullable()
.defaultTo(knex.fn.now());
});
}
export async function down(knex) {
await knex.schema.dropTable('comments');
await knex.schema.dropTable('posts');
await knex.schema.dropTable('shelves_settings');
await knex.schema.dropTable('shelves');
await knex.schema.dropTable('users');
};
await knex.raw(`
DROP FUNCTION IF EXISTS shack_id;
`);
}

66
migrations/nanoid.sql Normal file
View File

@@ -0,0 +1,66 @@
/*
* Copyright 2023 Viascom Ltd liab. Co
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE OR REPLACE FUNCTION nanoid(
size int DEFAULT 21,
alphabet text DEFAULT '_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
)
RETURNS text
LANGUAGE plpgsql
volatile
AS
$$
DECLARE
idBuilder text := '';
counter int := 0;
bytes bytea;
alphabetIndex int;
alphabetArray text[];
alphabetLength int;
mask int;
step int;
BEGIN
alphabetArray := regexp_split_to_array(alphabet, '');
alphabetLength := array_length(alphabetArray, 1);
mask := (2 << cast(floor(log(alphabetLength - 1) / log(2)) as int)) - 1;
step := cast(ceil(1.6 * mask * size / alphabetLength) AS int);
while true
loop
bytes := gen_random_bytes(step);
while counter < step
loop
alphabetIndex := (get_byte(bytes, counter) & mask) + 1;
if alphabetIndex <= alphabetLength then
idBuilder := idBuilder || alphabetArray[alphabetIndex];
if length(idBuilder) = size then
return idBuilder;
end if;
end if;
counter := counter + 1;
end loop;
counter := 0;
end loop;
END
$$;