On Github marlic7 / warsawjs-nodejs-and-oracle
Ruby Python Java Go Erlang Scala ???
Node.js
Projekt w Github: joeferner/node-oracle
oficjalnie jeszcze nie wspierany (jest procesowany PR)
instalacja z forka:npm install https://github.com/Bigous/node-oracledb.git
wczoraj tj. 17.11.2015 wydany release node-oracledb@1.4.0 Node.js 0.10, 0.12, 4.2 i 5.0
https://www.npmjs.com/package/node-dal https://github.com/marlic7/node-dal
Teraz poprzez przykłady omówię wybrane (ważniejsze) problemy, z którymi zetknąłem się realizując 2 projekty.
pool.getConnection(function(err, connection) {
    if (err) {
        cb(new Error(err));
        return;
    }
    connection.execute('SELECT SYSDATE FROM DUAL',
                       [],
                       function(err, result) {
        if (err) {
            cb(new Error(err));
            connection.release(function(err) {
                if (err) {
                    cb(new Error(err), {only_log: true});
                }
            });
            return;
        }
        cb(null, result.rows[0][0]);
        connection.release(function(err) {
            if (err) {
                cb(new Error(err), {only_log: true});
            }
        });
    });
});
    1. pobranie połączenia z puli (j. błąd to cb i return)
    2. wywołanie SQL (j. błąd to cb, zwolnienie połączenia do puli (z obsługą błędu) i return)
    3. zwolnienie połączenia do puli i przekazanie wyniku zapytania do głównego cb
dal.selectOneValueSql('SELECT SYSDATE FROM DUAL', [],
                      function(err, result) {
    if(err) {
        cb(new Error(err));
        return;
    }
    cb(null, result);
});
lub
dal.selectOneValue('DUAL', 'SYSDATE', [], function(err, result) {
    if(err) {
        cb(new Error(err));
        return;
    }
    cb(null, result);
});
var oracledb = require('oracledb');
oracledb.maxRows = 100; // (wartość domyślna)
connection.execute("SELECT * FROM employees", [], { maxRows: 1000 },
                   function(err, result) {
    // result.rows.length <= 1000
});
    maxRows - maksymalna liczba wierszy pobieranych przez execute()
    (gdy nie jest używany ResultSet). Wiersze powyżej tego limitu
    nie są pobierane.
    globalne zwiększenie tego limitu powoduje większą alokację pamięci na
    poziomie C++ dla każdego execute()
var oracledb = require('oracledb');
oracledb.prefetchRows = 100; // (wartość domyślna)
connection.execute("SELECT * FROM employees", [],
                   { resultSet: true, prefetchRows: 200 },
                   function(err, result) {
    var allRows = [];
    function fetch() {
        var max = 200;
        result.resultSet.getRows(max, function(err, rows) {
            allRows = allRows.concat(rows);
            if (rows.length === max) {
                fetch();
            } else {
                result.resultSet.close(function(err) {
                    connection.release(function(err) {
                        cb(null, allRows);
                    });
                });
            }
        });
    }
    fetch();
});
przykład bez obsługi błędów - dla przejrzystości
    resultSet - używać gdy nie wiemy ile wierszy może być zwrócone, albo wiemy ale
    może się to zmieniać w czasie. Używać gdy potrzeba pobrać dużą liczbę wierszy.
    Wtedy optymalnie jest wykorzystać przetwarzanie strumieniowe.
    przykład: fetch 200 wierszy, preparacja wyjścia csv i flush chunk-a do CSV
    można też bez strumieni, jeżeli wierszy nie ma bardzo dużo i chcemy po prostu pobrać wszystkie (next slide)
dal.selectAllRowsSql("SELECT * FROM employees", [],
                     function(err, result) {
    cb(null, allRows);
});
lub
dal.selectAllRows({
    tbl: 'employees',
    opt: { limit:10, page:5 },
    cb:  function(err, results) {
        cb(null, results);
    }
});
var async    = require('async'),
    oracledb = require('oracledb'),
    cfg  = {
        user:           "username",
        password:       "password",
        connectString:  "localhost/XE",
        poolMax:        10,
        poolMin:        2
    },
    sqls = [],
    i    = 15;
while(i--) { sqls.push('SELECT SYSDATE FROM DUAL'); }
oracledb.createPool(cfg, function(err, pool) {
    var executeSql = function(sql, cb) {
        pool.getConnection(function(err, connection) {
            connection.execute(sql, [], function(err, results) {
                cb(null, results.rows[0][0]);
            });
        });
    };
    async.map(sqls, executeSql, function(err, results) {
        callback(null, results);
    });
});
Wynik: ORA-24418: Nie można otworzyć kolejnych sesji.
przykłady bez obsługi błędów oraz bez zwalniania połączenia do puli - dla przejrzystości Wbudowana pula w driver natywny oracledb nie posiada aktualnie mechanizmów kolejki. Próba pobrania połączenia z puli w systuacji gdy wszystie połączenia pracują, kończy się niepowodzeniem.var async      = require('async'),
    dalFactory = require('node-dal'),
    cfg        = {
        connection: {
            user:           "testy",
            password:       "testy123",
            connectString:  "localhost/XE",
            poolMax:        10,
            poolMin:        1
        },
        getConnMaxProbes:   100, // times
        getConnWaitMinTime: 200, // miliseconds
        getConnWaitMaxTime: 500  // miliseconds
    },
    sqls = [],
    i    = 15;
while(i--) { sqls.push('SELECT SYSDATE FROM DUAL'); }
dalFactory('oracledb', cfg, function(err, dal) {
    var executeSql = function(sql, cb) {
        dal.selectOneValueSql(sql, [], function(err, result) {
            cb(null, result);
        });
    };
    async.map(sqls, executeSql, function(err, results) {
        callback(null, results);
    });
});
Wynik: [data1, data2, ... , data15]
przykłady bez obsługi błędów - dla przejrzystości brakuje tylko obsługi błędów, w tym przypadku nie trzeba zwracać połącenia do puliOWA - PL/SQL Web Toolkit APEX - Oracle Application Express
process.env.UV_THREADPOOL_SIZE = 4; // Node.js default value
process.env.UV_THREADPOOL_SIZE = 10;
Any application that can be written in JavaScript, will eventually be written in JavaScript.
Jeff Atwood, the founder of stackoverflow.com Put your speaker notes here. You can see them pressing 's'.