Re: [sqlite] Small enhancement: BEGIN SHARED

2006-04-08 Thread Paul Bohme
[EMAIL PROTECTED] wrote:
> Paul Bohme <[EMAIL PROTECTED]> wrote:
>   
>> I have a small patch that adds "BEGIN SHARED" syntax in addition to
>> IMMEDIATE and EXCLUSIVE.  I have an application that requires a
>> consistent view of the data across a number of individual statements. 
>> 
>
> This is what plain old "BEGIN" does.
>
> OK, really BEGIN does not acquire the lock until you actually
> try to use the database in some way.  So another process might
> modify the database in between the time when you issue the BEGIN
> and the time you actually start using the database.  But since
> you do not know what the state of the database is when you
> issue the BEGIN, why should you care?  The change might occur
> before or after the BEGIN but since you have know way of knowing
> which, why should it matter?
>   

Doah!  That's actually true - I'd forgotten (even though I went through
the code..) that the BEGIN also turns off the autocommit.  Sometimes
being habitually pedantic hides the forest amongst the trees.

No worries, then. ;-)

  -P



[sqlite] Small enhancement: BEGIN SHARED

2006-04-08 Thread Paul Bohme

  I have a small patch that adds "BEGIN SHARED" syntax in addition to
IMMEDIATE and EXCLUSIVE.  I have an application that requires a
consistent view of the data across a number of individual statements. 
What is ideal is a way to simply lock the database with a SHARED lock
for the duration, but the only way to do this is run a SELECT. 
Unfortunately, this means that I have a SELECT that does nothing other
than hold a lock.  This smacks of programming by side effect, so killed
a bit of time on a recent flight by adding the SHARED keyword.

  After digging about on the site, don't see the 'right' way to submit a
patch - although I did find the requirements for surrendering
copyright.  Odd at first thought, but a damn fine idea.  Therefore, as
this code was written on personal time using personal hardware, I
include the following as requested:

/The author or authors of this code dedicate any and all copyright
interest in this code to the public domain. We make this dedication
for the benefit of the public at large and to the detriment of our
heirs and successors. We intend this dedication to be an overt act
of relinquishment in perpetuity of all present and future rights
this code under copyright law. /


Attached patch is against 3.2.8.  Thoughts?

  -P

diff -urN sqlite-3.2.8/src/build.c sqlite-3.2.8-shared/src/build.c
--- sqlite-3.2.8/src/build.c	2005-12-19 11:26:41.0 -0500
+++ sqlite-3.2.8-shared/src/build.c	2006-04-04 12:44:47.0 -0400
@@ -2673,8 +2673,19 @@
   v = sqlite3GetVdbe(pParse);
   if( !v ) return;
   if( type!=TK_DEFERRED ){
+switch( type ) {
+  case TK_EXCLUSIVE:
+type = 2;
+break;
+  case TK_IMMEDIATE:
+type = 1;
+break;
+  case TK_SHARED:
+type = 0;
+break;
+}
 for(i=0; inDb; i++){
-  sqlite3VdbeAddOp(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
+  sqlite3VdbeAddOp(v, OP_Transaction, i, type);
 }
   }
   sqlite3VdbeAddOp(v, OP_AutoCommit, 0, 0);
diff -urN sqlite-3.2.8/src/parse.y sqlite-3.2.8-shared/src/parse.y
--- sqlite-3.2.8/src/parse.y	2005-12-19 11:25:45.0 -0500
+++ sqlite-3.2.8-shared/src/parse.y	2006-04-04 12:29:17.0 -0400
@@ -120,6 +120,7 @@
 transtype(A) ::= DEFERRED(X).  {A = @X;}
 transtype(A) ::= IMMEDIATE(X). {A = @X;}
 transtype(A) ::= EXCLUSIVE(X). {A = @X;}
+transtype(A) ::= SHARED(X).{A = @X;}
 cmd ::= COMMIT trans_opt.  {sqlite3CommitTransaction(pParse);}
 cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);}
 cmd ::= ROLLBACK trans_opt.{sqlite3RollbackTransaction(pParse);}
