diff --git a/README.md b/README.md index 94680c5..0c20624 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,7 @@ cd src python -m venv venv pip install flask flask --app main run -``` \ No newline at end of file +``` + +使用之前,需要新整一个mysql服务器,然后在里面建立一个数据库bigwork并保证该数据库被授权给了指定的用户。 +在config里面修改对应的用户、密码、服务器地址 \ No newline at end of file diff --git a/sql/db_create.sql b/sql/db_create.sql index 9cac25c..08232aa 100644 --- a/sql/db_create.sql +++ b/sql/db_create.sql @@ -1,111 +1,134 @@ -drop database if exists bigwork; -create database bigwork; - +use 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` ( - passwd varchar(100) NOT NULL + passwd varchar(200) NOT NULL ); -insert into `admin` (`passwd`) values(''); +-- 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 + user_id int PRIMARY KEY AUTO_INCREMENT, + user_name varchar(100) NOT NULL UNIQUE, + user_mail varchar(100) NOT NULL UNIQUE, + user_passwd varchar(200) NOT NULL, + user_limit int NOT NULL, + user_regtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) 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`) + 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, + book_author varchar(100) DEFAULT NULL, + 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; 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) + 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 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + 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`) ON DELETE CASCADE, + CONSTRAINT `fk_document_book_id` FOREIGN KEY (`book_id`) REFERENCES book(`book_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +create index `idx_doc_name` on document(doc_name); 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)) + note_id int PRIMARY KEY AUTO_INCREMENT, + note_name varchar(100) NOT NULL, + note_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + note_content text NOT NULL, + book_id int NOT NULL, + user_id int NOT NULL, + 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`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; - +create index `idx_note_name` on note(note_name); 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) + record_time timestamp PRIMARY KEY DEFAULT CURRENT_TIMESTAMP, + record_type varchar(10) NOT NULL, + doc_URL varchar(100) NOT NULL, + user_id int NOT NULL ) 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) + type_id int PRIMARY KEY AUTO_INCREMENT, + type_name varchar(20) NOT NULL UNIQUE ) 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)) + author_id int PRIMARY KEY AUTO_INCREMENT, + author_name varchar(50) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +create index `idx_author_name` on author(author_name); 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`) + 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`) ON DELETE RESTRICT, + 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; 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`) + 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`) ON DELETE CASCADE, + 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; 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`) + user_id int PRIMARY KEY, + user_limit int NOT NULL, + user_usedspace int NOT NULL DEFAULT 0, + user_bookcount int NOT NULL DEFAULT 0, + user_doccount int NOT NULL DEFAULT 0, + 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; +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; \ No newline at end of file diff --git a/sql/trigger.sql b/sql/trigger.sql index 27f832a..3863952 100644 --- a/sql/trigger.sql +++ b/sql/trigger.sql @@ -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`; DELIMITER ## create trigger `trig_update_stat_book_ins` @@ -36,20 +55,20 @@ create trigger `trig_update_stat_doc_del` end ## DELIMITER ; -drop trigger if exists `trig_update_stat_type_ins`; +drop trigger if exists `trig_update_stat_note_ins`; DELIMITER ## -create trigger `trig_update_stat_type_ins` - after insert on typetable +create trigger `trig_update_stat_note_ins` + after insert on note 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 ## DELIMITER ; -drop trigger if exists `trig_update_stat_type_del`; +drop trigger if exists `trig_update_stat_note_del`; DELIMITER ## -create trigger `trig_update_stat_type_del` - after delete on typetable +create trigger `trig_update_stat_note_del` + after delete on note 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 ## DELIMITER ; \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py index 373e599..e45354b 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -8,7 +8,11 @@ def create_app(test_config=None): app = Flask(__name__, instance_relative_config=True) app.config.from_mapping( 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: diff --git a/src/admin.py b/src/admin.py index a422dcf..81b89a7 100644 --- a/src/admin.py +++ b/src/admin.py @@ -7,7 +7,7 @@ from werkzeug.security import generate_password_hash from src.auth import admin_login_required from src.db import get_db -import sqlite3 +import pymysql bp = Blueprint('admin', __name__, url_prefix='/admin') @@ -20,10 +20,12 @@ def validateEmail(email): @bp.route('/') @admin_login_required def index(): - db = get_db() - users = db.execute( + cur = get_db().cursor() + cur.execute( 'select * from user' - ).fetchall() + ) + users = cur.fetchall() + cur.close() return render_template("admin/index.html", users=users) @bp.route('/adduser', methods=("GET", "POST")) @@ -39,22 +41,27 @@ def adduser(): error = '用户空间必须是整数GB' elif not validateEmail(usermail): error = 'email格式不合法' - userlimi = int(userlimi) + userlimi = float(userlimi) userlimi *= 1024 * 1024 # userlimit is stored and measured by KB + userlimi = int(userlimi) if error is None: db = get_db() + cur = db.cursor() try: - db.execute( - 'insert into user(`user_name`, `user_mail`, `user_passwd`, `user_limit`) values (?,?,?,?)', + cur.execute( + 'insert into user(`user_name`, `user_mail`, `user_passwd`, `user_limit`) values (%s,%s,%s,%s)', (username, usermail, generate_password_hash(password), userlimi,) ) db.commit() - except sqlite3.IntegrityError as _e: + + except pymysql.IntegrityError as _e: error = "用户名或邮箱已经存在 %s" % (_e) db.rollback() - except sqlite3.Error as _e: + except pymysql.Error as _e: error = "未知错误 %s" % (_e) db.rollback() + finally: + cur.close() if error is None: return redirect(url_for('admin.index')) flash(error) @@ -69,18 +76,21 @@ def removeuser(): uid_to_del = request.args.get("uid") if uid_to_del is not None and uid_to_del.isdecimal: db = get_db() + cur = db.cursor() rowcnt = 0 try: - rowcnt = db.execute( - "delete from user where user.user_id=?", (uid_to_del, ) - ).rowcount + rowcnt = cur.execute( + "delete from user where user.user_id=%s", (uid_to_del, ) + ) db.commit() - except sqlite3.IntegrityError as _e: + except pymysql.IntegrityError as _e: error = "用户未做好被删除的准备:%s" % (_e) db.rollback() - except sqlite3.Error as _e: + except pymysql.Error as _e: error = "删除发生未知错误: %s" %(_e) db.rollback() + finally: + cur.close() if error is None: if rowcnt != 0: error = "删除uid为%s的用户成功!" % uid_to_del diff --git a/src/auth.py b/src/auth.py index acc0aab..de6f206 100644 --- a/src/auth.py +++ b/src/auth.py @@ -11,20 +11,22 @@ def loginuser(): username = request.form['username'] password = request.form['password'] db = get_db() + cur = db.cursor() error = None - user = db.execute( - 'SELECT * FROM user WHERE user_name = ?', (username,) - ).fetchone() - + cur.execute( + 'SELECT * FROM user WHERE user_name = %s', (username,) + ) + user = cur.fetchone() + cur.close() if user is None: error = '用户名不存在' elif not check_password_hash(user['user_passwd'], password): error = '密码错误' - if error is None: + if error is None and user is not None: session.clear() session['user_id'] = user['user_id'] - return redirect(url_for('home')) + return redirect(url_for('user.home')) flash(error) @@ -35,8 +37,10 @@ def loginadmin(): if request.method == 'POST': password = request.form['password'] db = get_db() + cur = db.cursor() 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: error = '用户名不存在' @@ -64,9 +68,9 @@ def load_logged_in_user(): g.user = {'user_id':0, 'user_name': 'admin'} # use id=0 to refer to admin else: - g.user = get_db().execute( - 'SELECT * FROM user WHERE user_id = ?', (user_id,) - ).fetchone() + cur = get_db().cursor() + cur.execute('SELECT * FROM user WHERE user_id = %s', (user_id,)) + g.user = cur.fetchone() @bp.route('/logout') def logout(): @@ -91,7 +95,7 @@ def admin_login_required(view): if g.user is None: return redirect(url_for('auth.login')) elif g.user['user_id'] != 0: - return redirect(url_for('home')) + return redirect(url_for('user.home')) return view(**kwargs) return wrapped_view \ No newline at end of file diff --git a/src/db.py b/src/db.py index 6955350..1aeb664 100644 --- a/src/db.py +++ b/src/db.py @@ -1,16 +1,22 @@ -import sqlite3 +# import sqlite3 +import pymysql import click from flask import current_app, g from werkzeug.security import generate_password_hash def get_db(): if 'db' not in g: - g.db = sqlite3.connect( - current_app.config['DATABASE'], - detect_types=sqlite3.PARSE_DECLTYPES - ) - g.db.row_factory = sqlite3.Row - + # g.db = sqlite3.connect( + # current_app.config['DATABASE'], + # detect_types=sqlite3.PARSE_DECLTYPES + # ) + # 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 @@ -23,14 +29,16 @@ def close_db(e=None): @click.command('init-db') def init_db(): db = get_db() - click.echo("Initializing database schema...") - with current_app.open_resource('sql/db_create_sqlite.sql') as f: - db.executescript(f.read().decode('utf8')) - click.echo("Initializing database triggers...") - with current_app.open_resource('sql/trigger_sqlite.sql') as f: - db.executescript(f.read().decode('utf8')) + click.echo("PyMySQL do not support script execution...") + # click.echo("Initializing database schema...") + # with current_app.open_resource('sql/db_create_sqlite.sql') as f: + # db.executescript(f.read().decode('utf8')) + # click.echo("Initializing database triggers...") + # with current_app.open_resource('sql/trigger_sqlite.sql') as f: + # db.executescript(f.read().decode('utf8')) 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() click.echo("Initialized database.") diff --git a/src/sql/db_create.sql b/src/sql/db_create.sql deleted file mode 100644 index 9cac25c..0000000 --- a/src/sql/db_create.sql +++ /dev/null @@ -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; diff --git a/src/sql/trigger.sql b/src/sql/trigger.sql deleted file mode 100644 index 27f832a..0000000 --- a/src/sql/trigger.sql +++ /dev/null @@ -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 ; \ No newline at end of file diff --git a/src/templates/user/addbook.html b/src/templates/user/addbook.html index 5e9557b..7ceee92 100644 --- a/src/templates/user/addbook.html +++ b/src/templates/user/addbook.html @@ -9,7 +9,7 @@ z-index: 1; top: 20; left: 0; - overflow-x: hidden; + padding-left: 1.2rem; padding-right: 2rem; } @@ -17,7 +17,7 @@ height: 100%; max-width: 160px; z-index: 1; - overflow-x: hidden; + } +{% endblock %} + +{% block content %} +
+
+
+ +
+
+
+

编辑图书

+
+
+ {%if error%} +
+ {{error}} +
+ {% endif %} +
+ + + + + + + + + + + + +
+ {% for atype in typelist%} + {{atype['type_name']}} + {% endfor %} +
+ +
+
+ +
+
+
+{% endblock %} \ No newline at end of file diff --git a/src/user.py b/src/user.py index 2187460..1f383cf 100644 --- a/src/user.py +++ b/src/user.py @@ -7,7 +7,7 @@ from werkzeug.security import generate_password_hash from src.auth import login_required from src.db import get_db -import sqlite3 +import pymysql import datetime bp = Blueprint('user', __name__) @@ -15,16 +15,20 @@ bp = Blueprint('user', __name__) @bp.route("/home") @login_required def home(): - db = get_db() - user_stat = db.execute( - "select * from user_stat where user_id = ?", (g.user['user_id'],) - ).fetchone() + cur = get_db().cursor() + cur.execute( + "select * from user_stat where user_id = %s", (g.user['user_id'],) + ) + user_stat = cur.fetchone() + print(user_stat) + cur.close() return render_template("user/home.html", user_stat=user_stat, cur_time=datetime.datetime.now()) @bp.route("/addbook", methods=('GET', 'POST')) @login_required def addbook(): db = get_db() + cur = db.cursor() error = None if request.method == 'POST': bookname = request.form['bookname'] @@ -46,40 +50,43 @@ def addbook(): booklang = None if len(booktype) == 0: booktype = None - db.execute( + cur.execute( "insert into book (`book_name`, `book_isbn`" ", `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'],)) 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)'] 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: - typeid = db.execute("select type_id from typetable where type_name=?", - (booktype,)).fetchone() + cur.execute("select type_id from typetable where type_name=%s", (booktype,)) + typeid = cur.fetchone() if typeid is None: - db.execute("insert into typetable(`type_name`) values (?)", - (booktype,)) - typeid = db.execute("select type_id from typetable where type_name=?", - (booktype,)).fetchone() + 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: - db.execute("insert into book_type values(?,?)", - (typeid, bookid)) + cur.execute("insert into book_type values(%s,%s)",(typeid, bookid)) db.commit() - except sqlite3.Error as _e: + except pymysql.Error as _e: error = "未知错误: %s" % (_e) db.rollback() if error is None: error = "新建图书《%s》完成" % (bookname) # else: # 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, cur_time=datetime.datetime.now()) @@ -87,6 +94,7 @@ def addbook(): @login_required def tags(): db = get_db() + cur = db.cursor() error = None if request.method == 'POST': typename = request.form['typename'] @@ -95,13 +103,12 @@ def tags(): rowcount = 0 if error is None: try: - rowcount = db.execute("insert into typetable(`type_name`) values(?)", - (typename,)).rowcount + rowcount = cur.execute("insert into typetable(`type_name`) values(%s)", (typename,)) db.commit() - except sqlite3.IntegrityError: + except pymysql.IntegrityError: error = "类型名称已经存在: %s" % (typename) db.rollback() - except sqlite3.Error as _e: + except pymysql.Error as _e: error = "未知错误: %s" % (_e) db.rollback() if error is None: @@ -109,7 +116,8 @@ def tags(): error = "新建可能失败,再次检查是否完成" else: 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, cur_time=datetime.datetime.now()) @@ -117,6 +125,7 @@ def tags(): @login_required def removetype(): db = get_db() + cur = db.cursor() tid_to_del = request.args.get("tid") error = None if tid_to_del is None or not tid_to_del.isnumeric(): @@ -124,9 +133,9 @@ def removetype(): rowcnt = 0 if error is None: 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() - except sqlite3.Error as _e: + except pymysql.Error as _e: error = "删除失败:%s" % (_e) db.rollback() if error is None: @@ -134,6 +143,7 @@ def removetype(): error = "删除可能失败,再次检查是否完成" else: error = "删除(type_id=%s)完成" % tid_to_del + cur.close() return render_template("user/result.html", opname="删除分类", opresult=error, cur_time=datetime.datetime.now()) @@ -143,6 +153,7 @@ def search(): attr_dict = {"书名":"book_name", "ISBN":"book_isbn", "作者": "book_author", "出版社":"book_publisher", "分类": "specail1"} db = get_db() + cur = db.cursor() page = request.args.get('page') page_lim = 10 page_off = 0 @@ -169,20 +180,22 @@ def search(): bookattr="" if error is None: 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 = "" 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: - 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) # print(querystring) - queryresult = db.execute(querystring).fetchall() + cur.execute(querystring) + queryresult = cur.fetchall() + page_last = False if len(queryresult) < page_lim: page_last = True - next_page_link = "/search?bookname=%s&bookattr=%s&page=%d" %(queryval, bookattr, page + 1) - prev_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=%s" %(queryval, bookattr, page - 1) # print(prev_page_link, next_page_link) return render_template("user/search.html", cur_time=datetime.datetime.now(), error=error, queryresult=queryresult, @@ -193,8 +206,90 @@ def search(): @login_required def book(id): db = get_db() - book = db.execute("select * from book where book_id=?", (id,)).fetchone() - booktype = db.execute("select * from v_book_to_types where book_id=?", (book['book_id'], )).fetchall() + cur = db.cursor() + 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", book=book, booktype=booktype, + cur_time=datetime.datetime.now()) + +@bp.route("/book/update//", 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()) \ No newline at end of file