From bdee3b3efa7f2173c56599f61eac95ecffed888a Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Tue, 12 May 2026 19:25:31 +0800 Subject: [PATCH] feat: update database fields --- assets/migration/README.md | 3 + assets/migration/v1_to_v2.sqlite.sql | 49 ++++++++++++ backend/database.py | 108 +++++++++++++-------------- backend/sql/sqlite.sql | 80 ++++++++++---------- tools/.nginx.conf | 61 --------------- tools/dial_plate_gen.py | 29 ------- 6 files changed, 146 insertions(+), 184 deletions(-) create mode 100644 assets/migration/README.md create mode 100644 assets/migration/v1_to_v2.sqlite.sql delete mode 100644 tools/.nginx.conf delete mode 100644 tools/dial_plate_gen.py diff --git a/assets/migration/README.md b/assets/migration/README.md new file mode 100644 index 0000000..6107da6 --- /dev/null +++ b/assets/migration/README.md @@ -0,0 +1,3 @@ +# Migration + +This directory contains the migration scripts for the database. diff --git a/assets/migration/v1_to_v2.sqlite.sql b/assets/migration/v1_to_v2.sqlite.sql new file mode 100644 index 0000000..0b696b5 --- /dev/null +++ b/assets/migration/v1_to_v2.sqlite.sql @@ -0,0 +1,49 @@ +-- Migration script for coconut-leaf database v1 to v2 +-- This script updates field names by: +-- 1. Removing 'ccn_' prefix from all fields +-- 2. Converting camelCase to snake_case + +-- Step 1: Rename user table columns +ALTER TABLE user RENAME COLUMN ccn_name TO name; +ALTER TABLE user RENAME COLUMN ccn_password TO password; +ALTER TABLE user RENAME COLUMN ccn_isAdmin TO is_admin; +ALTER TABLE user RENAME COLUMN ccn_salt TO salt; + +-- Step 2: Rename token table columns +ALTER TABLE token RENAME COLUMN ccn_user TO user; +ALTER TABLE token RENAME COLUMN ccn_token TO token; +ALTER TABLE token RENAME COLUMN ccn_tokenExpireOn TO token_expire_on; +ALTER TABLE token RENAME COLUMN ccn_ua TO ua; +ALTER TABLE token RENAME COLUMN ccn_ip TO ip; + +-- Step 3: Rename collection table columns +ALTER TABLE collection RENAME COLUMN ccn_uuid TO uuid; +ALTER TABLE collection RENAME COLUMN ccn_name TO name; +ALTER TABLE collection RENAME COLUMN ccn_user TO user; +ALTER TABLE collection RENAME COLUMN ccn_lastChange TO last_change; + +-- Step 4: Rename share table columns +ALTER TABLE share RENAME COLUMN ccn_uuid TO uuid; +ALTER TABLE share RENAME COLUMN ccn_target TO target; + +-- Step 5: Rename calendar table columns +ALTER TABLE calendar RENAME COLUMN ccn_uuid TO uuid; +ALTER TABLE calendar RENAME COLUMN ccn_belongTo TO belong_to; +ALTER TABLE calendar RENAME COLUMN ccn_title TO title; +ALTER TABLE calendar RENAME COLUMN ccn_description TO description; +ALTER TABLE calendar RENAME COLUMN ccn_lastChange TO last_change; +ALTER TABLE calendar RENAME COLUMN ccn_eventDateTimeStart TO event_date_time_start; +ALTER TABLE calendar RENAME COLUMN ccn_eventDateTimeEnd TO event_date_time_end; +ALTER TABLE calendar RENAME COLUMN ccn_timezoneOffset TO timezone_offset; +ALTER TABLE calendar RENAME COLUMN ccn_loopRules TO loop_rules; +ALTER TABLE calendar RENAME COLUMN ccn_loopDateTimeStart TO loop_date_time_start; +ALTER TABLE calendar RENAME COLUMN ccn_loopDateTimeEnd TO loop_date_time_end; + +-- Step 6: Rename todo table columns +ALTER TABLE todo RENAME COLUMN ccn_uuid TO uuid; +ALTER TABLE todo RENAME COLUMN ccn_belongTo TO belong_to; +ALTER TABLE todo RENAME COLUMN ccn_data TO data; +ALTER TABLE todo RENAME COLUMN ccn_lastChange TO last_change; + +-- Note: Foreign key constraints will be automatically updated by SQLite when renaming columns +-- No additional steps needed for foreign keys diff --git a/backend/database.py b/backend/database.py index 0685021..6586e2b 100644 --- a/backend/database.py +++ b/backend/database.py @@ -119,10 +119,10 @@ class CalendarDatabase: # ======================= token related internal operation def tokenOper_clean(self): # remove outdated token - self.cursor.execute('DELETE FROM token WHERE [ccn_tokenExpireOn] <= ?',(utils.GetCurrentTimestamp(), )) + self.cursor.execute('DELETE FROM token WHERE [token_expire_on] <= ?',(utils.GetCurrentTimestamp(), )) def tokenOper_postpone_expireOn(self, token): - self.cursor.execute('UPDATE token SET [ccn_tokenExpireOn] = ? WHERE [ccn_token] = ?;', ( + self.cursor.execute('UPDATE token SET [token_expire_on] = ? WHERE [token] = ?;', ( utils.GetTokenExpireOn(), token )) @@ -131,12 +131,12 @@ class CalendarDatabase: self.tokenOper_get_username(token) def tokenOper_is_admin(self, username): - self.cursor.execute('SELECT [ccn_isAdmin] FROM user WHERE [ccn_name] = ?;',(username, )) + self.cursor.execute('SELECT [is_admin] FROM user WHERE [name] = ?;',(username, )) cache = self.cursor.fetchone()[0] return cache == 1 def tokenOper_get_username(self, token): - self.cursor.execute('SELECT [ccn_user] FROM token WHERE [ccn_token] = ? AND [ccn_tokenExpireOn] > ?;',( + self.cursor.execute('SELECT [user] FROM token WHERE [token] = ? AND [token_expire_on] > ?;',( token, utils.GetCurrentTimestamp() )) @@ -151,7 +151,7 @@ class CalendarDatabase: @SafeDatabaseOperation def common_salt(self, username): salt = utils.GenerateSalt() - self.cursor.execute('UPDATE user SET [ccn_salt] = ? WHERE [ccn_name] = ?;', ( + self.cursor.execute('UPDATE user SET [salt] = ? WHERE [name] = ?;', ( salt, username )) @@ -159,12 +159,12 @@ class CalendarDatabase: @SafeDatabaseOperation def common_login(self, username, password, clientUa, clientIp): - self.cursor.execute('SELECT [ccn_password], [ccn_salt] FROM user WHERE [ccn_name] = ?;', (username, )) + self.cursor.execute('SELECT [password], [salt] FROM user WHERE [name] = ?;', (username, )) (gotten_salt, gotten_password) = self.cursor.fetchone() if password == utils.ComputePasswordHashWithSalt(gotten_password, gotten_salt): token = utils.GenerateToken(username) - self.cursor.execute('UPDATE user SET [ccn_salt] = ? WHERE [ccn_name] = ?;', ( + self.cursor.execute('UPDATE user SET [salt] = ? WHERE [name] = ?;', ( utils.GenerateSalt(), # regenerate a new slat to prevent re-login try username )) @@ -182,7 +182,7 @@ class CalendarDatabase: @SafeDatabaseOperation def common_webLogin(self, username, password, clientUa, clientIp): - self.cursor.execute('SELECT [ccn_name] FROM user WHERE [ccn_name] = ? AND [ccn_password] = ?;', (username, utils.ComputePasswordHash(password))) + self.cursor.execute('SELECT [name] FROM user WHERE [name] = ? AND [password] = ?;', (username, utils.ComputePasswordHash(password))) if len(self.cursor.fetchall()) != 0: token = utils.GenerateToken(username) @@ -201,7 +201,7 @@ class CalendarDatabase: @SafeDatabaseOperation def common_logout(self, token): self.tokenOper_check_valid(token) - self.cursor.execute('DELETE FROM token WHERE [ccn_token] = ?;', (token, )) + self.cursor.execute('DELETE FROM token WHERE [token] = ?;', (token, )) return True @SafeDatabaseOperation @@ -214,24 +214,24 @@ class CalendarDatabase: def calendar_getFull(self, token, startDateTime, endDateTime): username = self.tokenOper_get_username(token) self.cursor.execute('SELECT calendar.* FROM calendar INNER JOIN collection \ - ON collection.ccn_uuid = calendar.ccn_belongTo \ - WHERE (collection.ccn_user = ? AND calendar.ccn_loopDateTimeEnd >= ? AND calendar.ccn_loopDateTimeStart - (calendar.ccn_eventDateTimeEnd - calendar.ccn_eventDateTimeStart) <= ?);', + ON collection.uuid = calendar.belong_to \ + WHERE (collection.user = ? AND calendar.loop_date_time_end >= ? AND calendar.loop_date_time_start - (calendar.event_date_time_end - calendar.event_date_time_start) <= ?);', (username, startDateTime, endDateTime)) return self.cursor.fetchall() @SafeDatabaseOperation def calendar_getList(self, token, startDateTime, endDateTime): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT calendar.ccn_uuid FROM calendar INNER JOIN collection \ - ON collection.ccn_uuid = calendar.ccn_belongTo \ - WHERE (collection.ccn_user = ? AND calendar.ccn_loopDateTimeEnd >= ? AND calendar.ccn_loopDateTimeStart - (calendar.ccn_eventDateTimeEnd - calendar.ccn_eventDateTimeStart) <= ?);', + self.cursor.execute('SELECT calendar.uuid FROM calendar INNER JOIN collection \ + ON collection.uuid = calendar.belong_to \ + WHERE (collection.user = ? AND calendar.loop_date_time_end >= ? AND calendar.loop_date_time_start - (calendar.event_date_time_end - calendar.event_date_time_start) <= ?);', (username, startDateTime, endDateTime)) return tuple(map(lambda x: x[0], self.cursor.fetchall())) @SafeDatabaseOperation def calendar_getDetail(self, token, uuid): self.tokenOper_check_valid(token) - self.cursor.execute('SELECT * FROM calendar WHERE [ccn_uuid] = ?;', (uuid, )) + self.cursor.execute('SELECT * FROM calendar WHERE [uuid] = ?;', (uuid, )) return self.cursor.fetchone() @SafeDatabaseOperation @@ -239,13 +239,13 @@ class CalendarDatabase: self.tokenOper_check_valid(token) # get prev data - self.cursor.execute('SELECT * FROM calendar WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', (uuid, lastChange)) + self.cursor.execute('SELECT * FROM calendar WHERE [uuid] = ? AND [last_change] = ?;', (uuid, lastChange)) analyseData = list(self.cursor.fetchone()) # construct update data lastupdate = utils.GenerateUUID() sqlList = [ - '[ccn_lastChange] = ?', + '[last_change] = ?', ] argumentsList = [ lastupdate, @@ -256,44 +256,44 @@ class CalendarDatabase: cache = optArgs.get('belongTo', None) if cache is not None: - sqlList.append('[ccn_belongTo] = ?') + sqlList.append('[belong_to] = ?') argumentsList.append(cache) cache = optArgs.get('title', None) if cache is not None: - sqlList.append('[ccn_title] = ?') + sqlList.append('[title] = ?') argumentsList.append(cache) cache = optArgs.get('description', None) if cache is not None: - sqlList.append('[ccn_description] = ?') + sqlList.append('[description] = ?') argumentsList.append(cache) cache = optArgs.get('eventDateTimeStart', None) if cache is not None: - sqlList.append('[ccn_eventDateTimeStart] = ?') + sqlList.append('[event_date_time_start] = ?') argumentsList.append(cache) reAnalyseLoop = True analyseData[5] = cache cache = optArgs.get('eventDateTimeEnd', None) if cache is not None: - sqlList.append('[ccn_eventDateTimeEnd] = ?') + sqlList.append('[event_date_time_end] = ?') argumentsList.append(cache) cache = optArgs.get('loopRules', None) if cache is not None: - sqlList.append('[ccn_loopRules] = ?') + sqlList.append('[loop_rules] = ?') argumentsList.append(cache) reAnalyseLoop = True analyseData[8] = cache cache = optArgs.get('timezoneOffset', None) if cache is not None: - sqlList.append('[ccn_timezoneOffset] = ?') + sqlList.append('[timezone_offset] = ?') argumentsList.append(cache) reAnalyseLoop = True analyseData[7] = cache if reAnalyseLoop: # re-compute loop data and upload it into list - sqlList.append('[ccn_loopDateTimeStart] = ?') + sqlList.append('[loop_date_time_start] = ?') argumentsList.append(analyseData[5]) - sqlList.append('[ccn_loopDateTimeEnd] = ?') + sqlList.append('[loop_date_time_end] = ?') argumentsList.append(str(dt.ResolveLoopStr( analyseData[8], analyseData[5], @@ -302,7 +302,7 @@ class CalendarDatabase: # execute argumentsList.append(uuid) - self.cursor.execute('UPDATE calendar SET {} WHERE [ccn_uuid] = ?;'.format(', '.join(sqlList)), + self.cursor.execute('UPDATE calendar SET {} WHERE [uuid] = ?;'.format(', '.join(sqlList)), tuple(argumentsList)) if self.cursor.rowcount != 1: raise Exception('Fail to update due to no matched rows or too much rows.') @@ -336,7 +336,7 @@ class CalendarDatabase: @SafeDatabaseOperation def calendar_delete(self, token, uuid, lastChange): self.tokenOper_check_valid(token) - self.cursor.execute('DELETE FROM calendar WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', (uuid, lastChange)) + self.cursor.execute('DELETE FROM calendar WHERE [uuid] = ? AND [last_change] = ?;', (uuid, lastChange)) if self.cursor.rowcount != 1: raise Exception('Fail to delete due to no matched rows or too much rows.') return True @@ -345,19 +345,19 @@ class CalendarDatabase: @SafeDatabaseOperation def collection_getFullOwn(self, token): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT [ccn_uuid], [ccn_name], [ccn_lastChange] FROM collection WHERE [ccn_user] = ?;', (username, )) + self.cursor.execute('SELECT [uuid], [name], [last_change] FROM collection WHERE [user] = ?;', (username, )) return self.cursor.fetchall() @SafeDatabaseOperation def collection_getListOwn(self, token): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT [ccn_uuid] FROM collection WHERE [ccn_user] = ?;', (username, )) + self.cursor.execute('SELECT [uuid] FROM collection WHERE [user] = ?;', (username, )) return tuple(map(lambda x: x[0], self.cursor.fetchall())) @SafeDatabaseOperation def collection_getDetailOwn(self, token, uuid): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT [ccn_uuid], [ccn_name], [ccn_lastChange] FROM collection WHERE [ccn_user] = ? AND [ccn_uuid] = ?;', (username, uuid)) + self.cursor.execute('SELECT [uuid], [name], [last_change] FROM collection WHERE [user] = ? AND [uuid] = ?;', (username, uuid)) return self.cursor.fetchone() @SafeDatabaseOperation @@ -374,7 +374,7 @@ class CalendarDatabase: self.tokenOper_check_valid(token) lastupdate = utils.GenerateUUID() - self.cursor.execute('UPDATE collection SET [ccn_name] = ?, [ccn_lastChange] = ? WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', ( + self.cursor.execute('UPDATE collection SET [name] = ?, [last_change] = ? WHERE [uuid] = ? AND [last_change] = ?;', ( newname, lastupdate, uuid, @@ -388,7 +388,7 @@ class CalendarDatabase: def collection_deleteOwn(self, token, uuid, lastChange): self.tokenOper_check_valid(token) - self.cursor.execute('DELETE FROM collection WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', ( + self.cursor.execute('DELETE FROM collection WHERE [uuid] = ? AND [last_change] = ?;', ( uuid, lastChange )) @@ -399,7 +399,7 @@ class CalendarDatabase: @SafeDatabaseOperation def collection_getSharing(self, token, uuid): self.tokenOper_check_valid(token) - self.cursor.execute('SELECT [ccn_target] FROM share WHERE [ccn_uuid] = ?;', (uuid, )) + self.cursor.execute('SELECT [target] FROM share WHERE [uuid] = ?;', (uuid, )) return tuple(map(lambda x: x[0], self.cursor.fetchall())) @SafeDatabaseOperation @@ -407,11 +407,11 @@ class CalendarDatabase: self.tokenOper_check_valid(token) lastupdate = utils.GenerateUUID() - self.cursor.execute('UPDATE collection SET [ccn_lastChange] = ?, WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', (lastupdate, uuid, lastChange)) + self.cursor.execute('UPDATE collection SET [last_change] = ?, WHERE [uuid] = ? AND [last_change] = ?;', (lastupdate, uuid, lastChange)) if self.cursor.rowcount != 1: raise Exception('Fail to delete due to no matched rows or too much rows.') - self.cursor.execute('DELETE FROM share WHERE [ccn_uuid] = ? AND [ccn_target] = ?;', (uuid, target)) + self.cursor.execute('DELETE FROM share WHERE [uuid] = ? AND [target] = ?;', (uuid, target)) if self.cursor.rowcount != 1: raise Exception('Fail to delete due to no matched rows or too much rows.') @@ -422,11 +422,11 @@ class CalendarDatabase: self.tokenOper_check_valid(token) lastupdate = utils.GenerateUUID() - self.cursor.execute('UPDATE collection SET [ccn_lastChange] = ? WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', (lastupdate, uuid, lastChange)) + self.cursor.execute('UPDATE collection SET [last_change] = ? WHERE [uuid] = ? AND [last_change] = ?;', (lastupdate, uuid, lastChange)) if self.cursor.rowcount != 1: raise Exception('Fail to delete due to no matched rows or too much rows.') - self.cursor.execute('SELECT * FROM share WHERE [ccn_uuid] = ? AND [ccn_target] = ?;', (uuid, target)) + self.cursor.execute('SELECT * FROM share WHERE [uuid] = ? AND [target] = ?;', (uuid, target)) if len(self.cursor.fetchall()) != 0: raise Exception('Fail to insert duplicated item.') self.cursor.execute('INSERT INTO share VALUES (?, ?);', (uuid, target)) @@ -436,29 +436,29 @@ class CalendarDatabase: @SafeDatabaseOperation def collection_getShared(self, token): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT collection.ccn_uuid, collection.ccn_name, collection.ccn_user \ + self.cursor.execute('SELECT collection.uuid, collection.name, collection.user \ FROM share INNER JOIN collection \ - ON share.ccn_uuid = collection.ccn_uuid \ - WHERE share.ccn_target = ?;', (username, )) + ON share.uuid = collection.uuid \ + WHERE share.target = ?;', (username, )) return self.cursor.fetchall() # =============================== todo @SafeDatabaseOperation def todo_getFull(self, token): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT * FROM todo WHERE [ccn_belongTo] = ?;', (username, )) + self.cursor.execute('SELECT * FROM todo WHERE [belong_to] = ?;', (username, )) return self.cursor.fetchall() @SafeDatabaseOperation def todo_getList(self, token): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT [ccn_uuid] FROM todo WHERE [ccn_belongTo] = ?;', (username, )) + self.cursor.execute('SELECT [uuid] FROM todo WHERE [belong_to] = ?;', (username, )) return tuple(map(lambda x: x[0], self.cursor.fetchall())) @SafeDatabaseOperation def todo_getDetail(self, token, uuid): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT * FROM todo WHERE [ccn_belongTo] = ? AND [ccn_uuid] = ?;', (username, uuid)) + self.cursor.execute('SELECT * FROM todo WHERE [belong_to] = ? AND [uuid] = ?;', (username, uuid)) return self.cursor.fetchone() @SafeDatabaseOperation @@ -482,7 +482,7 @@ class CalendarDatabase: # update newLastChange = utils.GenerateUUID() - self.cursor.execute('UPDATE todo SET [ccn_data] = ?, [ccn_lastChange] = ? WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', ( + self.cursor.execute('UPDATE todo SET [data] = ?, [last_change] = ? WHERE [uuid] = ? AND [last_change] = ?;', ( data, newLastChange, uuid, @@ -498,7 +498,7 @@ class CalendarDatabase: self.tokenOper_check_valid(token) # delete - self.cursor.execute('DELETE FROM todo WHERE [ccn_uuid] = ? AND [ccn_lastChange] = ?;', (uuid, lastChange)) + self.cursor.execute('DELETE FROM todo WHERE [uuid] = ? AND [last_change] = ?;', (uuid, lastChange)) if self.cursor.rowcount != 1: raise Exception('Fail to delete due to no matched rows or too much rows.') return True @@ -511,7 +511,7 @@ class CalendarDatabase: if not self.tokenOper_is_admin(username): raise Exception('Permission denied.') - self.cursor.execute('SELECT [ccn_name], [ccn_isAdmin] FROM user;') + self.cursor.execute('SELECT [name], [is_admin] FROM user;') return tuple(map(lambda x: (x[0], x[1] == 1), self.cursor.fetchall())) @SafeDatabaseOperation @@ -542,16 +542,16 @@ class CalendarDatabase: # analyse opt arg cache = optArgs.get('password', None) if cache is not None: - sqlList.append('[ccn_password] = ?') + sqlList.append('[password] = ?') argumentsList.append(utils.ComputePasswordHash(cache)) cache = optArgs.get('isAdmin', None) if cache is not None: - sqlList.append('[ccn_isAdmin] = ?') + sqlList.append('[is_admin] = ?') argumentsList.append(1 if cache else 0) # execute argumentsList.append(_username) - self.cursor.execute('UPDATE user SET {} WHERE [ccn_name] = ?;'.format(', '.join(sqlList)), + self.cursor.execute('UPDATE user SET {} WHERE [name] = ?;'.format(', '.join(sqlList)), tuple(argumentsList)) logging.debug(cache) logging.debug(tuple(argumentsList)) @@ -566,7 +566,7 @@ class CalendarDatabase: raise Exception('Permission denied.') # delete - self.cursor.execute('DELETE FROM user WHERE [ccn_name] = ?;', (username, )) + self.cursor.execute('DELETE FROM user WHERE [name] = ?;', (username, )) if self.cursor.rowcount != 1: raise Exception('Fail to delete due to no matched rows or too much rows.') return True @@ -580,7 +580,7 @@ class CalendarDatabase: @SafeDatabaseOperation def profile_changePassword(self, token, newpassword): username = self.tokenOper_get_username(token) - self.cursor.execute('UPDATE user SET [ccn_password] = ? WHERE [ccn_name] = ?;', ( + self.cursor.execute('UPDATE user SET [password] = ? WHERE [name] = ?;', ( utils.ComputePasswordHash(newpassword), username )) @@ -590,7 +590,7 @@ class CalendarDatabase: def profile_getToken(self, token): username = self.tokenOper_get_username(token) - self.cursor.execute('SELECT * FROM token WHERE [ccn_user] = ?;', ( + self.cursor.execute('SELECT * FROM token WHERE [user] = ?;', ( username, )) return self.cursor.fetchall() @@ -600,7 +600,7 @@ class CalendarDatabase: _username = self.tokenOper_get_username(token) # delete - self.cursor.execute('DELETE FROM token WHERE [ccn_user] = ? AND [ccn_token] = ?;', ( + self.cursor.execute('DELETE FROM token WHERE [user] = ? AND [token] = ?;', ( _username, deleteToken )) diff --git a/backend/sql/sqlite.sql b/backend/sql/sqlite.sql index ffcd44a..e52b028 100644 --- a/backend/sql/sqlite.sql +++ b/backend/sql/sqlite.sql @@ -1,67 +1,67 @@ CREATE TABLE user( - [ccn_name] TEXT NOT NULL, - [ccn_password] TEXT NOT NULL, - [ccn_isAdmin] TINYINT NOT NULL CHECK(ccn_isAdmin = 1 OR ccn_isAdmin = 0), - [ccn_salt] INTEGER NOT NULL, + [name] TEXT NOT NULL, + [password] TEXT NOT NULL, + [is_admin] TINYINT NOT NULL CHECK(is_admin = 1 OR is_admin = 0), + [salt] INTEGER NOT NULL, - PRIMARY KEY (ccn_name) + PRIMARY KEY (name) ); CREATE TABLE token( - [ccn_user] TEXT NOT NULL, - [ccn_token] TEXT UNIQUE NOT NULL, - [ccn_tokenExpireOn] BIGINT NOT NULL, - [ccn_ua] TEXT NOT NULL, - [ccn_ip] TEXT NOT NULL, + [user] TEXT NOT NULL, + [token] TEXT UNIQUE NOT NULL, + [token_expire_on] BIGINT NOT NULL, + [ua] TEXT NOT NULL, + [ip] TEXT NOT NULL, - FOREIGN KEY (ccn_user) REFERENCES user(ccn_name) ON DELETE CASCADE + FOREIGN KEY (user) REFERENCES user(name) ON DELETE CASCADE ); CREATE TABLE collection( - [ccn_uuid] TEXT NOT NULL, - [ccn_name] TEXT NOT NULL, - [ccn_user] TEXT NOT NULL, - [ccn_lastChange] TEXT NOT NULL, + [uuid] TEXT NOT NULL, + [name] TEXT NOT NULL, + [user] TEXT NOT NULL, + [last_change] TEXT NOT NULL, - PRIMARY KEY (ccn_uuid), - FOREIGN KEY (ccn_user) REFERENCES user(ccn_name) ON DELETE CASCADE + PRIMARY KEY (uuid), + FOREIGN KEY (user) REFERENCES user(name) ON DELETE CASCADE ); CREATE TABLE share( - [ccn_uuid] TEXT NOT NULL, - [ccn_target] TEXT NOT NULL, + [uuid] TEXT NOT NULL, + [target] TEXT NOT NULL, - FOREIGN KEY (ccn_uuid) REFERENCES collection(ccn_uuid) ON DELETE CASCADE - FOREIGN KEY (ccn_target) REFERENCES user(ccn_name) ON DELETE CASCADE + FOREIGN KEY (uuid) REFERENCES collection(uuid) ON DELETE CASCADE + FOREIGN KEY (target) REFERENCES user(name) ON DELETE CASCADE ); CREATE TABLE calendar( - [ccn_uuid] TEXT NOT NULL, - [ccn_belongTo] TEXT NOT NULL, + [uuid] TEXT NOT NULL, + [belong_to] TEXT NOT NULL, - [ccn_title] TEXT NOT NULL, - [ccn_description] TEXT NOT NULL, - [ccn_lastChange] TEXT NOT NULL, + [title] TEXT NOT NULL, + [description] TEXT NOT NULL, + [last_change] TEXT NOT NULL, - [ccn_eventDateTimeStart] BIGINT NOT NULL, - [ccn_eventDateTimeEnd] BIGINT NOT NULL, - [ccn_timezoneOffset] INT NOT NULL, + [event_date_time_start] BIGINT NOT NULL, + [event_date_time_end] BIGINT NOT NULL, + [timezone_offset] INT NOT NULL, - [ccn_loopRules] TEXT NOT NULL, - [ccn_loopDateTimeStart] BIGINT NOT NULL, - [ccn_loopDateTimeEnd] BIGINT NOT NULL, + [loop_rules] TEXT NOT NULL, + [loop_date_time_start] BIGINT NOT NULL, + [loop_date_time_end] BIGINT NOT NULL, - PRIMARY KEY (ccn_uuid), - FOREIGN KEY (ccn_belongTo) REFERENCES collection(ccn_uuid) ON DELETE CASCADE + PRIMARY KEY (uuid), + FOREIGN KEY (belong_to) REFERENCES collection(uuid) ON DELETE CASCADE ); CREATE TABLE todo( - [ccn_uuid] TEXT NOT NULL, - [ccn_belongTo] TEXT NOT NULL, + [uuid] TEXT NOT NULL, + [belong_to] TEXT NOT NULL, - [ccn_data] TEXT NOT NULL, - [ccn_lastChange] TEXT NOT NULL, + [data] TEXT NOT NULL, + [last_change] TEXT NOT NULL, - PRIMARY KEY (ccn_uuid), - FOREIGN KEY (ccn_belongTo) REFERENCES user(ccn_name) ON DELETE CASCADE + PRIMARY KEY (uuid), + FOREIGN KEY (belong_to) REFERENCES user(name) ON DELETE CASCADE ); \ No newline at end of file diff --git a/tools/.nginx.conf b/tools/.nginx.conf deleted file mode 100644 index 38148f6..0000000 --- a/tools/.nginx.conf +++ /dev/null @@ -1,61 +0,0 @@ -# ============================ -# 路由 1: /web -> 静态文件 -# ============================ -location /web { - # 使用 alias 精确映射 - # 请求 /web/index.html -> /var/www/static/index.html - alias /var/www/static; - - # 静态文件优化 - expires 7d; - add_header Cache-Control "public, max-age=604800"; - - # 尝试返回文件,不存在则返回404(避免落入其他location) - try_files $uri $uri/ =404; - - # 可选:启用 gzip 压缩 - gzip_static on; -} - -# ============================ -# 路由 2: /api -> Go 程序 (8848端口) -# ============================ -location /api { - # 反向代理到本地 Go 服务 - proxy_pass http://127.0.0.1:8848; - - # 重要:保留原始请求头 - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # WebSocket 支持(如果 Go 程序需要) - # proxy_http_version 1.1; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection "upgrade"; - - # 超时设置(根据业务调整) - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - - # 缓冲设置(可选,大文件上传时注意调整) - proxy_buffering on; - proxy_buffer_size 4k; - proxy_buffers 8 4k; -} - -# ============================ -# 可选:根路径处理 -# ============================ -location = / { - # 重定向到 /web - return 302 /web/; -} - -# 禁止访问隐藏文件 -location ~ /\. { - deny all; - return 404; -} \ No newline at end of file diff --git a/tools/dial_plate_gen.py b/tools/dial_plate_gen.py deleted file mode 100644 index ad83c70..0000000 --- a/tools/dial_plate_gen.py +++ /dev/null @@ -1,29 +0,0 @@ -import math - -print('Dial Plate Generator') -plateSize = float(input('Plate size: ')) -hourInnerRadius = float(input('Hour inner radius percent (float): ')) -hourOutterRadius = float(input('Hour outter radius percent (float): ')) -minuteRadius = float(input('Minute radius percent (float): ')) - -halfPlateSize = plateSize / 2 -for i in range(24): - rad = math.radians(90 - i * 30) - x = math.cos(rad) - y = math.sin(rad) - radius = halfPlateSize * (hourOutterRadius if i < 12 else hourInnerRadius) - x = x * radius + halfPlateSize - y = (-y * radius) + halfPlateSize - print('{}'.format(x, y, i)) - -print('') - -for i in range(12): - rad = math.radians(90 - i * 30) - x = math.cos(rad) - y = math.sin(rad) - radius = minuteRadius * halfPlateSize - x = x * radius + halfPlateSize - y = (-y * radius) + halfPlateSize - print('{}'.format(x, y, i * 5)) -