@@ -174,7 +175,7 @@
   ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT
   DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
   IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH PLAN QUERY KEY
-  OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
+  OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW SHARED STATEMENT
   TEMP TRIGGER VACUUM VIEW
 %ifdef SQLITE_OMIT_COMPOUND_SELECT
   EXCEPT INTERSECT UNION
diff -urN sqlite-3.2.8/tool/mkkeywordhash.c sqlite-3.2.8-shared/tool/mkkeywordhash.c
--- sqlite-3.2.8/tool/mkkeywordhash.c	2005-12-19 11:25:45.0 -0500
+++ sqlite-3.2.8-shared/tool/mkkeywordhash.c	2006-04-04 12:38:35.0 -0400
@@ -209,6 +209,7 @@
   { "ROW",  "TK_ROW",  TRIGGER},
   { "SELECT",   "TK_SELECT",   ALWAYS },
   { "SET",  "TK_SET",  ALWAYS },
+  { "SHARED",   "TK_SHARED",   ALWAYS },
   { "STATEMENT","TK_STATEMENT",TRIGGER},
   { "TABLE","TK_TABLE",ALWAYS },
   { "TEMP", "TK_TEMP", ALWAYS },


Re: [sqlite] Persistent user-defined functions

2006-04-08 Thread Paul Bohme
Daniel Franke wrote:
> Layering. Wrap sqlite3_* into your own set of functions. Create another 
> library, say libyourapp. Most functions will just forward the arguments to 
> sqlite, but others, e.g. yourapp_open_db() will not only open the database, 
> but also attach a couple of functions, which are also part of libyourapp.
>
> This additional layer won't cost too much CPU cycles and is also meaningfull 
> if you ever decide to switch database backends: just reimplemnt those 
> functions and you are back in business :)
>
>   

This is what I've done.  For consistency I've also used simple macros to
#define sqlite3_ functions to db_ counterparts, so there are no sqlite3_
APIs called directly from the code.  The db_open also registers a couple
of small C functions at the same time.  Also lets us do a few neat
things, like use the same base offset for binding and retrieving data as
well as centralizing SQLITE_BUSY returns and error reporting.

Would second Daniel's recommendation, all except for the part about
switching database backends.. ;-)

  -P



Re: [sqlite] SQLite and Flash memory

2006-01-12 Thread Paul Bohme

[EMAIL PROTECTED] wrote:


Has anyone experimented with putting SQLite directly on the
Linux MTD flash interface?  I.e. by-passing JFSS2.  Would this
offer any kind of significant efficiency benefit?  
 



JFFS2 is designed to wear the flash evenly, preventing you from 
'drilling holes' by writing to any single block more than others and 
wearing it out faster.  If there is a performance gain to be had by 
going directly to flash, you lose the robustness and leveling properties 
of the JFFS2.  Unless of course the 'direct to flash' implementation 
accounts for power loss, bad blocks and wear leveling I'd be loathe to 
give up JFFS2.


 -P



Re: [sqlite] ring buffer table

2006-01-09 Thread Paul Bohme

Julien LEFORT wrote:


Hi,
I would like to implement a log table with a finite dimension, for exemple a 
table with 500 records, and when the last record is set in the table I would 
like to come back at the first tuplet and write over the previous value 
recorded. I think it's the way SQLite journal is implmented.
Is there any way to declare this table with these properties included, so I 
don't have to add code to do this function?

Thanks
 



 A guy on this end had a suggestion that I kicked myself for not 
thinking of earlier: Use a simple numeric ID that you mod by the number 
of records you want, automatically overwriting the oldest record when a 
new one comes along..  I may have to put together a smallish trigger to 
keep the IDs in range, perhaps a manual implementation of a simple 
sequence to pull a value from, then use that as the record ID.


 -P



Re: [sqlite] ring buffer table

2005-12-23 Thread Paul Bohme

Cory Nelson wrote:


afaik, sqlite doesn't store row counts so count(*) causes a full table scan.

On 12/23/05, Axel Mammes (gmail) <[EMAIL PROTECTED]> wrote:
 


