Changing to postgresql..

Changed some schema. This database sorta loads, will refactor the .sql to have some basic info for testing logins and such.
master
Hailey Clark 3 years ago
parent 575553e831
commit d59cdc89d1
  1. 170
      appdb.py
  2. 127
      postgres-db-schema.sql

@ -1,9 +1,10 @@
#!/usr/bin/env python3
# appdb.py
# We connect to our database and any database calls are put here.
# This is moving awaay from mysql to poostgresql ! cuz I like it better.
import pymysql
import pymysql.cursors
import psycopg2
#import psycopg2.cursors
import pprint
import uuid
# import time
@ -21,24 +22,27 @@ app_debug = config.get("app", "debug")
def logsms_db(msg_id, msg_ts, direction, to_did, from_did, cost, status, msg,
account_id):
'''This statement logs a SMS to the smslog table.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("INSERT INTO messages (`timestamp`, `provider_timestamp`, `direction`, `source_number`, `dest_number`, `cost`, `pid`, `status`, `body`, `account_id`) VALUES (now(), %s, %s, %s, %s, %s, %s, %s, %s, %s)",
cur.execute("INSERT INTO messages (`timestamp`, `provider_timestamp`, `direction`, `source_number`, `dest_numbpsycopg2er`, `cost`, `pid`, `status`, `body`, `account_id`) VALUES (now(), %s, %s, %s, %s, %s, %s, %s, %s, %s)",
(msg_ts, direction, from_did, to_did, cost, msg_id, status, msg, account_id))
db.commit()
cur.close()
db.close()
return True
def getUserInfobyID(id):
'''This pulls * from 'account' and returns it if it matches an email.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT * FROM account WHERE id=%s LIMIT 1", (id))
data = cur.fetchone()
cur.close()
db.close()
if app_debug == '1':
pprint.pprint("email data:")
@ -49,11 +53,12 @@ def getUserInfobyID(id):
def isUserinDB(id):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT * FROM account WHERE id=%s LIMIT 1" % id)
data = cur.fetchone()
cur.close()
db.close()
if data:
pprint.pprint(data)
@ -63,11 +68,12 @@ def isUserinDB(id):
def isUserExist(email):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT email FROM account WHERE email=%s", (email))
data = cur.fetchone()
cur.close()
db.close()
if data:
return True
@ -75,25 +81,27 @@ def isUserExist(email):
def generate_id(email):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
newID = uuid.uuid4().hex
cur.execute("UPDATE account SET loginid=%s WHERE email=%s LIMIT 1",
(newID, email))
db.commit()
cur.close()
db.close()
return newID
def verify_id(email, uniqueid):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute(
"SELECT email FROM account WHERE email=%s AND loginid=%s LIMIT 1",
(email, uniqueid))
data = cur.fetchone()
cur.close()
db.close()
if data:
return True
@ -101,13 +109,14 @@ def verify_id(email, uniqueid):
def verify_login(email, password):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute(
"SELECT email FROM account WHERE email=%s AND passwd=%s LIMIT 1",
(email, password))
data = cur.fetchone()
cur.close()
db.close()
if data:
return data
@ -115,11 +124,12 @@ def verify_login(email, password):
def getUserInfo(email, uniqueid):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT * FROM account WHERE email=%s AND loginid=%s LIMIT 1",(email, uniqueid))
data = cur.fetchone()
cur.close()
db.close()
if app_debug == '1':
pprint.pprint("email data:")
@ -131,11 +141,12 @@ def getUserInfo(email, uniqueid):
def isUserVerfied(google_id):
'''This checks to see if the account is set to verified true'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT verified_email FROM account WHERE google_id=%s",(google_id))
data = cur.fetchone()
cur.close()
db.close()
if data:
return True
@ -144,37 +155,40 @@ def isUserVerfied(google_id):
def registerUser(email, password):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
# cur.execute("INSERT INTO account (`name`, `email`, `refresh_token`, `user_id`, `verified_email`, `created`, `last_modified`) VALUES \
# (%s, %s, %s, %s, %s, NOW(), NOW())",(name, email, refresh_token, user_id, verified))
db.commit()
cur.close()
db.close()
return "Success!"
def setNewUser(user_id, refresh_token, name, email, verified):
'''This statement is for creating a user into the account table.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("INSERT INTO account (`name`, `email`, `refresh_token`, `user_id`, `verified_email`, `created`, `last_modified`) VALUES \
(%s, %s, %s, %s, %s, NOW(), NOW())",(name, email, refresh_token, user_id, verified))
db.commit()
cur.close()
db.close()
return True
def finalizeNewUser(email, username, passwd):
def finalizeNewUser(email, username, password):
'''Finalizes a user creation after calling setNewUser(), this requires a
password already converted to a safe hash of the password. Don't store
plaintext passwords in this please'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
rows = cur.execute("UPDATE account SET username=%s, passwd=%s, verified_email=%s, last_modified=NOW() WHERE email=%s LIMIT 1",(username, passwd,2, email))
rows = cur.execute("UPDATE account SET username=%s, password=%s, verified_email=%s, last_modified=NOW() WHERE email=%s LIMIT 1",(username, password,2, email))
db.commit()
cur.close()
db.close()
if rows == 1:
return True
@ -184,11 +198,12 @@ def finalizeNewUser(email, username, passwd):
def getInfobyEmail(email):
'''This pulls * from 'account' and returns it if it matches an email.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT * FROM account WHERE email=%s LIMIT 1", (email))
data = cur.fetchone()
cur.close()
db.close()
if app_debug == '1':
pprint.pprint("email data:")
@ -200,11 +215,12 @@ def getInfobyEmail(email):
def getUserIdFromRT(refreshtoken):
'''This pulls an UserID from a Refresh Token'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT id FROM account WHERE loginid=%s", (refreshtoken))
data = cur.fetchone()
cur.close()
db.close()
if not data:
return False
@ -213,11 +229,12 @@ def getUserIdFromRT(refreshtoken):
def getAccountbyDID(did):
'''This function pulls the account id for the DID in the query.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT account_id FROM dids WHERE number=%s LIMIT 1", (did))
data = cur.fetchone()
cur.close()
db.close()
if not data:
return False
@ -226,21 +243,23 @@ def getAccountbyDID(did):
def getDIDsbyAccount(account_id):
'''DIDs that are assigned to an account.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT number,provider FROM dids WHERE account_id=%s", (account_id))
rows = cur.fetchall()
cur.close()
db.close()
return rows
def authIdforDID(account_id, did):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT account.id FROM dids,account WHERE dids.account_id=account.id AND account.id=%s AND dids.number=%s LIMIT 1", (account_id,did))
data = cur.fetchone()
cur.close()
db.close()
pprint.pprint("Printing AUTH ID")
if data:
@ -250,23 +269,25 @@ def authIdforDID(account_id, did):
def setRefreshToken(refresh_token, google_id):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
pprint.pprint("Setting new refresh token of " + google_id + " and " + refresh_token)
cur.execute("UPDATE account SET refresh_token=%s WHERE google_id=%s",
(refresh_token, google_id))
db.commit()
cur.close()
db.close()
return True
def getAccountId(uniqueID):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT id FROM account WHERE loginid=%s LIMIT 1", uniqueID)
rows = cur.fetchall()
cur.close()
db.close()
if rows:
return rows
@ -275,8 +296,8 @@ def getAccountId(uniqueID):
def getSubToken(account_id):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT subscription_token FROM account WHERE id =%s", (account_id))
data = cur.fetchone()
@ -288,68 +309,74 @@ def getSubToken(account_id):
def getAllSMSLog(limit=5, order='desc'):
'''This gets the last X amount of logs from all numbers.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT * FROM messages ORDER BY timestamp DESC LIMIT %s",
(limit))
rows = cur.fetchall()
cur.close()
db.close()
return rows
def getSMSbyAccount(login_id, limit=5):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT messages.* FROM messages, account WHERE messages.account_id=account.id AND account.loginid=%s ORDER BY id DESC LIMIT %s",(login_id, limit))
rows = cur.fetchall()
cur.close()
db.close()
return rows
def getNumSMSLog(did, limit=5):
'''This gets the last X amount of logs from all numbers.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT * FROM messages WHERE source_number=%s OR dest_number=%s ORDER BY timestamp DESC LIMIT %s",(did,did,limit))
rows = cur.fetchall()
# for row in rows:
# pprint.pprint(row)
cur.close()
db.close()
return rows
def updateReadStatus(msg_id, isread):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
affected_count = cur.execute("UPDATE messages SET is_read=%s WHERE id=%s",
(isread, msg_id))
db.commit()
cur.close()
db.close()
return affected_count
def updateMarkAllRead(account_id):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
affected_count = cur.execute("UPDATE messages SET is_read=1 WHERE account_id=%s",
(account_id))
db.commit()
cur.close()
db.close()
return affected_count
def updateMarkAllUnread(account_id):
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
affected_count = cur.execute("UPDATE messages SET is_read=0 WHERE account_id=%s",
(account_id))
db.commit()
cur.close()
db.close()
return affected_count
@ -357,12 +384,13 @@ def updateMarkAllUnread(account_id):
def updateMsgStatus(msg_id, status, msg_timestamp):
'''Update the delivered field in the database based on delivery reports.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
affected_count = cur.execute("UPDATE `messages` SET status=%s, `provider_timestamp`=%s WHERE `pid`=%s",
(status, msg_timestamp, msg_id))
db.commit()
cur.close()
db.close()
return affected_count
@ -370,11 +398,12 @@ def updateMsgStatus(msg_id, status, msg_timestamp):
def updateMsgTimestamp(msg_id, timestamp):
'''This changes the timestamp of the msg_id to the timestamp provided by
the provider.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
affected_count = cur.execute("UPDATE `messages` SET `provider_timestamp`=%s WHERE `pid`=%s",(timestamp,msg_id))
db.commit()
cur.close()
db.close()
return affected_count
@ -382,15 +411,16 @@ def updateMsgTimestamp(msg_id, timestamp):
def updateSubscriptionToken(account_id, token):
'''We need to store the token (I think) so that it can be used to send
messages to single endpoints rather than everyone. '''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
affected_count = cur.execute("UPDATE `account` SET `subscription_token`=%s WHERE `account_id`=%s",(account_id, token))
db.commit()
cur.close()
db.close()
if not data:
if not affected_count:
return False
return affected_count
@ -398,23 +428,25 @@ def updatePass(account_id, origpass, newpass):
'''updatePass(origpass, newpass) this assumes newpass has been verified
twice and origpass equals the current password. Returns the amount of rows
updated which should always be 1 or 0.'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
# pprint.pprint("Updating the following %s with old pass %s",(account_id, origpass))
affected_count = cur.execute("UPDATE account SET passwd=%s WHERE id=%s AND passwd=%s LIMIT 1",(newpass,account_id,origpass))
affected_count = cur.execute("UPDATE account SET password=%s WHERE id=%s AND passwd=%s LIMIT 1",(newpass,account_id,origpass))
db.commit()
cur.close()
db.close()
return affected_count
def validateFrom(did):
'''Looks up in the DB to see if a DID is a valid DID'''
db = pymysql.connect(host=sqlhost, port=sqlport,
user=sqluser, passwd=sqlpass, db=sqldb)
db = psycopg2.connect(host=sqlhost, port=sqlport,
user=sqluser, password=sqlpass, database=sqldb)
cur = db.cursor()
cur.execute("SELECT number FROM dids WHERE number=%s LIMIT 1" % did)
data = cur.fetchone()
cur.close()
db.close()
if data is not None and int(data[0]) == int(did):
return True

