I’m working on a custom combobox, and an using an SQLite in memory database to hold the list. Everything works great so far except I’m running into a problem with removerow and insertrow. The problem is I’m using rowid for my list index. When i delete rows from the table it leaves a ‘hole’ in the rowid sequence. Adding a row is also a problem because is I want to insert at the correct position I first need to increase all the higher rowid’s.
I’ve been wracking my brain but can’t think of a solution. Any ideas? A totally different approach? I really need to use a database for the list because of the filtering capabilities needed.
Ok this seems a little expensive but it works. I’m still open to suggestions.
'InsertRow(5000)
BEGIN TRANSACTION;
CREATE TABLE temp1 AS SELECT * FROM temp WHERE rowid < 5000;
INSERT INTO temp1 (rowid, f1) VALUES (5000, 'test insert');
INSERT INTO temp1 SELECT * FROM temp WHERE rowid > 4999;
DROP TABLE temp;
ALTER TABLE temp1 RENAME TO temp;
COMMIT ;
'RemoveRow(5000)
BEGIN TRANSACTION;
CREATE TABLE temp1 AS SELECT * FROM temp WHERE rowid < 5000 OR rowid > 5000;
DROP TABLE temp;
ALTER TABLE temp1 RENAME TO temp;
COMMIT ;
RowID are unique… if you delete a row, it WILL leave a hole… you can fill the hole if you defined a AutoInc Integer PK… and insure you assign it a value that does not exist… AutoInc takes the HIGHEST value and inserts it if you supply NULL
But in any case for what you are trying… don’t use “rowid” directly… assign your own PK
also… if you have ROWID but NOT AutoInc PK… VACUUM will compress those holes… but if you have your own PK it will not
[quote=333156:@Jean-Yves Pochez]use the listbow rowtag property to store your rowid
the database rowid are not following each other.[/quote]
Normally that would work but not in this case.
The dropdown listbox shows dynamically changing data that is filtered and loaded as the user types in the combobox.
I store the rowid in the listbox so when a user clicks the item I can find it in the underlying db.
The underlying db contains all the data for the combobox and needs to contain an integer field to be used as the listindex.
The real problem is that when a row is remove all rows with a higher index are changed.
I could do that but it still doesn’t circumvent the need to change every single id when a record is deleted.
You are doing something way way wrong here…
if you have a table (forget combobox or listbox)… stay with the base database table
and it has 3 records
create table myTable (fruit text)
insert into mytable values('Apple')
insert into mytable values('Peach')
insert into mytable values('Orange')
and then select that data
SELECT rowid,fruit FROM mytable
you get
1 Apple
2 Peach
3 Orange
NOTE : Starts with ONE, not ZERO
DELETE FROM mytable where Fruit='Peach'
Select then returns
1 Apple
3 Orange
The ROWID does NOT change, it will NEVER change unless you do a VACUUM
If you created a AutoInc PK, the hole would still be there, but you could then fill the hole if you wished, and VACUUM would have no effect on those values
Now, in a combobox (listbox)… the LISTINDEX DOES change, but it has NOTHING to do with the PK or RowID of the database
That would work but the reverse would be cumbersome. So if the user selects an item from the list (of queried results) I know what the PK number is but I would need to loop through the array to find the index.
and your combobox is so huge that this is an issue?
If so, I’d say you need to rethink this from the beginning…
a combobox should not have more than a few dozen entries at best
I still maintain you can use the rowtag property to store the PK
don’t need to create another property, the rowtag is already here for that purpose.
if you delete a row of the listbox, the rowtag gets deleted too
if you delete something in the database, or narrow the search, then update the listbox with the recordset values,
and re-store the rowtag of the listbox with the newly searched rowids