sql >> Databáze >  >> RDS >> Mysql

NodeJS MySQL výpis

Kód tak, jak byl napsán, se mi ani nedostal do souboru, který se ukládá. Zdá se, že existuje několik problémů. Nejste si jisti, zda se jedná o skutečný kód nebo se některé věci ztratily při kopírování. Nicméně na základě toho, co máte:

Velkou výhodou je, že se nikdy nepřipojujete k databázi ve svém kódu pomocí connection.connect().

Kód, který chcete spustit po připojení, by měl být uvnitř zpětného volání connection.connect(). např.

connection.connect(function (err, empty) {
    if (err)
        throw new Error ('Panic');

    // if no error, we are off to the races...
}

I když však rychle přefaktorujete svůj kód tak, aby zalomil poslední řádky uvnitř tohoto zpětného volání spojení, stále budete mít problémy, protože zničíte spojení dříve, než budou provedena různá volání SQL, takže budete chtít přesunout kód do nějakého konečného zpětného volání.

I poté, co to uděláte, budete mít stále prázdný soubor, protože voláte save_backup ze zpětného volání 'SHOW TABLES' spíše než poté, co jste jej skutečně naplnili prostřednictvím vnitřního zpětného volání, kde získáte příkaz CREATE TABLE a naplníte zálohovací vlastnost.

Toto je minimální přepis vašeho kódu, který udělá to, co zamýšlíte. Důležitá věc, kterou je třeba poznamenat, je "počítadlo", které řídí, kdy zapsat soubor a ukončit připojení. Udělal bych další změny, kdyby to bylo moje, včetně:

  • Použití slova „já“ místo „já“
  • Použití numerické smyčky for namísto syntaxe for (... v ...)
  • Má vlastní zpětná volání spadá do konvence uzlů (chyba, věci)
  • Podstatnější změnou je, že bych to přepsal tak, aby používal sliby, protože vám to může ušetřit trochu zármutku se zmatkem, který je vlastní hluboce vnořeným zpětným voláním. Osobně se mi knihovna Q líbí, ale zde je několik možností.

Doufám, že to pomohlo.

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){;});

});

Aktualizace:Pokud jste zvědaví, zde je silně komentovaná implementace pomocí slibů. Všimněte si, že bez komentářů vysvětlujících funkce knihovny Q slib je o něco kratší než původní verze a také nabízí komplexnější řešení chyb.

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. Průvodce PGpool - Rady a postřehy:Část třetí

  2. SQL Data Definition Language

  3. Chyba syntaxe tabulky Postgres

  4. Funkce Concat nefunguje - neplatný počet argumentů