From c68f11080f14bd9cd26bdb9286279532b797c5c4 Mon Sep 17 00:00:00 2001 From: Trivernis Date: Sun, 13 Oct 2019 18:17:47 +0200 Subject: [PATCH] Data access improvements - fixed votes - added column constraints - added post not found error to vote --- .gitignore | 1 + src/default-config.yaml | 2 +- src/graphql/resolvers.ts | 11 +- src/lib/MemoryCache.ts | 73 ---------- .../{dataaccess/index.ts => dataaccess.ts} | 10 +- src/lib/errors/graphqlErrors.ts | 7 +- src/lib/globals.ts | 5 - src/lib/{dataaccess => }/models/ChatMember.ts | 8 +- .../{dataaccess => }/models/ChatMessage.ts | 13 +- src/lib/{dataaccess => }/models/ChatRoom.ts | 0 src/lib/{dataaccess => }/models/Friendship.ts | 8 +- src/lib/{dataaccess => }/models/Post.ts | 30 ++-- src/lib/{dataaccess => }/models/PostVote.ts | 11 +- src/lib/{dataaccess => }/models/Request.ts | 12 +- src/lib/{dataaccess => }/models/User.ts | 31 +++- src/lib/{dataaccess => }/models/index.ts | 0 src/routes/home.ts | 2 +- src/sql/create-tables.sql | 137 ------------------ src/sql/update-tables.sql | 19 --- 19 files changed, 97 insertions(+), 283 deletions(-) delete mode 100644 src/lib/MemoryCache.ts rename src/lib/{dataaccess/index.ts => dataaccess.ts} (95%) rename src/lib/{dataaccess => }/models/ChatMember.ts (60%) rename src/lib/{dataaccess => }/models/ChatMessage.ts (73%) rename src/lib/{dataaccess => }/models/ChatRoom.ts (100%) rename src/lib/{dataaccess => }/models/Friendship.ts (57%) rename src/lib/{dataaccess => }/models/Post.ts (63%) rename src/lib/{dataaccess => }/models/PostVote.ts (57%) rename src/lib/{dataaccess => }/models/Request.ts (75%) rename src/lib/{dataaccess => }/models/User.ts (82%) rename src/lib/{dataaccess => }/models/index.ts (100%) delete mode 100644 src/sql/create-tables.sql delete mode 100644 src/sql/update-tables.sql diff --git a/.gitignore b/.gitignore index 92b6a08..982d25a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ dist .idea config.yaml sqz-force +greenvironment.db diff --git a/src/default-config.yaml b/src/default-config.yaml index 58a8ecc..0c24242 100644 --- a/src/default-config.yaml +++ b/src/default-config.yaml @@ -1,6 +1,6 @@ # database connection info database: - connectionUri: "sqlite://:memory:" + connectionUri: "sqlite://greenvironment.db" # http server configuration server: diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts index 8867c30..a764a9c 100644 --- a/src/graphql/resolvers.ts +++ b/src/graphql/resolvers.ts @@ -1,8 +1,8 @@ import {GraphQLError} from "graphql"; import * as status from "http-status"; import dataaccess from "../lib/dataaccess"; -import * as models from "../lib/dataaccess/models"; -import {NotLoggedInGqlError} from "../lib/errors/graphqlErrors"; +import * as models from "../lib/models"; +import {NotLoggedInGqlError, PostNotFoundGqlError} from "../lib/errors/graphqlErrors"; import globals from "../lib/globals"; import {InternalEvents} from "../lib/InternalEvents"; import {is} from "../lib/regex"; @@ -103,7 +103,12 @@ export function resolver(req: any, res: any): any { if (postId && type) { if (req.session.userId) { const post = await models.Post.findByPk(postId); - return await post.vote(req.session.userId, type); + if (post) { + return await post.vote(req.session.userId, type); + } else { + res.status(400); + return new PostNotFoundGqlError(postId); + } } else { res.status(status.UNAUTHORIZED); return new NotLoggedInGqlError(); diff --git a/src/lib/MemoryCache.ts b/src/lib/MemoryCache.ts deleted file mode 100644 index 1e76834..0000000 --- a/src/lib/MemoryCache.ts +++ /dev/null @@ -1,73 +0,0 @@ -import * as crypto from "crypto"; -import {EventEmitter} from "events"; - -export class MemoryCache extends EventEmitter { - private cacheItems: any = {}; - private cacheExpires: any = {}; - private expireCheck: NodeJS.Timeout; - - /** - * Creates interval function. - * @param ttl - */ - constructor(private ttl: number = 500) { - super(); - this.expireCheck = setInterval(() => this.checkExpires(), ttl / 2); - } - - /** - * Creates a md5 hash of the given key. - * @param key - */ - public hashKey(key: string): string { - const hash = crypto.createHash("sha1"); - const data = hash.update(key, "utf8"); - return data.digest("hex"); - } - - /** - * Sets an entry. - * @param key - * @param value - */ - public set(key: string, value: any) { - this.cacheItems[key] = value; - this.cacheExpires[key] = Date.now() + this.ttl; - this.emit("set", key, value); - } - - /** - * Returns the entry stored with the given key. - * @param key - */ - public get(key: string) { - if (this.cacheItems.hasOwnProperty(key)) { - this.emit("hit", key, this.cacheItems[key]); - return this.cacheItems[key]; - } else { - this.emit("miss", key); - } - } - - /** - * Deletes a cache item. - * @param key - */ - public delete(key: string) { - this.emit("delete", key); - delete this.cacheItems[key]; - } - - /** - * Checks expires and clears items that are over the expire value. - */ - private checkExpires() { - for (const [key, value] of Object.entries(this.cacheExpires)) { - if (value < Date.now()) { - this.emit("delete", key); - delete this.cacheItems[key]; - delete this.cacheExpires[key]; - } - } - } -} diff --git a/src/lib/dataaccess/index.ts b/src/lib/dataaccess.ts similarity index 95% rename from src/lib/dataaccess/index.ts rename to src/lib/dataaccess.ts index e5f04cc..e13faca 100644 --- a/src/lib/dataaccess/index.ts +++ b/src/lib/dataaccess.ts @@ -1,9 +1,9 @@ import {Sequelize} from "sequelize-typescript"; -import {ChatNotFoundError} from "../errors/ChatNotFoundError"; -import {EmailAlreadyRegisteredError} from "../errors/EmailAlreadyRegisteredError"; -import {UserNotFoundError} from "../errors/UserNotFoundError"; -import globals from "../globals"; -import {InternalEvents} from "../InternalEvents"; +import {ChatNotFoundError} from "./errors/ChatNotFoundError"; +import {EmailAlreadyRegisteredError} from "./errors/EmailAlreadyRegisteredError"; +import {UserNotFoundError} from "./errors/UserNotFoundError"; +import globals from "./globals"; +import {InternalEvents} from "./InternalEvents"; import * as models from "./models"; /** diff --git a/src/lib/errors/graphqlErrors.ts b/src/lib/errors/graphqlErrors.ts index 9e0b1b5..b33a883 100644 --- a/src/lib/errors/graphqlErrors.ts +++ b/src/lib/errors/graphqlErrors.ts @@ -1,8 +1,13 @@ import {GraphQLError} from "graphql"; export class NotLoggedInGqlError extends GraphQLError { - constructor() { super("Not logged in"); } } + +export class PostNotFoundGqlError extends GraphQLError { + constructor(postId: number) { + super(`Post '${postId}' not found!`); + } +} diff --git a/src/lib/globals.ts b/src/lib/globals.ts index 0a6669a..6fe2899 100644 --- a/src/lib/globals.ts +++ b/src/lib/globals.ts @@ -9,7 +9,6 @@ import {EventEmitter} from "events"; import * as fsx from "fs-extra"; import * as yaml from "js-yaml"; import * as winston from "winston"; -import {MemoryCache} from "./MemoryCache"; const configPath = "config.yaml"; const defaultConfig = __dirname + "/../default-config.yaml"; @@ -28,7 +27,6 @@ if (!(fsx.pathExistsSync(configPath))) { */ namespace globals { export const config = yaml.safeLoad(fsx.readFileSync("config.yaml", "utf-8")); - export const cache = new MemoryCache(1200); export const logger = winston.createLogger({ transports: [ new winston.transports.Console({ @@ -44,9 +42,6 @@ namespace globals { ], }); export const internalEmitter = new EventEmitter(); - cache.on("set", (key) => logger.debug(`Caching '${key}'.`)); - cache.on("miss", (key) => logger.debug(`Cache miss for '${key}'`)); - cache.on("hit", (key) => logger.debug(`Cache hit for '${key}'`)); } export default globals; diff --git a/src/lib/dataaccess/models/ChatMember.ts b/src/lib/models/ChatMember.ts similarity index 60% rename from src/lib/dataaccess/models/ChatMember.ts rename to src/lib/models/ChatMember.ts index dacd80a..f2b7aad 100644 --- a/src/lib/dataaccess/models/ChatMember.ts +++ b/src/lib/models/ChatMember.ts @@ -1,14 +1,16 @@ -import {Column, ForeignKey, Model, Table,} from "sequelize-typescript"; +import {Column, ForeignKey, Model, NotNull, Table,} from "sequelize-typescript"; import {ChatRoom} from "./ChatRoom"; import {User} from "./User"; @Table({underscored: true}) export class ChatMember extends Model { @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public userId: number; @ForeignKey(() => ChatRoom) - @Column + @NotNull + @Column({allowNull: false}) public chatId: number; } diff --git a/src/lib/dataaccess/models/ChatMessage.ts b/src/lib/models/ChatMessage.ts similarity index 73% rename from src/lib/dataaccess/models/ChatMessage.ts rename to src/lib/models/ChatMessage.ts index 9811579..3b7c357 100644 --- a/src/lib/dataaccess/models/ChatMessage.ts +++ b/src/lib/models/ChatMessage.ts @@ -1,21 +1,24 @@ import * as sqz from "sequelize"; -import {BelongsTo, Column, CreatedAt, ForeignKey, Model, Table,} from "sequelize-typescript"; -import markdown from "../../markdown"; +import {BelongsTo, Column, CreatedAt, ForeignKey, Model, NotNull, Table,} from "sequelize-typescript"; +import markdown from "../markdown"; import {ChatRoom} from "./ChatRoom"; import {User} from "./User"; @Table({underscored: true}) export class ChatMessage extends Model { - @Column(sqz.STRING(512)) + @NotNull + @Column({type: sqz.STRING(512), allowNull: false}) public content: string; @ForeignKey(() => ChatRoom) - @Column + @NotNull + @Column({allowNull: false}) public chatId: number; @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public authorId: number; @BelongsTo(() => ChatRoom, "chatId") diff --git a/src/lib/dataaccess/models/ChatRoom.ts b/src/lib/models/ChatRoom.ts similarity index 100% rename from src/lib/dataaccess/models/ChatRoom.ts rename to src/lib/models/ChatRoom.ts diff --git a/src/lib/dataaccess/models/Friendship.ts b/src/lib/models/Friendship.ts similarity index 57% rename from src/lib/dataaccess/models/Friendship.ts rename to src/lib/models/Friendship.ts index d383e7f..4d7773b 100644 --- a/src/lib/dataaccess/models/Friendship.ts +++ b/src/lib/models/Friendship.ts @@ -1,14 +1,16 @@ -import {Column, ForeignKey, Model, Table} from "sequelize-typescript"; +import {Column, ForeignKey, Model, NotNull, Table} from "sequelize-typescript"; import {User} from "./User"; @Table({underscored: true}) export class Friendship extends Model { @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public userId: number; @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public friendId: number; } diff --git a/src/lib/dataaccess/models/Post.ts b/src/lib/models/Post.ts similarity index 63% rename from src/lib/dataaccess/models/Post.ts rename to src/lib/models/Post.ts index b027822..93151a3 100644 --- a/src/lib/dataaccess/models/Post.ts +++ b/src/lib/models/Post.ts @@ -1,16 +1,18 @@ import * as sqz from "sequelize"; -import {BelongsTo, BelongsToMany, Column, CreatedAt, ForeignKey, Model, Table,} from "sequelize-typescript"; -import markdown from "../../markdown"; +import {BelongsTo, BelongsToMany, Column, CreatedAt, ForeignKey, Model, NotNull, Table,} from "sequelize-typescript"; +import markdown from "../markdown"; import {PostVote, VoteType} from "./PostVote"; import {User} from "./User"; @Table({underscored: true}) export class Post extends Model { - @Column(sqz.STRING(2048)) + @NotNull + @Column({type: sqz.STRING(2048), allowNull: false}) public content: string; @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public authorId: number; @BelongsTo(() => User, "authorId") @@ -44,21 +46,25 @@ export class Post extends Model { public async vote(userId: number, type: VoteType): Promise { type = type || VoteType.UPVOTE; - let vote = await PostVote.findOne({where: {user_id: userId, post_id: this.id}}); + let votes = await this.$get("rVotes", {where: {id: userId}}) as Array; + let vote = votes[0] || null; + let created = false; if (!vote) { - await this.$add("rVotes", userId); - vote = await PostVote.findOne({where: {user_id: userId, post_id: this.id}}); + await this.$add("rVote", userId); + votes = await this.$get("rVotes", {where: {id: userId}}) as Array; + vote = votes[0] || null; + created = true; } if (vote) { - if (vote.voteType === type) { - await vote.destroy(); + if (vote.PostVote.voteType === type && !created) { + await vote.PostVote.destroy(); return null; } else { - vote.voteType = type; - await vote.save(); + vote.PostVote.voteType = type; + await vote.PostVote.save(); } } - return vote.voteType; + return vote.PostVote.voteType; } } diff --git a/src/lib/dataaccess/models/PostVote.ts b/src/lib/models/PostVote.ts similarity index 57% rename from src/lib/dataaccess/models/PostVote.ts rename to src/lib/models/PostVote.ts index 058176d..50517f2 100644 --- a/src/lib/dataaccess/models/PostVote.ts +++ b/src/lib/models/PostVote.ts @@ -1,5 +1,5 @@ import * as sqz from "sequelize"; -import {Column, ForeignKey, Model, Table,} from "sequelize-typescript"; +import {Column, ForeignKey, Model, NotNull, Table,} from "sequelize-typescript"; import {Post} from "./Post"; import {User} from "./User"; @@ -10,14 +10,17 @@ export enum VoteType { @Table({underscored: true}) export class PostVote extends Model { - @Column({type: sqz.ENUM, values: ["UPVOTE", "DOWNVOTE"]}) + @NotNull + @Column({type: sqz.ENUM, values: ["UPVOTE", "DOWNVOTE"], defaultValue: "UPVOTE", allowNull: false}) public voteType: VoteType; @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public userId: number; @ForeignKey(() => Post) - @Column + @NotNull + @Column({allowNull: false}) public postId: number; } diff --git a/src/lib/dataaccess/models/Request.ts b/src/lib/models/Request.ts similarity index 75% rename from src/lib/dataaccess/models/Request.ts rename to src/lib/models/Request.ts index fffa09f..87f6f85 100644 --- a/src/lib/dataaccess/models/Request.ts +++ b/src/lib/models/Request.ts @@ -1,5 +1,5 @@ import * as sqz from "sequelize"; -import {BelongsTo, Column, ForeignKey, Model, Table,} from "sequelize-typescript"; +import {BelongsTo, Column, ForeignKey, Model, NotNull, Table,} from "sequelize-typescript"; import {User} from "./User"; export enum RequestType { @@ -10,18 +10,22 @@ export enum RequestType { @Table({underscored: true}) export class Request extends Model { - @Column({type: sqz.ENUM, values: ["FRIENDREQUEST", "GROUPINVITE", "EVENTINVITE"]}) + @NotNull + @Column({type: sqz.ENUM, values: ["FRIENDREQUEST", "GROUPINVITE", "EVENTINVITE"], + defaultValue: "FRIENDREQUEST", allowNull: false}) public requestType: RequestType; @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public senderId: number; @BelongsTo(() => User, "senderId") public rSender: User; @ForeignKey(() => User) - @Column + @NotNull + @Column({allowNull: false}) public receiverId: number; @BelongsTo(() => User, "receiverId") diff --git a/src/lib/dataaccess/models/User.ts b/src/lib/models/User.ts similarity index 82% rename from src/lib/dataaccess/models/User.ts rename to src/lib/models/User.ts index 1219173..1c4d567 100644 --- a/src/lib/dataaccess/models/User.ts +++ b/src/lib/models/User.ts @@ -1,6 +1,16 @@ import * as sqz from "sequelize"; -import {BelongsToMany, Column, CreatedAt, HasMany, Model, Table, UpdatedAt,} from "sequelize-typescript"; -import {RequestNotFoundError} from "../../errors/RequestNotFoundError"; +import { + BelongsToMany, + Column, + CreatedAt, + HasMany, + Model, + NotNull, + Table, + Unique, + UpdatedAt, +} from "sequelize-typescript"; +import {RequestNotFoundError} from "../errors/RequestNotFoundError"; import {ChatMember} from "./ChatMember"; import {ChatMessage} from "./ChatMessage"; import {ChatRoom} from "./ChatRoom"; @@ -11,19 +21,26 @@ import {Request, RequestType} from "./Request"; @Table({underscored: true}) export class User extends Model { - @Column(sqz.STRING(128)) + @NotNull + @Column({type: sqz.STRING(128), allowNull: false}) public username: string; - @Column(sqz.STRING(128)) + @NotNull + @Unique + @Column({type: sqz.STRING(128), allowNull: false, unique: true}) public handle: string; - @Column(sqz.STRING(128)) + @Unique + @NotNull + @Column({type: sqz.STRING(128), allowNull: false, unique: true}) public email: string; - @Column(sqz.STRING(128)) + @NotNull + @Column({type: sqz.STRING(128), allowNull: false}) public password: string; - @Column({defaultValue: 0}) + @NotNull + @Column({defaultValue: 0, allowNull: false}) public rankpoints: number; @BelongsToMany(() => User, () => Friendship) diff --git a/src/lib/dataaccess/models/index.ts b/src/lib/models/index.ts similarity index 100% rename from src/lib/dataaccess/models/index.ts rename to src/lib/models/index.ts diff --git a/src/routes/home.ts b/src/routes/home.ts index 128088c..102b88f 100644 --- a/src/routes/home.ts +++ b/src/routes/home.ts @@ -1,7 +1,7 @@ import {Router} from "express"; import {Namespace, Server} from "socket.io"; import dataaccess from "../lib/dataaccess"; -import {ChatMessage, ChatRoom, Post, Request, User} from "../lib/dataaccess/models"; +import {ChatMessage, ChatRoom, Post, Request, User} from "../lib/models"; import globals from "../lib/globals"; import {InternalEvents} from "../lib/InternalEvents"; import Route from "../lib/Route"; diff --git a/src/sql/create-tables.sql b/src/sql/create-tables.sql deleted file mode 100644 index 70e49e2..0000000 --- a/src/sql/create-tables.sql +++ /dev/null @@ -1,137 +0,0 @@ ---create functions -DO $$BEGIN - - IF NOT EXISTS(SELECT 1 from pg_proc WHERE proname = 'function_exists') THEN - CREATE FUNCTION function_exists(text) RETURNS boolean LANGUAGE plpgsql AS $BODY$ - BEGIN - RETURN EXISTS(SELECT 1 from pg_proc WHERE proname = $1); - END $BODY$; - END IF; - - IF NOT function_exists('type_exists') THEN - CREATE FUNCTION type_exists(text) RETURNS boolean LANGUAGE plpgsql AS $BODY$ - BEGIN - RETURN EXISTS (SELECT 1 FROM pg_type WHERE typname = $1); - END $BODY$; - END IF; - -END$$; - ---create types -DO $$ BEGIN - - IF NOT type_exists('votetype') THEN - CREATE TYPE votetype AS enum ('DOWNVOTE', 'UPVOTE'); - END IF; - - IF NOT type_exists('posttype') THEN - CREATE TYPE posttype AS enum ('MISC', 'ACTION', 'IMAGE', 'TEXT'); - END IF; - - IF NOT type_exists('requesttype') THEN - CREATE TYPE requesttype AS enum ('FRIENDREQUEST'); - END IF; - -END$$; - --- create functions relying on types - -DO $$ BEGIN - - IF NOT function_exists('cast_to_votetype') THEN - CREATE FUNCTION cast_to_votetype(text) RETURNS votetype LANGUAGE plpgsql AS $BODY$ - BEGIN - RETURN CASE WHEN $1::votetype IS NULL THEN 'UPVOTE' ELSE $1::votetype END; - END $BODY$; - END IF; - - IF NOT function_exists('cast_to_posttype') THEN - CREATE FUNCTION cast_to_posttype(text) RETURNS posttype LANGUAGE plpgsql AS $BODY$ - BEGIN - RETURN CASE WHEN $1::posttype IS NULL THEN 'MISC' ELSE $1::posttype END; - END $BODY$; - END IF; - -END$$; - --- create tables -DO $$ BEGIN - - CREATE TABLE IF NOT EXISTS "user_sessions" ( - "sid" varchar NOT NULL, - "sess" json NOT NULL, - "expire" timestamp(6) NOT NULL, - PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE - ) WITH (OIDS=FALSE); - - CREATE TABLE IF NOT EXISTS users ( - id SERIAL PRIMARY KEY, - name varchar(128) NOT NULL, - handle varchar(128) UNIQUE NOT NULL, - password varchar(1024) NOT NULL, - email varchar(128) UNIQUE NOT NULL, - greenpoints INTEGER DEFAULT 0, - joined_at TIMESTAMP DEFAULT now() - ); - - CREATE TABLE IF NOT EXISTS posts ( - id BIGSERIAL PRIMARY KEY, - upvotes INTEGER DEFAULT 0, - downvotes INTEGER DEFAULT 0, - created_at TIMESTAMP DEFAULT now(), - content text, - author SERIAL REFERENCES users (id) ON DELETE CASCADE, - type posttype NOT NULL DEFAULT 'MISC' - ); - - CREATE TABLE IF NOT EXISTS votes ( - user_id SERIAL REFERENCES users (id) ON DELETE CASCADE, - item_id BIGSERIAL REFERENCES posts (id) ON DELETE CASCADE, - vote_type votetype DEFAULT 'DOWNVOTE', - PRIMARY KEY (user_id, item_id) - ); - - CREATE TABLE IF NOT EXISTS events ( - id BIGSERIAL PRIMARY KEY, - time TIMESTAMP, - owner SERIAL REFERENCES users (id) - ); - - CREATE TABLE IF NOT EXISTS event_members ( - event BIGSERIAL REFERENCES events (id), - member SERIAL REFERENCES users (id), - PRIMARY KEY (event, member) - ); - - CREATE TABLE IF NOT EXISTS chats ( - id BIGSERIAL PRIMARY KEY - ); - - CREATE TABLE IF NOT EXISTS chat_messages ( - chat BIGSERIAL REFERENCES chats (id) ON DELETE CASCADE, - author SERIAL REFERENCES users (id) ON DELETE SET NULL, - content VARCHAR(1024) NOT NULL, - created_at TIMESTAMP DEFAULT now(), - PRIMARY KEY (chat, author, created_at) - ); - - CREATE TABLE IF NOT EXISTS chat_members ( - chat BIGSERIAL REFERENCES chats (id) ON DELETE CASCADE, - member SERIAL REFERENCES users (id) ON DELETE CASCADE, - PRIMARY KEY (chat, member) - ); - - CREATE TABLE IF NOT EXISTS user_friends ( - user_id SERIAL REFERENCES users (id) ON DELETE CASCADE, - friend_id SERIAL REFERENCES users (id) ON DELETE CASCADE, - PRIMARY KEY (user_id, friend_id) - ); - - CREATE TABLE IF NOT EXISTS requests ( - sender SERIAL REFERENCES users (id) ON DELETE CASCADE, - receiver SERIAL REFERENCES users (id) ON DELETE CASCADE, - type requesttype DEFAULT 'FRIENDREQUEST', - PRIMARY KEY (sender, receiver, type) - ); - -END $$; diff --git a/src/sql/update-tables.sql b/src/sql/update-tables.sql deleted file mode 100644 index 858a214..0000000 --- a/src/sql/update-tables.sql +++ /dev/null @@ -1,19 +0,0 @@ -DO $$ BEGIN - - ALTER TABLE IF EXISTS votes - ADD COLUMN IF NOT EXISTS vote_type votetype DEFAULT 'UPVOTE', - ALTER COLUMN vote_type TYPE votetype USING cast_to_votetype(vote_type::text), - ALTER COLUMN vote_type DROP DEFAULT, - ALTER COLUMN vote_type SET DEFAULT 'UPVOTE'; - - ALTER TABLE IF EXISTS posts - ALTER COLUMN type TYPE posttype USING cast_to_posttype(type::text), - ALTER COLUMN type DROP DEFAULT, - ALTER COLUMN type SET DEFAULT 'MISC', - DROP COLUMN IF EXISTS upvotes, - DROP COLUMN IF EXISTS downvotes; - - ALTER TABLE requests - ADD COLUMN IF NOT EXISTS type requesttype DEFAULT 'FRIENDREQUEST'; - -END $$;