Der geschriebene Code hat nicht einmal eine Dateispeicherung für mich erreicht. Es scheint ein paar Probleme zu geben. Ich bin mir nicht sicher, ob dies der tatsächliche Code ist oder einige Dinge beim Kopieren und Einfügen verloren gegangen sind. Basierend auf dem, was Sie haben:
Eine große Sache ist, dass Sie in Ihrem Code niemals mit connection.connect() eine Verbindung zur Datenbank herstellen.
Der Code, den Sie ausführen möchten, sobald die Verbindung hergestellt ist, sollte sich innerhalb des callbacks connection.connect() befinden. zB
connection.connect(function (err, empty) {
if (err)
throw new Error ('Panic');
// if no error, we are off to the races...
}
Aber selbst wenn Sie Ihren Code schnell umgestalten, um Ihre letzten Zeilen innerhalb dieses Get-Verbindungsrückrufs einzuschließen, werden Sie immer noch Probleme haben, weil Sie die Verbindung zerstören, bevor die verschiedenen SQL-Aufrufe getätigt werden, also sollten Sie die verschieben Code in eine Art abschließenden Callback.
Selbst nachdem Sie das getan haben, haben Sie immer noch eine leere Datei, weil Sie save_backup von Ihrem 'SHOW TABLES'-Callback aufrufen und nicht, nachdem Sie es tatsächlich über den inneren Callback gefüllt haben, wo Sie die CREATE TABLE-Anweisung erhalten und die Sicherungseigenschaft.
Dies ist das minimale Umschreiben Ihres Codes, der das tut, was Sie beabsichtigen. Eine wichtige Sache, die zu beachten ist, ist der "Zähler", der verwaltet, wann die Datei geschrieben und die Verbindung geschlossen werden soll. Ich würde andere Änderungen vornehmen, wenn es meine wäre, einschließlich:
- Verwendung von „self“ statt „me“
- Verwendung einer numerischen for-Schleife anstelle der for (... in ...)-Syntax
- Meine eigenen Callbacks fallen unter die Knotenkonvention von (err, stuff)
- Eine wesentlichere Änderung ist, dass ich dies umschreiben würde, um Versprechungen zu verwenden, da Ihnen dies etwas Kummer über die Verwirrung ersparen kann, die tief verschachtelten Rückrufen innewohnt. Ich persönlich mag die Q-Bibliothek, aber hier gibt es mehrere Optionen.
Hoffe, das hat geholfen.
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){;});
});
Update:Wenn Sie neugierig sind, finden Sie hier eine stark kommentierte Implementierung mit Versprechungen. Beachten Sie, dass sie ohne die Erläuterungen der Funktionen der Q Promise-Bibliothek etwas kürzer ist als die Originalversion und auch eine umfassendere Fehlerbehandlung bietet.
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');