fuck lining, from sqlite to mysql

This commit is contained in:
ridethepig 2022-12-11 21:43:19 +08:00
parent 018499d722
commit 9f93aa854b
17 changed files with 462 additions and 338 deletions

View File

@ -3,4 +3,7 @@ cd src
python -m venv venv python -m venv venv
pip install flask pip install flask
flask --app main run flask --app main run
``` ```
使用之前需要新整一个mysql服务器然后在里面建立一个数据库bigwork并保证该数据库被授权给了指定的用户。
在config里面修改对应的用户、密码、服务器地址

View File

@ -1,111 +1,134 @@
drop database if exists bigwork; use bigwork;
create database bigwork; drop table if exists `admin`;
drop table if exists user_stat;
drop table if exists book_type;
drop table if exists book_author;
drop table if exists author;
drop table if exists typetable;
drop table if exists record;
drop table if exists note;
drop table if exists document;
drop table if exists book;
drop table if exists user;
create table `admin` create table `admin`
( (
passwd varchar(100) NOT NULL passwd varchar(200) NOT NULL
); );
insert into `admin` (`passwd`) values(''); -- insert into `admin` (`passwd`) values('');
create table user create table user
( (
user_id int PRIMARY KEY AUTO_INCREMENT, user_id int PRIMARY KEY AUTO_INCREMENT,
user_name varchar(100) NOT NULL, user_name varchar(100) NOT NULL UNIQUE,
user_mail varchar(100) NOT NULL, user_mail varchar(100) NOT NULL UNIQUE,
user_passwd varchar(100) NOT NULL, user_passwd varchar(200) NOT NULL,
user_limit int NOT NULL, user_limit int NOT NULL,
user_regtime datetime NOT NULL user_regtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table book create table book
( (
book_id int PRIMARY KEY AUTO_INCREMENT, book_id int PRIMARY KEY AUTO_INCREMENT,
book_name varchar(100) NOT NULL, book_name varchar(100) NOT NULL,
book_isbn varchar(100) DEFAULT NULL, book_isbn varchar(100) DEFAULT NULL,
book_publisher varchar(100) DEFAULT NULL, book_publisher varchar(100) DEFAULT NULL,
book_pubdate datetime DEFAULT NULL, book_pubdate datetime DEFAULT NULL,
book_lang varchar(100) DEFAULT NULL, book_lang varchar(100) DEFAULT NULL,
user_id int NOT NULL, book_author varchar(100) DEFAULT NULL,
CONSTRAINT `fk_book_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) user_id int NOT NULL,
CONSTRAINT `fk_book_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table document create table document
( (
doc_id int PRIMARY KEY AUTO_INCREMENT, doc_id int PRIMARY KEY AUTO_INCREMENT,
doc_name varchar(100) NOT NULL, doc_name varchar(100) NOT NULL,
doc_url varchar(100) NOT NULL, doc_url varchar(100) NOT NULL,
doc_size int NOT NULL, doc_size int NOT NULL,
doc_date datetime NOT NULL, doc_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
doc_type varchar(100) NOT NULL, doc_type varchar(100) NOT NULL,
book_id int NOT NULL, book_id int NOT NULL,
user_id int NOT NULL, user_id int NOT NULL,
CONSTRAINT `fk_document_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`), CONSTRAINT `fk_document_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE,
CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`), CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE CASCADE
INDEX (doc_name(10)),
INDEX (doc_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create index `idx_doc_name` on document(doc_name);
create table note create table note
( (
note_id int PRIMARY KEY AUTO_INCREMENT, note_id int PRIMARY KEY AUTO_INCREMENT,
note_name varchar(100) NOT NULL, note_name varchar(100) NOT NULL,
note_date datetime NOT NULL, note_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
note_content mediumtext NOT NULL DEFAULT '', note_content text NOT NULL,
book_id int NOT NULL, book_id int NOT NULL,
user_id int NOT NULL, user_id int NOT NULL,
CONSTRAINT `fk_note_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`), CONSTRAINT `fk_note_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE,
CONSTRAINT `fk_note_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`), CONSTRAINT `fk_note_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE CASCADE
INDEX (note_name(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create index `idx_note_name` on note(note_name);
create table record create table record
( (
record_time timestamp PRIMARY KEY, record_time timestamp PRIMARY KEY DEFAULT CURRENT_TIMESTAMP,
record_type varchar(10) NOT NULL, record_type varchar(10) NOT NULL,
doc_URL varchar(100) NOT NULL, doc_URL varchar(100) NOT NULL,
user_id int NOT NULL, user_id int NOT NULL
INDEX (record_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table typetable create table typetable
( (
type_id int PRIMARY KEY AUTO_INCREMENT, type_id int PRIMARY KEY AUTO_INCREMENT,
type_name varchar(20) NOT NULL, type_name varchar(20) NOT NULL UNIQUE
UNIQUE (type_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table author create table author
( (
author_id int PRIMARY KEY AUTO_INCREMENT, author_id int PRIMARY KEY AUTO_INCREMENT,
author_name varchar(50) NOT NULL, author_name varchar(50) NOT NULL
INDEX (author_name(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create index `idx_author_name` on author(author_name);
create table book_author create table book_author
( (
author_id int NOT NULL, author_id int NOT NULL,
book_id int NOT NULL, book_id int NOT NULL,
PRIMARY KEY (`author_id`, `book_id`), PRIMARY KEY (`author_id`, `book_id`),
CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`), CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE RESTRICT,
CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`) CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table book_type create table book_type
( (
type_id int NOT NULL, type_id int NOT NULL,
book_id int NOT NULL, book_id int NOT NULL,
PRIMARY KEY (`type_id`, `book_id`), PRIMARY KEY (`type_id`, `book_id`),
CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`), CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE CASCADE,
CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`) CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table user_stat create table user_stat
( (
user_id int PRIMARY KEY, user_id int PRIMARY KEY,
user_usedspace int NOT NULL DEFAULT 0, user_limit int NOT NULL,
user_bookcount int NOT NULL DEFAULT 0, user_usedspace int NOT NULL DEFAULT 0,
user_doccount int NOT NULL DEFAULT 0, user_bookcount int NOT NULL DEFAULT 0,
user_typecount int NOT NULL DEFAULT 0, user_doccount int NOT NULL DEFAULT 0,
CONSTRAINT `fk_user_stat_user` FOREIGN KEY REFERENCES user(`user_id`) user_notecount int NOT NULL DEFAULT 0,
CONSTRAINT `fk_user_stat_user` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`) ON DELETE CASCADE,
CONSTRAINT `ck_usedspace` CHECK (user_usedspace <= user_limit)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
drop view if exists `v_book_to_types`;
create view `v_book_to_types` as
select book_id, typetable.type_id as type_id, type_name from book_type natural join typetable;
drop view if exists `v_type_to_book`;
create view `v_type_to_book` as
select book_id,
book_name,
book_isbn,
book_publisher,
book_lang,
book_author,
user_id,
type_id,
type_name
from book natural join book_type natural join typetable;

View File

@ -1,3 +1,22 @@
use bigwork;
DELIMITER ##
drop trigger if exists `trig_create_user_stat`;
create trigger `trig_create_user_stat`
after insert on user
for each row begin
insert into user_stat (`user_id`, `user_limit`) values(NEW.user_id, NEW.user_limit);
end ##
DELIMITER ;
DELIMITER ##
drop trigger if exists `trig_delete_user_stat`;
create trigger `trig_delete_user_stat`
after delete on user
for each row begin
delete from user_stat where user_id=OLD.user_id;
end ##
DELIMITER ;
drop trigger if exists `trig_update_stat_book_ins`; drop trigger if exists `trig_update_stat_book_ins`;
DELIMITER ## DELIMITER ##
create trigger `trig_update_stat_book_ins` create trigger `trig_update_stat_book_ins`
@ -36,20 +55,20 @@ create trigger `trig_update_stat_doc_del`
end ## end ##
DELIMITER ; DELIMITER ;
drop trigger if exists `trig_update_stat_type_ins`; drop trigger if exists `trig_update_stat_note_ins`;
DELIMITER ## DELIMITER ##
create trigger `trig_update_stat_type_ins` create trigger `trig_update_stat_note_ins`
after insert on typetable after insert on note
for each row begin for each row begin
update user_stat set user_typecount=user_typecount+1 where user_stat.user_id=NEW.user_id; update user_stat set user_notecount=user_notecount+1 where user_stat.user_id=NEW.user_id;
end ## end ##
DELIMITER ; DELIMITER ;
drop trigger if exists `trig_update_stat_type_del`; drop trigger if exists `trig_update_stat_note_del`;
DELIMITER ## DELIMITER ##
create trigger `trig_update_stat_type_del` create trigger `trig_update_stat_note_del`
after delete on typetable after delete on note
for each row begin for each row begin
update user_stat set user_typecount=user_typecount-1 where user_stat.user_id=OLD.user_id; update user_stat set user_notecount=user_notecount-1 where user_stat.user_id=OLD.user_id;
end ## end ##
DELIMITER ; DELIMITER ;

View File

@ -8,7 +8,11 @@ def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True) app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping( app.config.from_mapping(
SECRET_KEY='dev', SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'dbproj.db'), # DATABASE=os.path.join(app.instance_path, 'dbproj.db'),
DATABASE='bigwork',
DATABASE_USER='root',
DATABASE_HOST='localhost',
DATABASE_PASS='lil0,.lil0',
) )
if test_config is None: if test_config is None:

View File

@ -7,7 +7,7 @@ from werkzeug.security import generate_password_hash
from src.auth import admin_login_required from src.auth import admin_login_required
from src.db import get_db from src.db import get_db
import sqlite3 import pymysql
bp = Blueprint('admin', __name__, url_prefix='/admin') bp = Blueprint('admin', __name__, url_prefix='/admin')
@ -20,10 +20,12 @@ def validateEmail(email):
@bp.route('/') @bp.route('/')
@admin_login_required @admin_login_required
def index(): def index():
db = get_db() cur = get_db().cursor()
users = db.execute( cur.execute(
'select * from user' 'select * from user'
).fetchall() )
users = cur.fetchall()
cur.close()
return render_template("admin/index.html", users=users) return render_template("admin/index.html", users=users)
@bp.route('/adduser', methods=("GET", "POST")) @bp.route('/adduser', methods=("GET", "POST"))
@ -39,22 +41,27 @@ def adduser():
error = '用户空间必须是整数GB' error = '用户空间必须是整数GB'
elif not validateEmail(usermail): elif not validateEmail(usermail):
error = 'email格式不合法' error = 'email格式不合法'
userlimi = int(userlimi) userlimi = float(userlimi)
userlimi *= 1024 * 1024 # userlimit is stored and measured by KB userlimi *= 1024 * 1024 # userlimit is stored and measured by KB
userlimi = int(userlimi)
if error is None: if error is None:
db = get_db() db = get_db()
cur = db.cursor()
try: try:
db.execute( cur.execute(
'insert into user(`user_name`, `user_mail`, `user_passwd`, `user_limit`) values (?,?,?,?)', 'insert into user(`user_name`, `user_mail`, `user_passwd`, `user_limit`) values (%s,%s,%s,%s)',
(username, usermail, generate_password_hash(password), userlimi,) (username, usermail, generate_password_hash(password), userlimi,)
) )
db.commit() db.commit()
except sqlite3.IntegrityError as _e:
except pymysql.IntegrityError as _e:
error = "用户名或邮箱已经存在 %s" % (_e) error = "用户名或邮箱已经存在 %s" % (_e)
db.rollback() db.rollback()
except sqlite3.Error as _e: except pymysql.Error as _e:
error = "未知错误 %s" % (_e) error = "未知错误 %s" % (_e)
db.rollback() db.rollback()
finally:
cur.close()
if error is None: if error is None:
return redirect(url_for('admin.index')) return redirect(url_for('admin.index'))
flash(error) flash(error)
@ -69,18 +76,21 @@ def removeuser():
uid_to_del = request.args.get("uid") uid_to_del = request.args.get("uid")
if uid_to_del is not None and uid_to_del.isdecimal: if uid_to_del is not None and uid_to_del.isdecimal:
db = get_db() db = get_db()
cur = db.cursor()
rowcnt = 0 rowcnt = 0
try: try:
rowcnt = db.execute( rowcnt = cur.execute(
"delete from user where user.user_id=?", (uid_to_del, ) "delete from user where user.user_id=%s", (uid_to_del, )
).rowcount )
db.commit() db.commit()
except sqlite3.IntegrityError as _e: except pymysql.IntegrityError as _e:
error = "用户未做好被删除的准备:%s" % (_e) error = "用户未做好被删除的准备:%s" % (_e)
db.rollback() db.rollback()
except sqlite3.Error as _e: except pymysql.Error as _e:
error = "删除发生未知错误: %s" %(_e) error = "删除发生未知错误: %s" %(_e)
db.rollback() db.rollback()
finally:
cur.close()
if error is None: if error is None:
if rowcnt != 0: if rowcnt != 0:
error = "删除uid为%s的用户成功!" % uid_to_del error = "删除uid为%s的用户成功!" % uid_to_del

View File

@ -11,20 +11,22 @@ def loginuser():
username = request.form['username'] username = request.form['username']
password = request.form['password'] password = request.form['password']
db = get_db() db = get_db()
cur = db.cursor()
error = None error = None
user = db.execute( cur.execute(
'SELECT * FROM user WHERE user_name = ?', (username,) 'SELECT * FROM user WHERE user_name = %s', (username,)
).fetchone() )
user = cur.fetchone()
cur.close()
if user is None: if user is None:
error = '用户名不存在' error = '用户名不存在'
elif not check_password_hash(user['user_passwd'], password): elif not check_password_hash(user['user_passwd'], password):
error = '密码错误' error = '密码错误'
if error is None: if error is None and user is not None:
session.clear() session.clear()
session['user_id'] = user['user_id'] session['user_id'] = user['user_id']
return redirect(url_for('home')) return redirect(url_for('user.home'))
flash(error) flash(error)
@ -35,8 +37,10 @@ def loginadmin():
if request.method == 'POST': if request.method == 'POST':
password = request.form['password'] password = request.form['password']
db = get_db() db = get_db()
cur = db.cursor()
error = None error = None
admin = db.execute('SELECT * FROM admin limit 1').fetchone() cur.execute('SELECT * FROM admin limit 1')
admin = cur.fetchone()
if admin is None: if admin is None:
error = '用户名不存在' error = '用户名不存在'
@ -64,9 +68,9 @@ def load_logged_in_user():
g.user = {'user_id':0, 'user_name': 'admin'} g.user = {'user_id':0, 'user_name': 'admin'}
# use id=0 to refer to admin # use id=0 to refer to admin
else: else:
g.user = get_db().execute( cur = get_db().cursor()
'SELECT * FROM user WHERE user_id = ?', (user_id,) cur.execute('SELECT * FROM user WHERE user_id = %s', (user_id,))
).fetchone() g.user = cur.fetchone()
@bp.route('/logout') @bp.route('/logout')
def logout(): def logout():
@ -91,7 +95,7 @@ def admin_login_required(view):
if g.user is None: if g.user is None:
return redirect(url_for('auth.login')) return redirect(url_for('auth.login'))
elif g.user['user_id'] != 0: elif g.user['user_id'] != 0:
return redirect(url_for('home')) return redirect(url_for('user.home'))
return view(**kwargs) return view(**kwargs)
return wrapped_view return wrapped_view

View File

@ -1,16 +1,22 @@
import sqlite3 # import sqlite3
import pymysql
import click import click
from flask import current_app, g from flask import current_app, g
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
def get_db(): def get_db():
if 'db' not in g: if 'db' not in g:
g.db = sqlite3.connect( # g.db = sqlite3.connect(
current_app.config['DATABASE'], # current_app.config['DATABASE'],
detect_types=sqlite3.PARSE_DECLTYPES # detect_types=sqlite3.PARSE_DECLTYPES
) # )
g.db.row_factory = sqlite3.Row # g.db.row_factory = sqlite3.Row
g.db = pymysql.connect(
host=current_app.config['DATABASE_HOST'],
user=current_app.config['DATABASE_USER'],
password=current_app.config['DATABASE_PASS'],
database=current_app.config['DATABASE'], cursorclass=pymysql.cursors.DictCursor)
return g.db return g.db
@ -23,14 +29,16 @@ def close_db(e=None):
@click.command('init-db') @click.command('init-db')
def init_db(): def init_db():
db = get_db() db = get_db()
click.echo("Initializing database schema...") click.echo("PyMySQL do not support script execution...")
with current_app.open_resource('sql/db_create_sqlite.sql') as f: # click.echo("Initializing database schema...")
db.executescript(f.read().decode('utf8')) # with current_app.open_resource('sql/db_create_sqlite.sql') as f:
click.echo("Initializing database triggers...") # db.executescript(f.read().decode('utf8'))
with current_app.open_resource('sql/trigger_sqlite.sql') as f: # click.echo("Initializing database triggers...")
db.executescript(f.read().decode('utf8')) # with current_app.open_resource('sql/trigger_sqlite.sql') as f:
# db.executescript(f.read().decode('utf8'))
click.echo("Initializing admin passwd...") click.echo("Initializing admin passwd...")
db.execute("insert into admin (passwd) values (?)", (generate_password_hash("lolicon"),)) print(len(generate_password_hash("lolicon")))
db.cursor().execute("insert into admin (passwd) values (%s)", (generate_password_hash("lolicon")))
db.commit() db.commit()
click.echo("Initialized database.") click.echo("Initialized database.")

View File

@ -1,111 +0,0 @@
drop database if exists bigwork;
create database bigwork;
create table `admin`
(
passwd varchar(100) NOT NULL
);
insert into `admin` (`passwd`) values('');
create table user
(
user_id int PRIMARY KEY AUTO_INCREMENT,
user_name varchar(100) NOT NULL,
user_mail varchar(100) NOT NULL,
user_passwd varchar(100) NOT NULL,
user_limit int NOT NULL,
user_regtime datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table book
(
book_id int PRIMARY KEY AUTO_INCREMENT,
book_name varchar(100) NOT NULL,
book_isbn varchar(100) DEFAULT NULL,
book_publisher varchar(100) DEFAULT NULL,
book_pubdate datetime DEFAULT NULL,
book_lang varchar(100) DEFAULT NULL,
user_id int NOT NULL,
CONSTRAINT `fk_book_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table document
(
doc_id int PRIMARY KEY AUTO_INCREMENT,
doc_name varchar(100) NOT NULL,
doc_url varchar(100) NOT NULL,
doc_size int NOT NULL,
doc_date datetime NOT NULL,
doc_type varchar(100) NOT NULL,
book_id int NOT NULL,
user_id int NOT NULL,
CONSTRAINT `fk_document_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`),
CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
INDEX (doc_name(10)),
INDEX (doc_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table note
(
note_id int PRIMARY KEY AUTO_INCREMENT,
note_name varchar(100) NOT NULL,
note_date datetime NOT NULL,
note_content mediumtext NOT NULL DEFAULT '',
book_id int NOT NULL,
user_id int NOT NULL,
CONSTRAINT `fk_note_user_id` FOREIGN KEY (`user_id`) REFERENCES user(`user_id`),
CONSTRAINT `fk_note_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
INDEX (note_name(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table record
(
record_time timestamp PRIMARY KEY,
record_type varchar(10) NOT NULL,
doc_URL varchar(100) NOT NULL,
user_id int NOT NULL,
INDEX (record_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table typetable
(
type_id int PRIMARY KEY AUTO_INCREMENT,
type_name varchar(20) NOT NULL,
UNIQUE (type_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table author
(
author_id int PRIMARY KEY AUTO_INCREMENT,
author_name varchar(50) NOT NULL,
INDEX (author_name(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table book_author
(
author_id int NOT NULL,
book_id int NOT NULL,
PRIMARY KEY (`author_id`, `book_id`),
CONSTRAINT `fk_ba_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
CONSTRAINT `fk_ba_author_id` FOREIGN KEY (`author_id`) REFERENCES author(`author_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table book_type
(
type_id int NOT NULL,
book_id int NOT NULL,
PRIMARY KEY (`type_id`, `book_id`),
CONSTRAINT `fk_bt_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`),
CONSTRAINT `fk_bt_type_id` FOREIGN KEY (`type_id`) REFERENCES typetable(`type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
create table user_stat
(
user_id int PRIMARY KEY,
user_usedspace int NOT NULL DEFAULT 0,
user_bookcount int NOT NULL DEFAULT 0,
user_doccount int NOT NULL DEFAULT 0,
user_typecount int NOT NULL DEFAULT 0,
CONSTRAINT `fk_user_stat_user` FOREIGN KEY REFERENCES user(`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

View File

@ -1,55 +0,0 @@
drop trigger if exists `trig_update_stat_book_ins`;
DELIMITER ##
create trigger `trig_update_stat_book_ins`
after insert on book
for each row begin
update user_stat set user_bookcount=user_bookcount+1 where user_stat.user_id=NEW.user_id;
end ##
DELIMITER ;
drop trigger if exists `trig_update_stat_book_del`;
DELIMITER ##
create trigger `trig_update_stat_book_del`
after delete on book
for each row begin
update user_stat set user_bookcount=user_bookcount-1 where user_stat.user_id=OLD.user_id;
end ##
DELIMITER ;
drop trigger if exists `trig_update_stat_doc_ins`;
DELIMITER ##
create trigger `trig_update_stat_doc_ins`
after insert on document
for each row begin
update user_stat set user_doccount=user_doccount+1 where user_stat.user_id=NEW.user_id;
update user_stat set user_usedspace=user_usedspace+NEW.doc_size where user_stat.user_id=NEW.user_id;
end ##
DELIMITER ;
drop trigger if exists `trig_update_stat_doc_del`;
DELIMITER ##
create trigger `trig_update_stat_doc_del`
after delete on document
for each row begin
update user_stat set user_doccount=user_doccount-1 where user_stat.user_id=OLD.user_id;
update user_stat set user_usedspace=user_usedspace-OLD.doc_size where user_stat.user_id=OLD.user_id;
end ##
DELIMITER ;
drop trigger if exists `trig_update_stat_type_ins`;
DELIMITER ##
create trigger `trig_update_stat_type_ins`
after insert on typetable
for each row begin
update user_stat set user_typecount=user_typecount+1 where user_stat.user_id=NEW.user_id;
end ##
DELIMITER ;
drop trigger if exists `trig_update_stat_type_del`;
DELIMITER ##
create trigger `trig_update_stat_type_del`
after delete on typetable
for each row begin
update user_stat set user_typecount=user_typecount-1 where user_stat.user_id=OLD.user_id;
end ##
DELIMITER ;

View File

@ -9,7 +9,7 @@
z-index: 1; z-index: 1;
top: 20; top: 20;
left: 0; left: 0;
overflow-x: hidden;
padding-left: 1.2rem; padding-left: 1.2rem;
padding-right: 2rem; padding-right: 2rem;
} }
@ -17,7 +17,7 @@
height: 100%; height: 100%;
max-width: 160px; max-width: 160px;
z-index: 1; z-index: 1;
overflow-x: hidden;
} }
</style> </style>
<script> <script>
@ -42,7 +42,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container maindiv"> <div class="container">
<div class="columns"> <div class="columns">
<div class="column col-3"> <div class="column col-3">
<ul class="nav"> <ul class="nav">

View File

@ -9,7 +9,7 @@
z-index: 1; z-index: 1;
top: 20; top: 20;
left: 0; left: 0;
overflow-x: hidden;
padding-left: 1.2rem; padding-left: 1.2rem;
padding-right: 2rem; padding-right: 2rem;
} }
@ -17,13 +17,13 @@
height: 100%; height: 100%;
max-width: 160px; max-width: 160px;
z-index: 1; z-index: 1;
overflow-x: hidden;
} }
</style> </style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container maindiv"> <div class="container">
<div class="columns"> <div class="columns">
<div class="column col-3"> <div class="column col-3">
<ul class="nav"> <ul class="nav">

View File

@ -9,7 +9,6 @@
z-index: 1; z-index: 1;
top: 20; top: 20;
left: 0; left: 0;
overflow-x: hidden;
padding-left: 1.2rem; padding-left: 1.2rem;
padding-right: 2rem; padding-right: 2rem;
} }
@ -17,13 +16,12 @@
height: 100%; height: 100%;
max-width: 160px; max-width: 160px;
z-index: 1; z-index: 1;
overflow-x: hidden;
} }
</style> </style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container maindiv"> <div class="container">
<div class="columns"> <div class="columns">
<div class="column col-3"> <div class="column col-3">
<ul class="nav"> <ul class="nav">
@ -43,12 +41,57 @@
</div> </div>
<div class="column col-9 panel"> <div class="column col-9 panel">
<div class="panel-header"> <div class="panel-header">
<div class="panel-title h4">{{book['book_name']}}</div> <div class="panel-title h3">{{book['book_name']}}</div>
</div> {%if booktype|length > 0 %}
<div class="panel-body"> <div>
<mark>分类标签:</mark>
{% for atype in booktype %} {% for atype in booktype %}
<span class="chip"> {{atype['type_name']}}</span> <span class="chip"> {{atype['type_name']}}</span>
{% endfor %} {% endfor %}
</div>
{%endif%}
{%if book['book_author']%}
<div class="py-1">
<mark>作者:</mark><span class="px-2">{{book['book_author']}}</span>
</div>
{% endif %}
{%if book['book_publisher']%}
<div class="py-1">
<mark>出版社:</mark><span class="px-2">{{book['book_publisher']}}</span>
</div>
{% endif %}
{%if book['book_isbn']%}
<div class="py-1">
<mark>ISBN</mark><span class="px-2">{{book['book_isbn']}}</span>
</div>
{% endif %}
{%if book['book_lang']%}
<div class="py-1">
<mark>语言:</mark><span class="px-2">{{book['book_lang']}}</span>
</div>
{% endif %}
<div>
<a href="/book/update/{{book['book_id']}}/" class="btn btn-primary">编辑图书信息</a>
</div>
</div>
<div class="panel-body">
<div id="book-docs" class="card">
<div class="card-header">
<div class="card-title h5">文档1</div>
<div class="card-subtitle">
<span>大小:</span>
<span>日期:</span>
<div class="float-right">
<button class="btn btn-primary">下载</button>
<button class="btn">删除</button>
</div>
</div>
</div>
</div>
<div class="divider"></div>
<div id = "book-notes" class="card">
</div>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
Rendered @ {{cur_time}} Rendered @ {{cur_time}}

View File

@ -9,7 +9,7 @@
z-index: 1; z-index: 1;
top: 20; top: 20;
left: 0; left: 0;
overflow-x: hidden;
padding-left: 1.2rem; padding-left: 1.2rem;
padding-right: 2rem; padding-right: 2rem;
} }
@ -17,13 +17,13 @@
height: 100%; height: 100%;
max-width: 160px; max-width: 160px;
z-index: 1; z-index: 1;
overflow-x: hidden;
} }
</style> </style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container maindiv"> <div class="container">
<div class="columns"> <div class="columns">
<div class="column col-3"> <div class="column col-3">
<ul class="nav"> <ul class="nav">

View File

@ -9,7 +9,6 @@
z-index: 1; z-index: 1;
top: 20; top: 20;
left: 0; left: 0;
overflow-x: hidden;
padding-left: 1.2rem; padding-left: 1.2rem;
padding-right: 2rem; padding-right: 2rem;
} }
@ -17,13 +16,12 @@
height: 100%; height: 100%;
max-width: 160px; max-width: 160px;
z-index: 1; z-index: 1;
overflow-x: hidden;
} }
</style> </style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container maindiv"> <div class="container">
<div class="columns"> <div class="columns">
<div class="column col-3"> <div class="column col-3">
<ul class="nav"> <ul class="nav">

View File

@ -9,7 +9,6 @@
z-index: 1; z-index: 1;
top: 20; top: 20;
left: 0; left: 0;
overflow-x: hidden;
padding-left: 1.2rem; padding-left: 1.2rem;
padding-right: 2rem; padding-right: 2rem;
} }
@ -17,13 +16,12 @@
height: 100%; height: 100%;
max-width: 160px; max-width: 160px;
z-index: 1; z-index: 1;
overflow-x: hidden;
} }
</style> </style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="container maindiv"> <div class="container">
<div class="columns"> <div class="columns">
<div class="column col-3"> <div class="column col-3">
<ul class="nav"> <ul class="nav">

View File

@ -0,0 +1,85 @@
{% extends 'base.html' %}
{% block header %}
<script>
var typelist = {};
function switch_type(typename) {
if (typelist.hasOwnProperty(typename)) {
delete typelist[typename];
} else {
typelist[typename] = 1;
}
let typeinput = document.getElementById("booktype");
let typestr = "";
for (let typekey in typelist) {
typestr += typekey + ";";
}
typeinput.value = typestr;
}
function create_type_button(typename) {
}
</script>
{% endblock %}
{% block content %}
<div class="container">
<div class="columns">
<div class="column col-3">
<ul class="nav">
<li class="nav-item">
<a href="/home">主页</a>
</li>
<li class="nav-item">
<a href="/search">搜索</a>
</li>
<li class="nav-item">
<a href="/addbook">增加</a>
</li>
<li class="nav-item">
<a href="/tags">分类</a>
</li>
</ul>
</div>
<div class="column col-9 panel">
<div class="panel-header">
<h2>编辑图书</h2>
</div>
<div class="panel-body">
{%if error%}
<div class="toast">
{{error}}
</div>
{% endif %}
<form method="post" class="form-group">
<label class="form-label" for="bookname">书名</label>
<input class="form-input" name="bookname" id="bookname" value="{{book['book_name']}}" required>
<label class="form-label" for="bookisbn">ISBN</label>
<input class="form-input" name="bookisbn" id="bookisbn" value="{{book['book_isbn']}}">
<label class="form-label" for="bookpublisher">出版社</label>
<input class="form-input" name="bookpublisher" id="bookpublisher" value="{{book['book_publisher']}}">
<label class="form-label" for="bookauthor">作者</label>
<input class="form-input" name="bookauthor" id="bookauthor" value="{{book['book_author']}}">
<label class="form-label" for="booklang">语言</label>
<select class="form-select" name="booklang" id="booklang">
<option selected>CN</option>
<option>EN</option>
<option>Other</option>
</select>
<label class="form-label" for="booktype">分类</label>
<input class="form-input" name="booktype" id="booktype" value="{{booktype}}">
<div>
{% for atype in typelist%}
<span class="chip btn" onclick="switch_type('{{atype['type_name']}}')">{{atype['type_name']}}</span>
{% endfor %}
</div>
<input class="btn btn-primary input-group-btn p-centered" type="submit" value="提交">
</form>
</div>
<div class="panel-footer">
Rendered @ {{cur_time}}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -7,7 +7,7 @@ from werkzeug.security import generate_password_hash
from src.auth import login_required from src.auth import login_required
from src.db import get_db from src.db import get_db
import sqlite3 import pymysql
import datetime import datetime
bp = Blueprint('user', __name__) bp = Blueprint('user', __name__)
@ -15,16 +15,20 @@ bp = Blueprint('user', __name__)
@bp.route("/home") @bp.route("/home")
@login_required @login_required
def home(): def home():
db = get_db() cur = get_db().cursor()
user_stat = db.execute( cur.execute(
"select * from user_stat where user_id = ?", (g.user['user_id'],) "select * from user_stat where user_id = %s", (g.user['user_id'],)
).fetchone() )
user_stat = cur.fetchone()
print(user_stat)
cur.close()
return render_template("user/home.html", user_stat=user_stat, cur_time=datetime.datetime.now()) return render_template("user/home.html", user_stat=user_stat, cur_time=datetime.datetime.now())
@bp.route("/addbook", methods=('GET', 'POST')) @bp.route("/addbook", methods=('GET', 'POST'))
@login_required @login_required
def addbook(): def addbook():
db = get_db() db = get_db()
cur = db.cursor()
error = None error = None
if request.method == 'POST': if request.method == 'POST':
bookname = request.form['bookname'] bookname = request.form['bookname']
@ -46,40 +50,43 @@ def addbook():
booklang = None booklang = None
if len(booktype) == 0: if len(booktype) == 0:
booktype = None booktype = None
db.execute( cur.execute(
"insert into book (`book_name`, `book_isbn`" "insert into book (`book_name`, `book_isbn`"
", `book_publisher`, `book_lang`, `book_author`, `user_id`) " ", `book_publisher`, `book_lang`, `book_author`, `user_id`) "
"values (?,?,?,?,?,?)", "values (%s,%s,%s,%s,%s,%s)",
(bookname, bookisbn, bookpublisher, booklang, bookauthor, g.user['user_id'],)) (bookname, bookisbn, bookpublisher, booklang, bookauthor, g.user['user_id'],))
db.commit() db.commit()
bookid = db.execute("select max(book_id) from book").fetchone() cur.execute("select max(book_id) from book")
bookid = cur.fetchone()
bookid = bookid['max(book_id)'] bookid = bookid['max(book_id)']
error = None error = None
if booktype is not None: if booktype is not None:
booktype = booktype.strip()
if booktype[-1] != ';':
booktype += ';'
booktypes = booktype.split(";") booktypes = booktype.split(";")
booktypes.remove("") booktypes.remove("")
print(booktypes) print(booktypes)
for booktype in booktypes: for booktype in booktypes:
typeid = db.execute("select type_id from typetable where type_name=?", cur.execute("select type_id from typetable where type_name=%s", (booktype,))
(booktype,)).fetchone() typeid = cur.fetchone()
if typeid is None: if typeid is None:
db.execute("insert into typetable(`type_name`) values (?)", cur.execute("insert into typetable(`type_name`) values (%s)", (booktype,))
(booktype,)) cur.execute("select type_id from typetable where type_name=%s", (booktype,))
typeid = db.execute("select type_id from typetable where type_name=?", typeid = cur.fetchone()
(booktype,)).fetchone()
typeid = typeid['type_id'] typeid = typeid['type_id']
try: try:
db.execute("insert into book_type values(?,?)", cur.execute("insert into book_type values(%s,%s)",(typeid, bookid))
(typeid, bookid))
db.commit() db.commit()
except sqlite3.Error as _e: except pymysql.Error as _e:
error = "未知错误: %s" % (_e) error = "未知错误: %s" % (_e)
db.rollback() db.rollback()
if error is None: if error is None:
error = "新建图书《%s》完成" % (bookname) error = "新建图书《%s》完成" % (bookname)
# else: # else:
# return render_template("user/addbook.html", success=True) # return render_template("user/addbook.html", success=True)
typelist = db.execute("select type_name from typetable").fetchall() cur.execute("select type_name from typetable")
typelist = cur.fetchall()
return render_template("user/addbook.html", typelist=typelist, error=error, return render_template("user/addbook.html", typelist=typelist, error=error,
cur_time=datetime.datetime.now()) cur_time=datetime.datetime.now())
@ -87,6 +94,7 @@ def addbook():
@login_required @login_required
def tags(): def tags():
db = get_db() db = get_db()
cur = db.cursor()
error = None error = None
if request.method == 'POST': if request.method == 'POST':
typename = request.form['typename'] typename = request.form['typename']
@ -95,13 +103,12 @@ def tags():
rowcount = 0 rowcount = 0
if error is None: if error is None:
try: try:
rowcount = db.execute("insert into typetable(`type_name`) values(?)", rowcount = cur.execute("insert into typetable(`type_name`) values(%s)", (typename,))
(typename,)).rowcount
db.commit() db.commit()
except sqlite3.IntegrityError: except pymysql.IntegrityError:
error = "类型名称已经存在: %s" % (typename) error = "类型名称已经存在: %s" % (typename)
db.rollback() db.rollback()
except sqlite3.Error as _e: except pymysql.Error as _e:
error = "未知错误: %s" % (_e) error = "未知错误: %s" % (_e)
db.rollback() db.rollback()
if error is None: if error is None:
@ -109,7 +116,8 @@ def tags():
error = "新建可能失败,再次检查是否完成" error = "新建可能失败,再次检查是否完成"
else: else:
error = "新建类型\"%s\"完成" % (typename) error = "新建类型\"%s\"完成" % (typename)
typelist = db.execute("select * from typetable").fetchall() cur.execute("select * from typetable")
typelist = cur.fetchall()
return render_template("user/addtype.html", typelist=typelist, error=error, return render_template("user/addtype.html", typelist=typelist, error=error,
cur_time=datetime.datetime.now()) cur_time=datetime.datetime.now())
@ -117,6 +125,7 @@ def tags():
@login_required @login_required
def removetype(): def removetype():
db = get_db() db = get_db()
cur = db.cursor()
tid_to_del = request.args.get("tid") tid_to_del = request.args.get("tid")
error = None error = None
if tid_to_del is None or not tid_to_del.isnumeric(): if tid_to_del is None or not tid_to_del.isnumeric():
@ -124,9 +133,9 @@ def removetype():
rowcnt = 0 rowcnt = 0
if error is None: if error is None:
try: try:
rowcnt = db.execute("delete from typetable where type_id=?", (tid_to_del,)).rowcount rowcnt = cur.execute("delete from typetable where type_id=%s", (tid_to_del,))
db.commit() db.commit()
except sqlite3.Error as _e: except pymysql.Error as _e:
error = "删除失败:%s" % (_e) error = "删除失败:%s" % (_e)
db.rollback() db.rollback()
if error is None: if error is None:
@ -134,6 +143,7 @@ def removetype():
error = "删除可能失败,再次检查是否完成" error = "删除可能失败,再次检查是否完成"
else: else:
error = "删除(type_id=%s)完成" % tid_to_del error = "删除(type_id=%s)完成" % tid_to_del
cur.close()
return render_template("user/result.html", opname="删除分类", return render_template("user/result.html", opname="删除分类",
opresult=error, cur_time=datetime.datetime.now()) opresult=error, cur_time=datetime.datetime.now())
@ -143,6 +153,7 @@ def search():
attr_dict = {"书名":"book_name", "ISBN":"book_isbn", attr_dict = {"书名":"book_name", "ISBN":"book_isbn",
"作者": "book_author", "出版社":"book_publisher", "分类": "specail1"} "作者": "book_author", "出版社":"book_publisher", "分类": "specail1"}
db = get_db() db = get_db()
cur = db.cursor()
page = request.args.get('page') page = request.args.get('page')
page_lim = 10 page_lim = 10
page_off = 0 page_off = 0
@ -169,20 +180,22 @@ def search():
bookattr="" bookattr=""
if error is None: if error is None:
if queryval is None or len(queryval) == 0: if queryval is None or len(queryval) == 0:
querystring = "select * from book where user_id=%d" % (g.user['user_id']) querystring = "select * from book where user_id=%s" % (g.user['user_id'])
queryval = "" queryval = ""
elif bookattr == "分类": elif bookattr == "分类":
querystring = "SELECT * from v_type_to_book WHERE user_id=%d AND type_name LIKE \'%%%s%%\'" % (g.user['user_id'], queryval) querystring = "SELECT * from v_type_to_book WHERE user_id=%s AND type_name LIKE \'%%%s%%\'" % (g.user['user_id'], queryval)
else: else:
querystring = "select * from book where user_id=%d and %s like \'%%%s%%\'" % (g.user['user_id'], queryattr, queryval) querystring = "select * from book where user_id=%s and %s like \'%%%s%%\'" % (g.user['user_id'], queryattr, queryval)
querystring += " limit %d offset %d" % (page_lim, page_off) querystring += " limit %d offset %d" % (page_lim, page_off)
# print(querystring) # print(querystring)
queryresult = db.execute(querystring).fetchall() cur.execute(querystring)
queryresult = cur.fetchall()
page_last = False page_last = False
if len(queryresult) < page_lim: if len(queryresult) < page_lim:
page_last = True page_last = True
next_page_link = "/search?bookname=%s&bookattr=%s&page=%d" %(queryval, bookattr, page + 1) next_page_link = "/search?bookname=%s&bookattr=%s&page=%s" %(queryval, bookattr, page + 1)
prev_page_link = "/search?bookname=%s&bookattr=%s&page=%d" %(queryval, bookattr, page - 1) prev_page_link = "/search?bookname=%s&bookattr=%s&page=%s" %(queryval, bookattr, page - 1)
# print(prev_page_link, next_page_link) # print(prev_page_link, next_page_link)
return render_template("user/search.html", return render_template("user/search.html",
cur_time=datetime.datetime.now(), error=error, queryresult=queryresult, cur_time=datetime.datetime.now(), error=error, queryresult=queryresult,
@ -193,8 +206,90 @@ def search():
@login_required @login_required
def book(id): def book(id):
db = get_db() db = get_db()
book = db.execute("select * from book where book_id=?", (id,)).fetchone() cur = db.cursor()
booktype = db.execute("select * from v_book_to_types where book_id=?", (book['book_id'], )).fetchall() cur.execute("select * from book where book_id=%s", (id,))
book = cur.fetchone()
cur.execute("select * from v_book_to_types where book_id=%s", (book['book_id'], ))
booktype = cur.fetchall()
return render_template("/user/book.html", return render_template("/user/book.html",
book=book, booktype=booktype, book=book, booktype=booktype,
cur_time=datetime.datetime.now())
@bp.route("/book/update/<int:id>/", methods=("GET", "POST"))
@login_required
def book_update(id):
db = get_db()
cur = db.cursor()
error = None
if request.method == 'POST':
bookname = request.form['bookname']
bookisbn = request.form['bookisbn']
bookpublisher = request.form['bookpublisher']
booklang = request.form['booklang']
bookauthor = request.form['bookauthor']
booktype = request.form['booktype']
error = None
if len(bookname) == 0:
error = "书名不能为空"
if len(bookisbn) == 0:
bookisbn = None
if len(bookpublisher) == 0:
bookpublisher = None
if len(booklang) == 0:
booklang = None
if len(bookauthor) == 0:
booklang = None
if len(booktype) == 0:
booktype = None
cur.execute('update book set `book_name`=%s where `book_id`=%s', (bookname, id))
cur.execute('update book set `book_isbn`=%s where `book_id`=%s', (bookisbn, id))
cur.execute('update book set `book_publisher`=%s where `book_id`=%s', (bookpublisher, id))
cur.execute('update book set `book_lang`=%s where `book_id`=%s', (booklang, id))
cur.execute('update book set `book_author`=%s where `book_id`=%s', (bookauthor, id))
db.commit()
error = None
if booktype is not None:
booktype = booktype.strip()
if booktype[-1] != ';':
booktype += ';'
booktypes = booktype.split(";")
booktypes.remove("")
print(booktypes)
for booktype in booktypes:
cur.execute("select type_id from typetable where type_name=%s", (booktype,))
typeid = cur.fetchone()
if typeid is None:
cur.execute("insert into typetable(`type_name`) values (%s)", (booktype,))
cur.execute("select type_id from typetable where type_name=%s", (booktype,))
typeid = cur.fetchone()
typeid = typeid['type_id']
try:
cur.execute("insert into book_type values(%s,%s)",(typeid, id))
db.commit()
except pymysql.IntegrityError:
db.rollback()
except pymysql.Error as _e:
error = "未知错误: %s" % (_e)
db.rollback()
if error is None:
cur.close()
return redirect(url_for("user.book", id=id))
cur.execute("select * from book where book_id=%s", (id,))
bookinfo = cur.fetchone()
assert(bookinfo is not None)
cur.execute("select * from v_book_to_types where book_id=%s", (bookinfo['book_id'], ))
booktype = cur.fetchall()
cur.execute("select type_name from typetable")
typelist = cur.fetchall()
cur.close()
for k in bookinfo:
if bookinfo[k] is None:
bookinfo[k] = ''
booktypestr = ""
print(booktype)
for k in booktype:
booktypestr += k['type_name'] + ';'
return render_template("/user/updatebook.html",
book=bookinfo, booktype=booktypestr, typelist=typelist,
cur_time=datetime.datetime.now()) cur_time=datetime.datetime.now())