Kode seperti yang tertulis bahkan tidak sampai ke file yang disimpan untuk saya. Sepertinya ada beberapa masalah. Tidak yakin apakah ini kode yang sebenarnya atau ada yang hilang dalam salin tempel. Namun, berdasarkan apa yang Anda dapatkan:
Masalah besar adalah Anda tidak pernah terhubung ke database dalam kode Anda dengan connection.connect().
Kode yang ingin Anda jalankan setelah terhubung harus berada di dalam callback connection.connect(). misalnya
connection.connect(function (err, empty) {
if (err)
throw new Error ('Panic');
// if no error, we are off to the races...
}
Namun, bahkan jika Anda dengan cepat memfaktorkan ulang kode Anda untuk membungkus baris terakhir Anda di dalamnya yang mendapatkan panggilan balik koneksi, Anda masih akan mengalami masalah, karena Anda menghancurkan koneksi sebelum berbagai panggilan SQL dibuat, jadi Anda ingin memindahkan kode menjadi semacam panggilan balik terakhir.
Bahkan setelah Anda melakukannya, Anda masih akan memiliki file kosong, karena Anda memanggil save_backup dari panggilan balik 'SHOW TABLES' daripada setelah Anda benar-benar mengisinya melalui panggilan balik bagian dalam tempat Anda mendapatkan pernyataan CREATE TABLE dan mengisi properti cadangan.
Ini adalah penulisan ulang minimal kode Anda yang akan melakukan apa yang Anda inginkan. Hal penting yang perlu diperhatikan adalah "penghitung" yang mengatur kapan harus menulis file dan menutup koneksi. Saya akan membuat perubahan lain jika itu milik saya, termasuk:
- Menggunakan 'diri' bukan 'saya'
- Menggunakan loop for numerik daripada sintaks for (... in ...)
- Mendapatkan callback saya sendiri termasuk dalam konvensi simpul (err, stuff)
- Perubahan yang lebih substansial adalah saya akan menulis ulang ini untuk menggunakan janji, karena hal itu dapat menghindarkan Anda dari kesedihan dengan kebingungan yang melekat pada panggilan balik yang sangat bersarang. Saya pribadi menyukai pustaka Q, tetapi ada beberapa opsi di sini.
Semoga membantu.
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){;});
});
Pembaruan:Jika Anda penasaran, berikut adalah implementasi yang banyak dikomentari menggunakan janji. Perhatikan bahwa tanpa komentar yang menjelaskan fungsi perpustakaan janji Q, ini agak lebih pendek dari versi aslinya dan juga menawarkan penanganan kesalahan yang lebih komprehensif.
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');