vendredi 25 septembre 2015

Inserting numerous rows in Cordova SQLitePLugin uses all the memory in hybrid app

I am trying to save email messages that also contain attachments for offline use, using Cordova SQLitePlugin in my hybrid app. After about 4000 transactions, the insertion stops and the app freezes. I realized that it uses all the memory on the iphone. Doing different tests, I realized that if I was not saving the attachments I could insert 20000 rows successfully. Can someone see my code and tell me if I have a memory leak somewhere, or how can I bypass this problem? I want to be able to save about 20000 rows with the table that holds the attachments. The attachments are of maximum size 2mb each.

Below is my code:

 function _syncBegin() {
    _lastBookmark = localStorage.BookmarkForOfflineMessage;
    _countMessages = 0;
    _ensureDbInited(function () {
        if (_lastBookmark === '') {
            app.dbSqlite.transaction(function (tx) {
                tx.executeSql('DROP TABLE if exists offlineMessageAttachments', [], function (transaction, results) {
                }, function (error) {
                    alert('3' + JSON.stringify(error));
                    _onError(error.message);
                });
            });
            app.dbSqlite.transaction(function (tx) {
                tx.executeSql('DROP TABLE if exists offlineMessage', [], function (transaction, results) {
                    _createOfflineAddressTableIfNotExist(_fetchNextBatch);
                }, function (error) {
                    alert('4' + JSON.stringify(error));
                    _onError(error.message);
                });
            });
        } else {
            _fetchNextBatch();
        }
    });
}
function _createOfflineAddressTableIfNotExist(callback) {
    app.dbSqlite.transaction(function (tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS offlineMessageAttachments (' +
            'idRow INTEGER PRIMARY KEY AUTOINCREMENT, ' +
            'idMessage INTEGER,' +
            'orderAttc INTEGER,' +
            'name TEXT,' +
            'sizeAttch INTEGER,' +
            'attachment BLOB' +
            ')', [], function (transaction, results) {
            }, function (error) {
                alert('1' + JSON.stringify(error));
                _onError(error.message);
            });

            tx.executeSql('CREATE TABLE IF NOT EXISTS offlineMessage (' +
            'idRow INTEGER PRIMARY KEY,' +
            'date DATE,' +
            'subject TEXT,' +
            'fromAddr TEXT,' +
            'toAddr TEXT,' +
            'bcc TEXT,' +
            'cc TEXT,' +
            'body TEXT' +
            ')', [], function (transaction, results) {
                callback();
            }, function (error) {
                alert('2' + JSON.stringify(error));
                _onError(error.message);
            });
    });
}

function _fetchNextBatch() {

    function processNewMessageData(data) {
        if (data.Messages.length === 0 ) {
            _batchProcessed(true);
        } else {
             localStorage.BookmarkForOfflineMessage = data.Bookmark;
             _processor = new OfflineMessagesBatch(data.Messages, _fetchNextBatch);
             _lastBookmark = data.Bookmark;
        }
    }
    if (_countMessages != _pageSize) {

        $.ajax({
            url: 'http://common-domain/Message?',
            type: 'GET',
            dataType: 'json',
            beforeSend: function (req, options) {

                options.url += 'bookmark=' + localStorage.BookmarkForOfflineMessage + '&count=' + _pageSize + '&dateSeps=false&search[0][FieldName]=HasAttachments&search[0]' +
                '[Operation]=EqualTo&search[0][Value]=true&search[1][FieldName]=Class&search[1][Operation]=EqualTo&search[1]' +
                '[Value]=Normal&search[2][FieldName]=Size&search[2][Operation]=LessThanOrEqualTo&search[2]' +
                '[Value]=500000&search[3][FieldName]=Type&search[3][Operation]=EqualTo&search[3]' +
                '[Value]=Email'
            },
            success: function (jsonData) {
                if (localStorage.BookmarkForOfflineMessage === '') {
                    app.dbSqlite.transaction(function (tx) {
                        tx.executeSql('delete from offlineMessageAttachments', [], function (transaction, results) {

                        }, function (error) {
                            _onError(error.message);
                        });
                    });
                    app.dbSqlite.transaction(function (tx) {
                        tx.executeSql('delete from offlineMessage', [], function (transaction, results) {
                            _countMessages += _pageSize;
                            processNewMessageData(jsonData);
                        }, function (error) {
                            _onError(error.message);
                        });
                    });
                } else {
                    _countMessages += _pageSize;
                    processNewMessageData(jsonData);
                }
            },
            error: function (responce) {
                _onError(responce.responseText);
            }

        });
    }
}

function OfflineMessagesBatch(data, success) {
    var self = this;
    self.currentIndex = 0;
    processData(data[0]);

    function processData(row) {
        if (typeof row === 'undefined') {
            handleNextItem();
        }
        else {
            $.ajax({
                url: 'http://common-domain/Message?',
                type: 'GET',
                dataType: 'json',
                beforeSend: function (req, options) {
                    options.url += 'id=' + row.ID + '&markRead=false&BODYFORMAT=TEXT&noImages=true&partial=true'
                },
                success: function (newData) {
                    console.log("get message details");
                    app.dbSqlite.transaction(function (tx) {
                        var offlineMessageQuery = 'INSERT INTO offlineMessage (' +
                            'idRow,date,subject,fromAddr,toAddr,bcc,cc, body' +
                            ') VALUES (' +
                            '?,?,?,?,?,?,?,?' +
                            ')';
                       tx.executeSql(offlineMessageQuery,
                            [row.ID, row.Date, row.Subj, newData.FromAddr, JSON.stringify(newData.To), JSON.stringify(newData.Bcc), JSON.stringify(newData.Cc), typeof newData.Body != 'undefined' ? newData.Body.Body : ''], function (transaction, results) {
                                var curIndex = 0;
                                handleNextAttachement();

                                function handleNextAttachement() {
                                    if (curIndex >= newData.Atts.length) {
                                        handleNextItem();
                                        return;
                                    }

                                    processAttachement(newData.Atts[curIndex]);
                                    curIndex++;
                                }

                                function processAttachement(lineRow) {
                                     var request = $.ajax({
                                        url: 'http://common-domain/Message/Attachment?',
                                        type: 'GET',
                                        dataType: 'blob',
                                        beforeSend: function (req, options) {
                                            options.url += 'token=' + localStorage.userToken + '&id=' + row.ID + '&order=' + lineRow.Order + '&embedded=false'
                                        },
                                        success: function (attchData) {
                                          handleNextAttachement();
                                           },
                                        error: function (response) {
                                            console.log("get attachment");
                                            if (response.status == 200) {
                                                app.dbSqlite.transaction(function (sx) {
                                                    var q = 'INSERT INTO offlineMessageAttachments (' +
                                                            'idMessage,orderAttc,name,sizeAttch,attachment' +
                                                            ') VALUES (' +
                                                            '?,?,?,?,?' +
                                                            ')';
                                                    sx.executeSql(q,
                                                    [row.ID, lineRow.Order, lineRow.Name, lineRow.Size, response.responseText], function (transaction, results) {
                                                        handleNextAttachement();
                                                    }, function (error) {
                                                        _onError(error.message);
                                                    });
                                                });
                                            }
                                        }
                                    });
                                }
                            }, function (error) {
                                if (error) {
                                    app.alert(error);
                                }
                                handleNextItem();
                            });
                    });
                },
                error: function (responce) {
                    if (error) {
                        app.alert(error);
                    }
                    handleNextItem();
                }
            });
        }
    }

Aucun commentaire:

Enregistrer un commentaire