Wouldn´t a SELECT COUNT(*) just read the table header and get the amount of
records from there? That should be faster and simpler than maintaning a
separate table for the counters.
   




Is a good question, I might have to crack into it and have a look (to 
know for sure what it does..)  Depending on the database a single 
counter is a perfect spot for locking contention so many don't have a 
count of rows or other entities, thus I didn't really expect SQLite to 
have it.




-Original Message-
From: Paul Bohme [mailto:[EMAIL PROTECTED]
Sent: Viernes, 23 de Diciembre de 2005 02:52 p.m.
To: sqlite-users@sqlite.org
Subject: Re: [sqlite] ring buffer table

Julien LEFORT wrote:

   


Hi,
I would like to implement a log table with a finite dimension, for exemple
 


a
   


table with 500 records, and when the last record is set in the table I
 


would
   


like to come back at the first tuplet and write over the previous value
recorded. I think it's the way SQLite journal is implmented.
Is there any way to declare this table with these properties included, so I
 


don't have to add code to do this function?
Thanks


 


I need something similar, so was planning a couple of simple tricks to
keep the overhead low.  I want to avoid "select count" queries as much
as possible, so how does the following sound:

- insert/delete triggers on the table I want to limit the size of
- a separate table with a row that contains a single counter, that is
incremented and decremented by the above triggers
- a process that runs at intervals that checks the counter, and if over
the limit trims the appropriate number of records

Seems like a reasonable way to keep a table to a limited growth without
too much of a hit on every insert.  The counter table would be a serious
hot spot in other databases, but SQLite's locking is simple enough that
it doesn't seem like it will be a problem.

 -P


   




--
Cory Nelson
http://www.int64.org
 





Re: [sqlite] ring buffer table

2005-12-23 Thread Paul Bohme

Julien LEFORT wrote:


Hi,
I would like to implement a log table with a finite dimension, for exemple a 
table with 500 records, and when the last record is set in the table I would 
like to come back at the first tuplet and write over the previous value 
recorded. I think it's the way SQLite journal is implmented.
Is there any way to declare this table with these properties included, so I 
don't have to add code to do this function?

Thanks
 



I need something similar, so was planning a couple of simple tricks to 
keep the overhead low.  I want to avoid "select count" queries as much 
as possible, so how does the following sound:


- insert/delete triggers on the table I want to limit the size of
- a separate table with a row that contains a single counter, that is 
incremented and decremented by the above triggers
- a process that runs at intervals that checks the counter, and if over 
the limit trims the appropriate number of records


Seems like a reasonable way to keep a table to a limited growth without 
too much of a hit on every insert.  The counter table would be a serious 
hot spot in other databases, but SQLite's locking is simple enough that 
it doesn't seem like it will be a problem.


 -P



Re: [sqlite] SQlite for Linux on the ARM processor.

2005-12-22 Thread Paul Bohme

Ben Clewett wrote:


Dear SQLite

I wish to compile SQLite for the ARM processor running Linux (ARM720T).

The compilation will have to use the cross-compiler arm-linux-gcc 
version 2.95.2 running on Intel Linux, since the devise it's self has 
no compiler.


Does any person have an image for ARM?

If not, would any person have any advise on how this can be made?

Eg, in the configure, can the arm-Linux-gcc be specified as the compiler?

Thanks for any advise,

Ben Clewett.




The official way is to modify the Makefile (tweak the documented options 
to suit).


Given that there are autotools, this seems a bit 'off'.  Unfortunately 
the autotools scripts are slightly broken for doing cross-compile 
builds, but aren't hard to make work.  I had to tweak the configure 
script to allow disabling of the readline library (don't have/want it 
for my ARM target) - I can send along a patch against 3.2.7 for this if 
you'd like.  Then, my configure command line was:


config_TARGET_CC=arm-linux-gcc config_BUILD_CC=gcc ./configure 
--disable-tcl --disable-readline --enable-threadsafe 
--enable-releasemode --host=arm-linux --prefix=/usr/local/arm


You will want to modify the --prefix= option to someplace that you want 
the ARM version installed so your other build scripts can pick it up.


 -P

P.S. to DRH: If you'd like I can properly package up any changes 
required to make SQLite more 'cross-compile friendly' without having 
parallel build mechanisms and pass them along.  Doesn't look like any 
more depth needed than some simple autotools scripting tweaks so no 
damage to vital organs..




Re: [sqlite] Using time and date values

2005-12-15 Thread Paul Bohme

Brad wrote:


I am looking for a simple way of using date and time values with
sqlite3. I have some Ctime classes (VC++.net) which have to be stored in
the database and they should be compared.



If the class you're using has .Value property, or a way to easily 
transform the date from one format to another, you should probably 
store that.  For instance, I like to store dates in string format, 
using something like "CCYYMMDDHHmmSS.SS". If I expect to need to 
deal with time zones, I'll store all the dates/times as GMT, or 
Universal time, and do the conversions when I create the datetime 
objects.



Storing as strings is great as long as you only ever display the 
values.  Doing range checks on a stringified format becomes prohibitive, 
at best.  If you're going to have to filter/query on the dates, by far 
your best bet is a simple number that is an offset from an epoch.  
Classic UNIX calendar time is effective for dates in the proper range 
for precisions above one second (most of us) or you can do something 
similar to Java's date representation that measures milliseconds since 
the epoch.


 -P



[sqlite] Odd query optimization

2005-12-02 Thread Paul Bohme
OK, little puzzled by this one, wondering if my expectations of behavior 
are off.  (Apologies for the longish post..)


This is with 3.2.7.  I have a reasonably simple 'users' table, with a 
single compound index (at first) on user last/first name:


create table users (
 id integer primary key,
 account_id integer not null,
 first_name varchar collate nocase,
 last_name varchar collate nocase,
 enabled date default CURRENT_TIMESTAMP,
 expires date default null,
 deleted integer
);
create index user_name_index on users(last_name, first_name);

Then ran the following query:

SELECT id, first_name, last_name
FROM users
WHERE account_id = ? AND last_name >= ? AND last_name < ? AND deleted is 
null

ORDER BY last_name, first_name
LIMIT 25 OFFSET ? ;

which performs well enough.  Thinking that adding an index to account_id 
would only speed things up, I added the following:


create index user_account_index on users(account_id);

Which made the following query take 10x longer (!) to produce the same 
results.  This is what left me scratching my head.  I ran explain both 
before and after the addition of the index and got the following 
(totally different) outputs:


Without user_account_index:

0|Noop|0|0|
1|Integer|25|0|
2|MustBeInt|0|0|
3|Negative|0|0|
4|MemStore|0|1|
5|Variable|4|0|
6|MustBeInt|0|0|
7|Negative|0|0|
8|MemStore|1|1|
9|Goto|0|50|
10|Integer|0|0|
11|OpenRead|0|2|
12|SetNumColumns|0|7|
13|Integer|0|0|
14|OpenRead|2|3|keyinfo(2,NOCASE,NOCASE)
15|Variable|3|0|
16|NotNull|-1|19|
17|Pop|1|0|
18|Goto|0|47|
19|MakeRecord|1|0|tt
20|MemStore|3|1|
21|Variable|2|0|
22|NotNull|-1|25|
23|Pop|1|0|
24|Goto|0|47|
25|MakeRecord|1|0|tt
26|MoveGe|2|47|
27|MemLoad|3|0|
28|IdxGE|2|47|
29|RowKey|2|0|
30|IdxIsNull|1|46|
31|IdxRowid|2|0|
32|MoveGe|0|0|
33|Column|0|1|
34|Variable|1|0|
35|Ne|361|46|collseq(BINARY)
36|Column|0|6|
37|NotNull|1|46|
38|MemIncr|1|0|
39|IfMemPos|1|41|
40|Goto|0|46|
41|MemIncr|0|47|
42|Rowid|0|0|
43|Column|0|2|
44|Column|0|3|
45|Callback|3|0|
46|Next|2|27|
47|Close|0|0|
48|Close|2|0|
49|Halt|0|0|
50|Transaction|0|0|
51|VerifyCookie|0|2|
52|Goto|0|10|
53|Noop|0|0|


After adding user_account_index:

0|OpenVirtual|1|4|keyinfo(2,NOCASE,NOCASE)
1|Integer|25|0|
2|MustBeInt|0|0|
3|Negative|0|0|
4|MemStore|0|1|
5|Variable|4|0|
6|MustBeInt|0|0|
7|Negative|0|0|
8|MemStore|1|1|
9|Goto|0|64|
10|Integer|0|0|
11|OpenRead|0|2|
12|SetNumColumns|0|7|
13|Integer|0|0|
14|OpenRead|2|4|keyinfo(1,BINARY)
15|Variable|1|0|
16|NotNull|-1|19|
17|Pop|1|0|
18|Goto|0|47|
19|MakeRecord|1|0|i
20|MemStore|2|0|
21|MoveGe|2|47|
22|MemLoad|2|0|
23|IdxGE|2|47|+
24|RowKey|2|0|
25|IdxIsNull|1|46|
26|IdxRowid|2|0|
27|MoveGe|0|0|
28|Column|0|3|
29|Variable|2|0|
30|Lt|372|46|collseq(NOCASE)
31|Column|0|3|
32|Variable|3|0|
33|Ge|372|46|collseq(NOCASE)
34|Column|0|6|
35|NotNull|1|46|
36|Rowid|0|0|
37|Column|0|2|
38|Column|0|3|
39|MakeRecord|3|0|
40|Column|0|3|
41|Column|0|2|
42|Sequence|1|0|
43|Pull|3|0|
44|MakeRecord|4|0|
45|IdxInsert|1|0|
46|Next|2|22|
47|Close|0|0|
48|Close|2|0|
49|Sort|1|63|
50|MemIncr|1|0|
51|IfMemPos|1|53|
52|Goto|0|62|
53|MemIncr|0|63|
54|Column|1|3|
55|Integer|3|0|
56|Pull|1|0|
57|Column|-1|0|
58|Column|-2|1|
59|Column|-3|2|
60|Callback|3|0|
61|Pop|2|0|
62|Next|1|50|
63|Halt|0|0|
64|Transaction|0|0|
65|VerifyCookie|0|3|
66|Goto|0|10|
67|Noop|0|0|

An "explain query plan" of the second also gave me something interesting:

0|0|TABLE users WITH INDEX user_account_index

Does this mean it's only able to use one index, so the addition of a 
separate index knocks the most useful one out of the running?


Anyone have any thoughts on why adding an index nailed the 
plan/performance so remarkably?


Thanks,

 -P



Re: [sqlite]cross compiling with powerpc

2005-12-02 Thread Paul Bohme

Julien LEFORT wrote:


Hi,
I've been struggling for few hours trying to run the configure script the 
right way so I can cross compile sqlite3 for a powerpc target.

I guess it is only a problem of options I pass into the configure script.
here is the command I pass:

CC=powerpc-linux-gcc CXX=powerpc-linux-g++ BUILD_CC=gcc ../configure 
--host=i686-linux --target=powerpc-linux --disable-shared --disable-tcl


and the error I get:

Version number set to 3002007
checking for i686-linux-gcc... (cached) powerpc-linux-gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether powerpc-linux-gcc accepts -g... (cached) yes
checking for powerpc-linux-gcc option to accept ANSI C... (cached) none needed
configure: error: unable to find a compiler for building build tools

Anyone has any idea?
Thanks

Julien
 



For building ARM I use the following:

config_TARGET_CC=arm-linux-gcc config_BUILD_CC=gcc ./configure 
--disable-tcl --disable-readline --enable-threadsafe 
--enable-releasemode --host=arm-linux --prefix=`pwd`/install


I found that it was choking on the config_TARGET_CC and config_BUILD_CC 
variables, so set those explicitly.  (I also added a check to be able to 
fully kill readline as I don't have/want it for my target.)


 -P