@ -0,0 +1,127 @@
# Database layout
Here is some code.
-- Database: smsproject
-- DROP DATABASE IF EXISTS smsproject;
CREATE DATABASE smsproject
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'C'
LC_CTYPE = 'C'
TABLESPACE = pg_default
CONNECTION LIMIT = -1;
CREATE TABLE account (
id serial NOT NULL PRIMARY KEY,
name VARCHAR(50) NOT NULL DEFAULT '0',
email VARCHAR(75) NOT NULL DEFAULT '0'
);
-- CREATE UNIQUE INDEX FK_destination_account ON account (account_id);
CREATE TYPE v_status AS ENUM ('Y','N','P');
CREATE TYPE call_direction AS ENUM('inbound','outbound');
CREATE TYPE phone_num_type AS ENUM('mobile','home', 'office', 'other');
CREATE TABLE destination (
id serial NOT NULL PRIMARY KEY,
dest_did VARCHAR(11) NOT NULL DEFAULT '0',
verify_status v_status NOT NULL DEFAULT 'N',
idpin INT NULL DEFAULT '0',
account_id INT NOT NULL DEFAULT '0',
CONSTRAINT FK_destination_account FOREIGN KEY (account_id) REFERENCES account (id)
);
CREATE TABLE dids (
id serial PRIMARY KEY,
number TEXT NOT NULL,
provider VARCHAR(18) NULL DEFAULT '0',
account_id INT NULL DEFAULT NULL,
CONSTRAINT FK_dids_account FOREIGN KEY (account_id) REFERENCES account (id)
);
INSERT INTO dids (number,provider,account_id) VALUES ('17605551212','Flowroute',1);
CREATE TABLE messages (
id serial NOT NULL PRIMARY KEY,
account_id INT NULL DEFAULT NULL,
timestamp TIMESTAMP NOT NULL,
pid VARCHAR(64) NULL DEFAULT NULL,
provider_timestamp VARCHAR(36) NULL DEFAULT NULL,
direction call_direction DEFAULT 'inbound',
source_number VARCHAR(11) NOT NULL,
dest_number VARCHAR(11) NOT NULL,
cost VARCHAR(10) NOT NULL DEFAULT '0.00',
body TEXT NOT NULL,
status VARCHAR(30) NOT NULL DEFAULT 'pending',
CONSTRAINT FK_messages_account FOREIGN KEY (account_id) REFERENCES account (id)
);
##########Update V2
# Adding token and other infos.
ALTER TABLE account ADD COLUMN refresh_token bytea NULL;
ALTER TABLE account ADD COLUMN google_id VARCHAR(255) NULL UNIQUE;
ALTER TABLE account ADD COLUMN verified_email BOOL NOT NULL DEFAULT False;
##########Update V3
# Adding last modified and created, as well as changing the timestamp
# This requires loss of all logs. Oops.
ALTER TABLE account ADD COLUMN created TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
CREATE OR REPLACE FUNCTION update_last_modified_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.last_modified = now();
RETURN NEW;
END;
$$ language 'plpgsql';
ALTER TABLE account ADD COLUMN last_modified TIMESTAMP;
CREATE TRIGGER update_last_modtime BEFORE UPDATE ON account FOR EACH ROW EXECUTE PROCEDURE update_last_modified_column();
##########Update V4
# Add an entirely new table contactlist
CREATE TABLE contacts (
id serial NOT NULL PRIMARY KEY,
account_id INT NULL DEFAULT NULL,
last_modified TIMESTAMP,
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
archived BOOL NOT NULL DEFAULT '0',
fullname VARCHAR(122) NOT NULL,
email VARCHAR(200) NULL
);
CREATE TRIGGER update_last_modtime BEFORE UPDATE ON contacts FOR EACH ROW EXECUTE PROCEDURE update_last_modified_column();
CREATE TABLE phonebase (
id serial NOT NULL PRIMARY KEY,
contact_id INT NULL DEFAULT NULL,
phone_number VARCHAR(15) NOT NULL,
number_type phone_num_type NULL DEFAULT 'mobile',
archived BOOL NOT NULL DEFAULT '0',
CONSTRAINT pb_accountassoc FOREIGN KEY (contact_id) REFERENCES account (id)
);
########### Update V5
# Adding password and username support.
ALTER TABLE account ADD COLUMN username VARCHAR(255) NULL UNIQUE;
ALTER TABLE account ADD COLUMN passwd VARCHAR(255) NULL;
########## UPDATE V6
ALTER TABLE account DROP COLUMN google_id;
ALTER TABLE account DROP COLUMN username;
ALTER TABLE account DROP COLUMN refresh_token;
ALTER TABLE account ADD COLUMN loginid VARCHAR(255) NULL UNIQUE;
ALTER TABLE account ADD COLUMN picture_url VARCHAR(255) NULL;
ALTER TABLE messages ADD COLUMN is_read BOOL NOT NULL DEFAULT '0';
ALTER TABLE account ADD COLUMN subscription_token VARCHAR(50) NULL DEFAULT NULL;
Loading…
Cancel
Save