From 2da99f65bbabedbf8d24b33c73d012a4bbf5c109 Mon Sep 17 00:00:00 2001 From: ws <3515701696@qq.com> Date: Mon, 20 Oct 2025 20:35:18 +0800 Subject: [PATCH] db_2 --- ghost/core/core/server/data/db/backup.js | 7 ++- ghost/core/core/server/data/db/connection.js | 22 +++---- .../server/data/exporter/export-filename.js | 58 +++++++++++++++---- .../core/core/server/data/schema/commands.js | 2 +- .../data/schema/default-settings/index.js | 1 + .../data/schema/fixtures/FixtureManager.js | 2 +- 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/ghost/core/core/server/data/db/backup.js b/ghost/core/core/server/data/db/backup.js index 55c99ab..758e1f0 100644 --- a/ghost/core/core/server/data/db/backup.js +++ b/ghost/core/core/server/data/db/backup.js @@ -12,6 +12,7 @@ const exporter = require('../exporter'); * @param {object} exportResult * @param {string} exportResult.filename * @param {object} exportResult.data + * 文件写入功能 */ const writeExportFile = async (exportResult) => { const filename = path.resolve(urlUtils.urlJoin(config.get('paths').contentPath, 'data', exportResult.filename)); @@ -21,7 +22,8 @@ const writeExportFile = async (exportResult) => { }; /** - * @param {string} filename + * @param {string} fileName + * 文件读取功能 */ const readBackup = async (filename) => { const parsedFileName = path.parse(filename); @@ -43,10 +45,11 @@ const readBackup = async (filename) => { * * @param {Object} options * @returns {Promise | null} + * 数据库备份功能 */ const backup = async function backup(options = {}) { // do not create backup if disabled in config (this is intended for large customers who will OOM node) - if (config.get('disableJSBackups')) { + if (config.get('disableJSBackups')) { //检查是否禁用了备份功能 logging.info('Database backup is disabled in Ghost config'); return null; } diff --git a/ghost/core/core/server/data/db/connection.js b/ghost/core/core/server/data/db/connection.js index 5933e89..ebd6a88 100644 --- a/ghost/core/core/server/data/db/connection.js +++ b/ghost/core/core/server/data/db/connection.js @@ -8,17 +8,17 @@ const config = require('../../../shared/config'); const errors = require('@tryghost/errors'); /** @type {knex.Knex} */ -let knexInstance; +let knexInstance; //执行的时候才会被赋予一个Knex实例 // @TODO: // - if you require this file before config file was loaded, // - then this file is cached and you have no chance to connect to the db anymore // - bring dynamic into this file (db.connect()) function configure(dbConfig) { - const client = dbConfig.client; + const client = dbConfig.client; //获取但概念的客户端 - if (client === 'sqlite3') { - // Backwards compatibility with old knex behaviour + if (client === 'sqlite3') { //向后兼容性,如果使用的是sqlite3客户端 + // Backwards compatibility with old knex behaviour dbConfig.useNullAsDefault = Object.prototype.hasOwnProperty.call(dbConfig, 'useNullAsDefault') ? dbConfig.useNullAsDefault : true; // Enables foreign key checks and delete on cascade @@ -38,6 +38,7 @@ function configure(dbConfig) { // In the default SQLite test config we set the path to /tmp/ghost-test.db, // but this won't work on Windows, so we need to replace the /tmp bit with // the Windows temp folder + // 在windows系统下的兼容性处理 const filename = dbConfig.connection.filename; if (process.platform === 'win32' && _.isString(filename) && filename.match(/^\/tmp/)) { dbConfig.connection.filename = filename.replace(/^\/tmp/, os.tmpdir()); @@ -47,18 +48,19 @@ function configure(dbConfig) { if (client === 'mysql2') { dbConfig.connection.timezone = 'Z'; - dbConfig.connection.charset = 'utf8mb4'; - dbConfig.connection.decimalNumbers = true; + dbConfig.connection.charset = 'utf8mb4'; //编码方式的设置 + dbConfig.connection.decimalNumbers = true; //是否将MySQL的DECIMAL类型转换为JavaScript的Number类型 - if (process.env.REQUIRE_INFILE_STREAM) { - if (process.env.NODE_ENV === 'development' || process.env.ALLOW_INFILE_STREAM) { + if (process.env.REQUIRE_INFILE_STREAM) { //是否要求启用infile流 + if (process.env.NODE_ENV === 'development' || process.env.ALLOW_INFILE_STREAM) { //如果是在开发环境下,或者允许启用infile流 dbConfig.connection.infileStreamFactory = path => fs.createReadStream(path); - } else { + } else {//如果不是在开发环境下,并且不允许启用infile流 throw new errors.InternalServerError({message: 'MySQL infile streaming is required to run the current process, but is not allowed. Run the script in development mode or set ALLOW_INFILE_STREAM=1.'}); } } } - + //如果前两个if都没成功的话,就会返回原始的dbConfig对象 + //返回数据库配置对象 return dbConfig; } diff --git a/ghost/core/core/server/data/exporter/export-filename.js b/ghost/core/core/server/data/exporter/export-filename.js index c2564d9..4e997e3 100644 --- a/ghost/core/core/server/data/exporter/export-filename.js +++ b/ghost/core/core/server/data/exporter/export-filename.js @@ -1,32 +1,70 @@ +/** + * 数据库导出文件名生成模块 + * + * 负责为 Ghost 数据库备份文件生成智能、安全的文件名 + * 文件名格式:{站点标题}.ghost.{时间戳}.json + * + * @module exporter/export-filename + */ + const _ = require('lodash'); const logging = require('@tryghost/logging'); const errors = require('@tryghost/errors'); const security = require('@tryghost/security'); const models = require('../../models'); +/** + * 数据库模型查询选项配置 + * 使用内部上下文权限访问设置数据 + */ const modelOptions = {context: {internal: true}}; +/** + * 生成数据库导出文件的文件名 + * + * 文件名生成规则: + * 1. 如果提供了自定义文件名,直接使用 + * 2. 否则生成格式:{站点标题}.ghost.{年-月-日-时-分-秒}.json + * 3. 包含安全过滤和错误处理机制 + * + * @param {Object} [options] - 配置选项 + * @param {string} [options.filename] - 自定义文件名(不含后缀) + * @param {Object} [options.transacting] - 事务对象 + * @returns {Promise} 生成的完整文件名(包含 .json 后缀) + * + */ const exportFileName = async function exportFileName(options) { + // 生成当前时间戳,格式:年-月-日-时-分-秒 const datetime = require('moment')().format('YYYY-MM-DD-HH-mm-ss'); - let title = ''; + let title = ''; // 站点标题部分,默认为空 + // 确保 options 参数不为空 options = options || {}; - - // custom filename - if (options.filename) { + + if (options.filename) { //对文件名进行处理 return options.filename + '.json'; } try { - const settingsTitle = await models.Settings.findOne({key: 'title'}, _.merge({}, modelOptions, _.pick(options, 'transacting'))); + /** + * 从数据库查询站点标题设置 + * 使用内部权限上下文,支持事务传递 + */ + const settingsTitle = await models.Settings.findOne( + {key: 'title'}, + _.merge({}, modelOptions, _.pick(options, 'transacting')) + ); - if (settingsTitle) { - title = security.string.safe(settingsTitle.get('value')) + '.'; + // 如果成功获取到站点标题,进行安全过滤处理 + if (settingsTitle) { + title = security.string.safe(settingsTitle.get('value')) + '.'; //对站点标题进行安全性过滤,移除一些可能会出问题的字符 } - return title + 'ghost.' + datetime + '.json'; - } catch (err) { - logging.error(new errors.InternalServerError({err: err})); + return title + 'ghost.' + datetime + '.json'; //返回完整的文件名格式 + } catch (err) { + logging.error(new errors.InternalServerError({err: err})); //错误处理机制,记录错误日志 + + // 错误情况下返回默认文件名:ghost.{时间戳}.json return 'ghost.' + datetime + '.json'; } }; diff --git a/ghost/core/core/server/data/schema/commands.js b/ghost/core/core/server/data/schema/commands.js index d0ed9f4..e46d977 100644 --- a/ghost/core/core/server/data/schema/commands.js +++ b/ghost/core/core/server/data/schema/commands.js @@ -301,7 +301,7 @@ async function dropUnique(tableName, columns, transaction = db.knex) { }); } catch (err) { if (err.code === 'SQLITE_ERROR') { -logging.warn(`Constraint for '${columns}' does not exist for table '${tableName}'`); + logging.warn(`Constraint for '${columns}' does not exist for table '${tableName}'`); return; } if (err.code === 'ER_CANT_DROP_FIELD_OR_KEY') { diff --git a/ghost/core/core/server/data/schema/default-settings/index.js b/ghost/core/core/server/data/schema/default-settings/index.js index b83d391..bf6eb87 100644 --- a/ghost/core/core/server/data/schema/default-settings/index.js +++ b/ghost/core/core/server/data/schema/default-settings/index.js @@ -4,3 +4,4 @@ const defaultSettingsPath = config.get('paths').defaultSettings; const defaultSettings = require(defaultSettingsPath); module.exports = defaultSettings; +//一些默认配置文件 \ No newline at end of file diff --git a/ghost/core/core/server/data/schema/fixtures/FixtureManager.js b/ghost/core/core/server/data/schema/fixtures/FixtureManager.js index a763cdf..81fa194 100644 --- a/ghost/core/core/server/data/schema/fixtures/FixtureManager.js +++ b/ghost/core/core/server/data/schema/fixtures/FixtureManager.js @@ -1,4 +1,4 @@ -const _ = require('lodash'); +const _ = require('lodash'); //引入lodash库,用于处理数组、对象等数据结构 const logging = require('@tryghost/logging'); const {sequence} = require('@tryghost/promise');