我试图编写一个基本的cron脚本来运行和“转储”一个mysql数据库。由于某种原因,当“成功保存文件”时,它会创建文件,但是它为空。如果执行保存console.log而不是保存文件,它将打印一个空字符串。对我可能做错的事情有任何想法吗?
提前致谢。
var mysql_backup = function(){
this.backup = '';
this.mysql = require('mysql'),
this.init = function(){
this.connection = this.mysql.createConnection({
user: 'root',
password: 'root',
database: 'test'
});
}
this.query = function(sql, callback) {
this.connection.query(sql, function (error, results, fields) {
if (error) {
throw error;
}
if (results.length > 0) {
callback(results);
}
});
}
this.get_tables = function(callback){
var me = this;
me.query('SHOW TABLES',
function(tables) {
for (var table in tables){
me.query(
'SHOW CREATE TABLE ' + tables[table].Tables_in_test,
function(r){
for (var t in r) {
me.backup += "DROP TABLE " + r[t].Table + "\n\n";
me.backup += r[t]["Create Table"] + "\n\n";
}
}
)
}
me.save_backup();
});
}
this.save_backup = function(){
var fs = require('fs');
fs.writeFile("./backup_test.txt", this.backup, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
}
};
var db = new mysql_backup;
db.init();
db.get_tables();
db.connection.destroy();
编写的代码甚至都没有保存到我的文件中。似乎有一些问题。不知道这是实际的代码还是某些内容丢失在复制粘贴中。但是,根据您所拥有的:
一个很大的问题是,您永远不会使用connection.connect()连接到代码中的数据库。
连接后要运行的代码应位于connection.connect()回调内部。例如
connection.connect(function (err, empty) {
if (err)
throw new Error ('Panic');
// if no error, we are off to the races...
}
但是,即使您快速重构代码以将最后几行换行到该get连接回调中,您仍然会遇到问题,因为在进行各种SQL调用之前您正在销毁连接,因此您将需要移动代码进入某种最终回调。
即使这样做了,您仍然会有一个空文件,因为您是从“ SHOW
TABLES”回调中调用save_backup,而不是通过内部回调实际填充它之后,在内部回调中您会获得CREATE TABLE语句并填充备份属性。
这是对代码的最小重写,可以完成您的预期工作。要注意的重要事项是“计数器”,它管理何时写入文件和关闭连接。如果属于我,我会进行其他更改,包括:
希望这会有所帮助。
var mysql_backup = function(){
this.backup = '';
this.mysql = require('mysql');
this.init = function(){
this.connection = this.mysql.createConnection({
user : 'root',
password : 'root',
database : 'test'
});
};
this.query = function(sql, callback) {
this.connection.query(sql, function (error, results, fields) {
if (error) {
throw error;
}
if (results.length > 0) {
callback(results);
}
});
};
this.get_tables = function(callback){
var counter = 0;
var me = this;
this.query('SHOW TABLES',
function(tables) {
for (table in tables){
counter++;
me.query(
'SHOW CREATE TABLE ' + tables[table].Tables_in_mvc,
function(r){
for (t in r) {
me.backup += "DROP TABLE " + r[t].Table + "\n\n";
me.backup += r[t]["Create Table"] + "\n\n";
}
counter--;
if (counter === 0){
me.save_backup();
me.connection.destroy();
}
}
)
}
});
};
this.save_backup = function(){
var fs = require('fs');
fs.writeFile("./backup_test.txt", this.backup, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
}
};
var db = new mysql_backup;
db.init();
db.connection.connect(function (err){
if (err) console.log(err);
db.get_tables(function(x){;});
});
更新:如果您感到好奇,这是一个使用Promise进行了广泛评论的实现。请注意,由于没有说明Q承诺库功能的注释,它比原始版本要短一些,并且还提供了更全面的错误处理。
var MysqlBackup = function(connectionInfo, filename){
var Q = require('q');
var self = this;
this.backup = '';
// my personal preference is to simply require() inline if I am only
// going to use something a single time. I am certain some will find
// this a terrible practice
this.connection = require('mysql').createConnection(connectionInfo);
function getTables(){
// return a promise from invoking the node-style 'query' method
// of self.connection with parameter 'SHOW TABLES'.
return Q.ninvoke(self.connection,'query', 'SHOW TABLES');
};
function doTableEntries(theResults){
// note that because promises only pass a single parameter around,
// if the 'denodeify-ed' callback has more than two parameters (the
// first being the err param), the parameters will be stuffed into
// an array. In this case, the content of the 'fields' param of the
// mysql callback is in theResults[1]
var tables = theResults[0];
// create an array of promises resulting from another Q.ninvoke()
// query call, chained to .then(). Note that then() expects a function,
// so recordEntry() in fact builds and returns a new one-off function
// for actually recording the entry (see recordEntry() impl. below)
var tableDefinitionGetters = [];
for (var i = 0; i < tables.length ; i++){
// I noticed in your original code that your Tables_in_[] did not
// match your connection details ('mvc' vs 'test'), but the below
// should work and is a more generalized solution
var tableName = tables[i]['Tables_in_'+connectionInfo.database];
tableDefinitionGetters.push(Q.ninvoke(self.connection, 'query', 'SHOW CREATE TABLE ' + tableName)
.then(recordEntry(tableName)) );
}
// now that you have an array of promises, you can use Q.allSettled
// to return a promise which will be settled (resolved or rejected)
// when all of the promises in the array are settled. Q.all is similar,
// but its promise will be rejected (immediately) if any promise in the
// array is rejected. I tend to use allSettled() in most cases.
return Q.allSettled(tableDefinitionGetters);
};
function recordEntry (tableName){
return function(createTableQryResult){
self.backup += "DROP TABLE " + tableName + "\n\n";
self.backup += createTableQryResult[0][0]["Create Table"] + "\n\n";
};
};
function saveFile(){
// Q.denodeify return a promise-enabled version of a node-style function
// the below is probably excessively terse with its immediate invocation
return (Q.denodeify(require('fs').writeFile))(filename, self.backup);
}
// with the above all done, now you can actually make the magic happen,
// starting with the promise-return Q.ninvoke to connect to the DB
// note that the successive .then()s will be executed iff (if and only
// if) the preceding item resolves successfully, .catch() will get
// executed in the event of any upstream error, and finally() will
// get executed no matter what.
Q.ninvoke(this.connection, 'connect')
.then(getTables)
.then(doTableEntries)
.then(saveFile)
.then( function() {console.log('Success'); } )
.catch( function(err) {console.log('Something went awry', err); } )
.finally( function() {self.connection.destroy(); } );
};
var myConnection = {
host : '127.0.0.1',
user : 'root',
password : 'root',
database : 'test'
};
// I have left this as constructor-based calling approach, but the
// constructor just does it all so I just ignore the return value
new MysqlBackup(myConnection,'./backup_test.txt');
我得到了错误 我在文件夹中执行此操作。当我在另一台计算机上运行相同的命令时,一切都很好。问题是什么?
没笔试 1月2号面的 现在还没回信 大概率挂了 1、先介绍了一下项目 2、C++面向对象的三大特性 3、虚函数的理解 4、两个子类继承同一个父类和一个子类继承两个父类有区别吗? 5、QT的信号和槽的原理? 6、信号和槽连接的第五个参数? 7、IO多路复用 8、介绍一下TCP和UDP协议? 9、视频聊天用的是什么协议? 10、TCP协议是如何保证可靠性传输的? 11、两个线程之间如何进行通信? 12
一个数组基本有序应该采用哪种排序方法 为什么要有线程池 ,线程太多会怎么样?? 阻塞队列与普通队列的区别是? 递归与非递归区别是什么?各自的优缺点? 递归如何转为非递归? 操作系统为什么会有内核态和用户态? 代码编写中什么操作会触发内核态到用户态的转变? python c++ java各自的执行效率为什么会有差别? 腾讯会议打开了,现在又点击会提示已经打开,这怎么实现的? 腾讯会议语音传输用的是哪
按照Patrick Dubroy的指南,我试图将堆转储转换为J2SE HPROF,但无法执行。这很奇怪,因为它位于文件夹中。 怎么解决这个?
1、变量提升,let,const,var,暂时性死区 2、函数是否存在变量提升? 3、react组件间通信 4、防抖,节流 5、浏览器跨域,跨域产生的原因,怎么解决? 6、浏览器存储,cookie,sessionstorage,localstorage的区别和应用场景? 7、[]==![]输出? 8、其他几道输出题 9、水平垂直居中方法 10、判断数据类型的方法?instanceof和typeof
1. 聊一下你知道的Java中的锁 2. synchronized的底层原理,为什么synchronized能够保证可见性、有序性、原子性。AQS的底层原理,CAS的底层原理。 3. 线程池:核心参数、工作流程、参数如何定义,还有最大线程池是如何销毁的 4. Redis常用数据类型的底层数据结构,跳跃表的介绍、优点等等 5. Redis的集群说一下 6. Redis分布式说一下,为什么要用Lua脚