Skip to content

Broken SQL.open( data ) / SQL.exportData() #9

Closed
@ltearno

Description

@ltearno

The mechanism through which it is possible to save and load a SQL instance seems to be broken.

The problem happens when opening a SQL instance passing the data returned by exportData() to the open(data) method.
To me it seems that although when created empty the database makes his buffer grow without problem, when the database is opened with a given uint8array, as the database grows the buffer is not reallocated and an overflow is generated, leading then to a corruption in the database disk image (SQLite exception: 11, database disk image is malformed)

Here is the test case proving the bug. The principle is simple, i first create an empty database, fill it with some records, then export its data, close it, reopen it with the exported data, and then going again with insertions.

Here is the Javascript code for this bug test-case, it is inpired by your demo page :

<script type="text/javascript" language="javascript">

// This variable will receive instance of SQLite
var db = null;

// method taken from your demo
function print(text) {
  var element = document.getElementById('output');
  element.innerHTML += "<br/>" + text;//.replace(/\n/g, '<br>');
}

// method taken from your demo
// only one modification : returns true when everything ok, and false when an exception has been triggered
function execute(commands) {
  try {
    print( "<b>" + commands + "</b>" );
    var data = db.exec(commands.replace(/\n/g, '; '));
    print(JSON.stringify(data, null, '  '));
    return true;
  } catch(e) {
    print(e);
    return false;
  }
}

var res = true;
for( i=0; i<10; i++ )
{
    print( "Pass " + i );

    var data = null;

    // if a SQLite instance has already been opened, we just export its data, 
    // close it and reopen a new instance with the exported data
    if( db != null )
    {
        data = db.exportData();
        db.close();
        db = null;

        print( "Exporting data and closing sqlite, bytes=" + data.length );
    }

    if( data != null )
    {
        db = SQL.open( data );
    }
    else
    {
        db = SQL.open();
        execute( "CREATE TABLE Persons( id INTEGER PRIMARY KEY AUTOINCREMENT, LastName varchar(255) NOT NULL );" );
    }

    execute( "SELECT count(*) as 'CountOfPersons' from Persons;" );

    for( j=0; j<100; j++ )
    {
        res = execute( "insert into Persons (LastName) values ('Toto-"+i+"-"+j+"');" );
        if( ! res )
            break;
    }

    if( ! res )
        break;
}

print( "Finished" );

</script>

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions