sql >> データベース >  >> RDS >> Mysql

NodeJSMySQLダンプ

    書かれたコードは、私のためにファイルを保存することすらできませんでした。いくつかの問題があるようです。これが実際のコードなのか、コピーペーストで失われたものなのかわからない。ただし、入手したものに基づいて:

    大きな問題は、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 connectionコールバック内の最後の行をラップしても、さまざまなSQL呼び出しが行われる前に接続を破棄しているため、問題が発生します。そのため、ある種の最終的なコールバックにコードを記述します。

    それを行った後でも、CREATE TABLEステートメントを取得してデータを入力する内部コールバックを介して実際にデータを入力した後ではなく、「SHOW TABLES」コールバックからsave_backupを呼び出しているため、空のファイルが残ります。バックアッププロパティ。

    これは、意図したとおりに実行されるコードの最小限の書き換えです。注意すべき重要なことは、ファイルを書き込んで接続を閉じるタイミングを管理する「カウンター」です。それが私のものであれば、次のような他の変更を加えます。

    • 「私」の代わりに「自己」を使用する
    • for(... in ...)構文ではなく数値のforループを使用する
    • 自分のコールバックを持つことは、(err、stuff)のノード規則に該当します
    • より重要な変更は、promiseを使用するようにこれを書き直すことです。そうすることで、深くネストされたコールバックに固有の混乱に苦しむことがなくなります。私は個人的にQライブラリが好きですが、ここにはいくつかのオプションがあります。

    これがお役に立てば幸いです。

    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を使用したコメントの多い実装を次に示します。 Qpromiseライブラリ関数を説明するコメントがないため、元のバージョンよりもいくらか短く、より包括的なエラー処理も提供されることに注意してください。

    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. OracleのNUMTOYMINTERVAL()関数

    2. OracleDatabaseのFORALLステートメントの概要

    3. EM12cデータベースの待機アラートの使用時間

    4. MySQLでのTRIM()関数のしくみ