pull/2/head
ws 3 months ago
parent 6a759f8310
commit 2da99f65bb

@ -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<String> | 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;
}

@ -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;
}

@ -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<string>} 生成的完整文件名包含 .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';
}
};

@ -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') {

@ -4,3 +4,4 @@ const defaultSettingsPath = config.get('paths').defaultSettings;
const defaultSettings = require(defaultSettingsPath);
module.exports = defaultSettings;
//一些默认配置文件

@ -1,4 +1,4 @@
const _ = require('lodash');
const _ = require('lodash'); //引入lodash库用于处理数组、对象等数据结构
const logging = require('@tryghost/logging');
const {sequence} = require('@tryghost/promise');

Loading…
Cancel
Save