views:

39

answers:

1

Hi,

I started trying to use sqlite to host small websites and on my own personal server, I ran into a glich which kind of spoils the whole idea.

I have a very simple test example, on a two row table in a sqlite 2.x database, I am being hosted with 5.2.12, I have also tried with the PDO sqlite3 database, the problem is this. The "users" table, holds some information, the table is like this

fields(id,username,forename,surname,password)

There are two entries into the table, they are

entry(1,chris,Christopher,Thomas,123) entry(2,adam,Adam,Tanner,456)

The problem is a bit strange, when I query the database like this:

query("select * from users where id=2")

I get the correct results, like this below:

entry(2,adam,Adam,Tanner,456)

When I request ALL the rows, like this query("select * from users") I get this:

entry(1,chris,Christopher,Tanner,456) entry(2,adams,Adamstopher,Tanner,456)

Do you see what seems to have happened? The information in the second entry, is less characters than the first entry, so it seems to be just overwriting the data with the second entry, causing some corruption.

chris adams<---- The s comes from chris

Christopher Adamstopher <--- The stopher comes from chri*stopher*


The code is very simple, this is what I run, I try direct sqlite_* calls on sqlite2 and then PDO on sqlite2 and sqlite3 versions of the same database, just to make sure there was any doubt.

(BTW: I added some simple html markup changes and things to make it all look better in the stackoverflow website, those changes aren't in the original code, but they are just things like h1->p or wrapping things with <pre> to preserve the code formatting, etc).

<p>TEST 1 with direct sqlite_* calls</p>
<?php 
try{
    $connection = sqlite_open("../playground.sqlite",0666,$error);
    $handle = sqlite_query("select * from users",$connection);

    $numResults = sqlite_num_rows($handle);

    for($a=0;$a<$numResults;$a++){
        print("<pre>".print_r(sqlite_fetch_array($handle,SQLITE_ASSOC),true)."</pre>");    
    }

}catch(Exception $e){
    die("EXCEPTION OCCURED: '$error'");
}
?>
<p>PDO TEST: SQLITE 2.x</p>
<?php    
    $connection = new PDO('sqlite2:../playground.sqlite');
    $handle = $connection->query("SELECT * FROM users");

    if($handle){
        $result = $handle->fetchAll(PDO::FETCH_ASSOC);
        print("<pre>".print_r($result,true)."</pre>");
    }else{
        var_dump($connection->errorInfo());
        print("query returned negatively");
    }
?>
<p>PDO TEST: SQLITE 3.x</p>
<?php    
    $connection = new PDO('sqlite:../playground.sqlite3');
    $handle = $connection->query("SELECT * FROM users");

    if($handle){
        $result = $handle->fetchAll(PDO::FETCH_ASSOC);
        print("<pre>".print_r($result,true)."</pre>");
    }else{
        var_dump($connection->errorInfo());
        print("query returned negatively");
    }
?>

The output from running this code is:

TEST 1 with direct sqlite_* calls
Array
(
    [id] => 1
    [username] => chris
    [forename] => Christopher
    [surname] => Thomas
    [password] => 123
)

Array
(
    [id] => 2
    [username] => adams
    [forename] => Adamstopher
    [surname] => Tanner
    [password] => 456
)

PDO TEST: SQLITE 2.x
Array
(
    [0] => Array
        (
            [id] => 1
            [username] => chris
            [forename] => Christopher
            [surname] => Thomas
            [password] => 123
        )

    [1] => Array
        (
            [id] => 2
            [username] => adams
            [forename] => Adamstopher
            [surname] => Tanner
            [password] => 456
        )

)

PDO TEST: SQLITE 3.x
Array
(
    [0] => Array
        (
            [id] => 1
            [username] => chris
            [forename] => Christopher
            [surname] => Thomas
            [password] => 123
        )

    [1] => Array
        (
            [id] => 2
            [username] => adams
            [forename] => Adamstopher
            [surname] => Tanner
            [password] => 456
        )
)

If you know why this happens, thanks for letting me know!

+1  A: 
<?php
echo PHP_VERSION, ' ', PHP_OS, ' ', PHP_SAPI, "\n";

$pdo = new PDO('sqlite:sotest.sqlite'); 
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$pdo->exec('DROP TABLE IF EXISTS users');
$pdo->exec('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY ASC, username,forename,surname,password)');
$pdo->exec("INSERT INTO users (id,username,forename,surname,password) VALUES (1,'chris','Christopher','Thomas',123)");
$pdo->exec("INSERT INTO users (id,username,forename,surname,password) VALUES (2,'adam','Adam','Tanner',456)");

$rows = $pdo->query("SELECT Length(forename) as cForename, Length(surname) as cSurname, * FROM users")->fetchAll(PDO::FETCH_ASSOC);
print_r($rows);

on my machine prints

5.3.2 WINNT cli
Array
(
    [0] => Array
        (
            [cForename] => 11
            [cSurname] => 6
            [id] => 1
            [username] => chris
            [forename] => Christopher
            [surname] => Thomas
            [password] => 123
        )

    [1] => Array
        (
            [cForename] => 4
            [cSurname] => 6
            [id] => 2
            [username] => adam
            [forename] => Adam
            [surname] => Tanner
            [password] => 456
        )

)

Can you reproduce the erroneous behaviour with this code on your 5.2.x server?

VolkerK
ok, thats just plain weird, it doesn't generate the error, you can see the results herehttp://burning-candle.com/widget-playground/profile-image/test_database2.phpand http://burning-candle.com/widget-playground/profile-image/test_database2.phps(I made a small mod to output inside a <pre> so it formats correctly).ok, this is a test case, lets find the minimum code needed to reproduce my error, I wonder if it's obtaining the lengths that does it? or perhaps creating the tables using the tool I am with (SQLiteManager 3.1.1 from sqlabs.net)
Christopher Thomas
check out thesehttp://burning-candle.com/widget-playground/profile-image/test_database3.phpandhttp://burning-candle.com/widget-playground/profile-image/test_database4.php
Christopher Thomas
oh, I dont like how it puts links, grr!!
Christopher Thomas
it looks like a corrupted database, I am not sure why though, or why there doesnt seem to be any errors, it just outputs crap data, I wonder how you would detect this with a larger and more complex database?
Christopher Thomas
Maybe you find something related in http://www.sqlite.org/src/rptview?rn=1 | Do you have another frontend you can use on the (possibly corrupted) database file? Preferably one that uses another, maybe more recent version of the sqlite lib than you php version does?
VolkerK
I tried the sqlite command line and it was outputting the correct data, inside my tool sqlitemanager, it outputs correct data too, just in the PHP server it was corrupted output.i've removed all the test_database* scripts now, since the problem is solved and all the code necessary to reproduce the scripts are contained in this question from you and me. So I wanted to cleanup my debugging mess.thanks volkerK!
Christopher Thomas