Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FBblob::EIO_After_Read - invalid BLOB handle #80

Open
mreis1 opened this issue Oct 3, 2017 · 4 comments
Open

FBblob::EIO_After_Read - invalid BLOB handle #80

mreis1 opened this issue Oct 3, 2017 · 4 comments
Labels

Comments

@mreis1
Copy link

mreis1 commented Oct 3, 2017

I'm trying to push a blob to my database but until now I couldn't figure out what's going wrong.

For example:
Having an open connection named tx.

# Sample Text Blob 
let d = tx.newBlobSync();
d._write(new Buffer('Hello World'), function (err) {
    console.log(err) **//<--- FBblob::EIO_After_Read - invalid BLOB handle**
    let ff = tx.prepareSync('update table set logo = ?'); //
    ff.execSync(d);
    tx.commitSync();
    tx.disconnect();
});
# Image Blob 
let d = tx.newBlobSync();
var data = fs.readFileSync(filePath);
d._write(data, function (err) {
    console.log(err) //<--- FBblob::EIO_After_Read - invalid BLOB handle
    let ff = tx.prepareSync('update table set logo = ?'); //
    ff.execSync(d);
    tx.commitSync();
    tx.disconnect();
});

Both Return the exactly same error.
FBblob::EIO_After_Read - invalid BLOB handle

var data = fs.readFileSync(filePath);
d._write(data, data.length, function (err) {
    console.log(err)
    let ff = tx.prepareSync('update table set logo = ?'); //
    ff.execSync(d);
    tx.commitSync();
    tx.disconnect();
});

Using _writeSync


let d = tx.newBlobSync();
var data = fs.readFileSync(filePath);
try {
    d._writeSync(data, data.length);
} catch (e){
    console.log(e); // <---- a) **Error: In FBblob::_writeSync - invalid BLOB handle**
}

try {
    let ff = tx.prepareSync('update table set logo = ?');
    ff.execSync(d);
} catch (e){
    console.log(e); // <---- b) **Error: In FBStatement::execSync - BLOB not found** 
}

tx.commitSync();
tx.disconnect();



b) Since we got the error a) naturally b failed since the FBblob was empty


@xdenser
Copy link
Owner

xdenser commented Oct 3, 2017

probably you have not started transaaction in connection,
i see a couple of bugs here :

  1. Error message is wrong :EIO_After_Read should be:EIO_After_Write
  2. newBlobSync should throw an exception if there is no active transaction

@xdenser xdenser added the bug label Oct 3, 2017
@mreis1
Copy link
Author

mreis1 commented Oct 3, 2017

You are right @xdenser, I confused one of the particularities of the lib where a new transaction is only created upon call to con.query(....

Now I updated to code to ensure that a startNewTransaction is called but _writeSync() still throws invalid BLOB handle.

con.startNewTransaction(function(err, tx){
    if (err){
        throw err;
    }

    console.log({
        inTransaction: tx.inTransaction   // outputs { inTransaction: true }
    });
    
    let d = con.newBlobSync();
    let myFileData = fs.readFileSync(filePath);

    try {
        d._writeSync(myFileData);  // **<---- Error: In FBblob::_writeSync - invalid BLOB handle**
        writeToDatabase();
    } catch (e){
        console.log(e);
        tx.commitSync();
        tx.disconnect();
    }

    function writeToDatabase(){
        try {
            let ff = tx.prepareSync('update table set logo = ?');
            ff.execSync(d);
            tx.commitSync();
            tx.disconnect();
        } catch (e){
            console.log(e);
        }
    }
})

@xdenser
Copy link
Owner

xdenser commented Oct 3, 2017

Still getting error ? this is trange
try to use approach as in the test

@mreis1
Copy link
Author

mreis1 commented Oct 3, 2017

@xdenser Thanks for the tip. I hadn't noticed the blob test in the tests folder.
Following the same procedure worked like a charm.

FirebirdManager.pool.get()
    .then((tx) => {
        let ff = tx.prepareSync('update table set logo = ?'); 
        let d = tx.newBlobSync();
        let strm = new fb.Stream(d);
        let logoStrm = fs.createReadStream(filePath);

        logoStrm.pipe(strm);

        strm.on('close', function () {
            writeToDatabase();
        });

        strm.on('error', function (err) {
            console.log('error in write blob stream ', err);
        });

        logoStrm.on('end', writeToDatabase);

        function writeToDatabase() {
            try {
                ff.execSync(strm._blob);
                tx.commitSync();
                tx.disconnect();
            } catch (e) {
                console.log(e);
            }
        }
    })
    .catch(err => reject(err));

I noticed that con.prepareSync() must be called before creating the FBblob, so it will start the required transaction. But If I don't use the stream approach and if I try to write to the FBblob as show below (execSync(myBlob)) this will simply throw FBStatement::execSync - invalid BLOB ID

return new Promise((resolve, reject) => {
        FirebirdManager.pool.get()
            .then((tx) => {
                let ff = tx.prepareSync('update table set logo = ?');
                let d = tx.newBlobSync();
                let dataBuffer = fs.readFileSync(filePath);

                d._writeSync(dataBuffer);
                save(); 
                
                // or in async
                // d._write(dataBuffer, function(err){
                //     if (err){
                //         return rollback();
                //     }
                //     save();
                // });

                function save(){
                    try {
                        ff.execSync(d);
                        tx.commitSync();
                        tx.disconnect();
                        resolve();
                    } catch (e){
                       rollback(e); //<-------- In FBStatement::execSync - invalid BLOB ID
                    }

                }
                function rollback(e){
                    tx.rollbackSync();
                    tx.disconnect();
                    reject(e);
                }

            })
            .catch(err => reject(err));
    });

By the way, I forked the project and I did run all the tests.

test-events
....
✖ TensOfEvents

Assertion Message: We have 100 events
AssertionError: false == true
FAILURES: 1/740 assertions failed (469276ms)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants