SQLite Forum

Timeline
Login

50 most recent forum posts by user slavin

2021-10-14
14:33 Edit reply: binary .dump format (artifact: 698355ddf8 user: slavin)

In that case, instead of using .dump, the OP should be using

https://www.sqlite.org/sqldiff.html

and then compressing the result. But the analysis phase of sqldiff might take a long time.

14:33 Reply: binary .dump format (artifact: 7501594306 user: slavin)

In that case, instead of using /dump, the OP should be using

https://www.sqlite.org/sqldiff.html

and then compressing the result. But the analysis phase of sqldiff might take a long time.

10:10 Edit reply: binary .dump format (artifact: 442587d3b7 user: slavin)

Your major complaint seems to be that the text representation of BLOBs doubles their length. I can understand you wanting a custom-written solution for your particular SQLite project. But years of experience tells me you'll be better off with this solution.

  1. Use the existing .dump facility to produce the text dump file
  2. Use pkzip or some other command-line facility to compress the dump file.

Not only will this compress the BLOBs, it'll compress everything else too. I haven't tried it on databases with big BLOBs but it's very good at compressing normal SQLite database dumps. And it'll do it using standard tools, widely available on many platforms, that you don't have to write and maintain yourself.

10:08 Reply: binary .dump format (artifact: 02470db818 user: slavin)

Your major complaint seems to be that the text representation of BLOBs doubles their length. I can understand you wanting a custom-written solution for your particular SQLite project. But years of experience tells me you'll be better off with this solution.

  1. Use the existing .dump facility to produce the text dump file
  2. Use pkzip or some other command-line facility to compress the dump file.

Not only will this compress the BLOBs, it'll compress everything else too. I haven't tried it on databases with big BLOBs but it's very good at compressing normal SQLite database dumps.

2021-10-13
19:18 Reply: inconsistent output: insert on conflict with returning (artifact: a339db3dbc user: slavin)

Can I ask where you got the idea to use 'excluded.' in those commands ?

12:19 Reply: Data Types (artifact: 073be6a27e user: slavin)

Ah, got it.

With regard to all values returned being 5, did you define the column types when you defined the table ? Or was the table definition like

CREATE TABLE MyTable (first, second, third);

? Also note that SQLite does not enforce values to be the same type as a column definition. For instance, you can define a column as INTEGER but put a text value into one row for it. If that row happens to the first one returned by a query, sqlite3_column_type() will return SQLITE_TEXT for that column.

From the page you quoted …

The sqlite3_column_type() routine returns the datatype code for the initial data type of the result column. The returned value is one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. The return value of sqlite3_column_type() can be used to decide which of the first six interface should be used to extract the column value. The value returned by sqlite3_column_type() is only meaningful if no automatic type conversions have occurred for the value in question. After a type conversion, the result of calling sqlite3_column_type() is undefined, though harmless. Future versions of SQLite may change the behavior of sqlite3_column_type() following a type conversion.

2021-10-12
21:55 Reply: Data Types (artifact: b010aa47f1 user: slavin)

SQLite doesn't work in a way that would need that table. For instance, it doesn't use numeric codes, and its internal storage doesn't use classes you might see elsewhere (e.g. C++).

One table which resembles the table you asked for appears here:

https://www.sqlite.org/datatype3.html#affinity_name_examples

but actually I'd recommend you read the whole page since it explains why you won't see the table you asked about.

For technical details about how values of all types are stored in the database, see this page:

https://sqlite.org/fileformat.html

If I misunderstood your question, or can help, please post a reply to this thread.

2021-10-11
01:52 Reply: Update with table alias (artifact: 3872dc98e3 user: slavin)

The RETURNING clause apparently doesn't have access to internal aliases. If you change

old.name
to
demo.name
does it work ?

2021-10-10
02:56 Edit reply: Understanding memory allocation behavior of SQLite (artifact: d560d3da8f user: slavin)

Out of interest, can you leave your memory monitoring hooks in place but test this ?

  1. Create the table, allowing SQLite to assign ROWIDs, and without the PRIMARY KEY.
  2. Load your 77 million rows of data, using transactions to bunch together INSERTs as before
  3. Create a UNIQUE INDEX on ('col1','col2','col3')

Does this turn out faster or slower than the procedure you describe above ? Does it allocate more or less memory ?

2021-10-09
15:16 Reply: Understanding memory allocation behavior of SQLite (artifact: 153bc160cf user: slavin)

Out of interest, can you leave your memory monitoring hooks in place but test this ?

  1. Create the table, allowing SQLite to assign ROWIDs, and without defining any indexes.
  2. Load your 77 million rows of data, using transactions to bunch together INSERTs as before
  3. Create a UNIQUE INDEX on ('col1','col2','col3')

Does this turn out faster or slower than the procedure you describe above ? Does it allocate more or less memory ?

2021-10-03
13:43 Delete reply: Unexpected output from the SELECT (artifact: 3dbd531b91 user: slavin)
Deleted
05:08 Reply: Unexpected output from the SELECT (artifact: 7e7078acd4 user: slavin)
sqlite> .mode table
sqlite> SELECT a67.c7 > a67.c9  FROM v1 AS a67;
+-----------------+
| a67.c7 > a67.c9 |
+-----------------+
|                 |
|                 |
+-----------------+

It produces two NULL rows, which is not the same as producing no rows. Both of those rows are TRUE, in that they each have a column. Next,

sqlite> SELECT * FROM v0 AS a66 WHERE EXISTS ( SELECT a67.c7 > a67.c9  FROM v1 AS a67 WHERE a66.c3 = a67.c10 AND a66.c3 IS a67.c6 );
+----+----+----+-----+-----+
| c1 | c2 | c3 | c4  | c5  |
+----+----+----+-----+-----+
| 1  |    | 0  | 100 | 200 |
+----+----+----+-----+-----+

gives you one row. Which is correct. And therefore your full line gives you one row.

SQLite seems to be interpreting this horrible piece of SQL in a reasonable way, and getting a reasonable result. I don't think the result is technically wrong. Just different to what an earlier version got.

2021-09-28
21:17 Reply: Reset database (artifact: 9d6f9839d7 user: slavin)

So you have read-only access to the database but you have read-write access to the drive the database is on. Why would an admin give you this combination of access ?

To get back to your question

  1. do you have sole access or is there a chance that some program not under your control has it open ?
  2. by 'the state when it was created' do you mean all tables are empty, or there are no tables ?
2021-09-26
13:19 Reply: SIGBUS in sqlite (artifact: ebeb240cfe user: slavin)

This worries me, because it suggests you can delete these files while the database is in use.

If SQLite closes the last connection to a database in WAL mode, it deletes the .shm file. So if you see a .shm file on disk SQLite thinks that one or more connection is still using the database, so you shouldn't delete any of the above files.

If you think a previous run of the database has crashed, and these flies really aren't being used, you can check this by using

sqlite_open()
"PRAGMA user_version" (or any other operation which requires reading the file)
sqlite_close()

on the database. If no other connections are using the database then this will delete the .shm file.

2021-09-25
21:06 Reply: V3.36 (artifact: b66e1c3b4a user: slavin)

Your question doesn't quite correspond with how SQLite manages open databases. When you want SQLite to access a database you create a 'connection'. That database will be the 'main' database for that connection. If you want SQLite to access a second database you can either attach another database to the first connection, or open another connection. So …

One instance of SQLite can have many connections. Each connection has a main database and can have many attached databases.

Given the above, to discover all databases you currently have access to, for each SQLite connection, use

https://sqlite.org/pragma.html#pragma_database_list

PRAGMA database_list

It returns one line per database, second column is the connection's name for that database, third column is the name of the database file.

Your next natural question is how to find out what tables are in each of those databases, and you'll find it on the above page, under

PRAGMA schema.table_xinfo(table-name)

(I spend a few minutes trying to find out how to iterate through the connections for an instance of SQLite and failed. Contributions welcome.)

2021-09-24
11:27 Edit reply: Cannot select a value that matches another column name (artifact: f4796c6f76 user: slavin)

The post that starts that thread shows a misunderstanding of SQL. Double quote characters indicate an entity name: a table name or a column name. To specify a string you use apostrophes (single quote characters). For instance, the line

SELECT * FROM Test WHERE Name = "Value";

should be

SELECT * FROM Test WHERE Name = 'Value';

11:24 Reply: Cannot select a value that matches another column name (artifact: 5aaeb72c2e user: slavin)

The post that starts that thread shows a misunderstanding of SQL. Double quote characters indicate an entity name: a table name or a column name. To specify a string you use apostrophes (single quote characters). For instance, the line

. SELECT * FROM Test WHERE Name = "Value";

should be

SELECT * FROM Test WHERE Name = 'Value';

2021-09-21
06:00 Reply: get only first record found (artifact: aa20b2d8f0 user: slavin)

You have the best SELECT command. However, you may not have the best schema to keep time and processing to a minimum. Do this …

CREATE INDEX test_available ON test (available)

… just once. Then try the SELECT command again.

PS: I see that this is just a test, but other people may find this code, so I remind them it is considered bad style to use 'SELECT *' in real production code. You should name the columns you want.

2021-09-20
15:10 Reply: adding record if it doesn't already exist (artifact: 14fc4693a5 user: slavin)

If the INSERT OR IGNORE fails because any UNIQUE indexes would be violated, nothing changes. If the INSERT OR IGNORE does not fail, all fields defined in the command are changed.

In other words, this does what you seem to want.

15:08 Reply: Database anomaly (artifact: 07696551da user: slavin)

Which API are you using ? Are you addressing SQLite's C API directly, or using a SQLite library for your programming language ?

The string with path and filename that you're passing to the API. Is it ASCII, UTF-8, or 16-bit Unicode ?

My suspicion is that the API is expecting one, but you're using another.

2021-09-16
12:46 Reply: about "strict" mode (artifact: 66dc6d95aa user: slavin)

And if you want rowids to survive a vacuum you can just declare them in the table definition. SQLite already does what you want. It doesn't need a special non-standard column type.

2021-09-15
11:42 Reply: Select query returning: no such table error (artifact: ca3b8865ac user: slavin)

We've seen this sort of thing before. It often turns out that something is stomping on the memory SQLite uses to keep track of data or file handles, causing it to look in a corrupted list of tables, or in a non-existent file. I'm not saying that this is the cause in your case, just that it's something to look for.

Do you have anything else accessing the same file ? It could be the SQLite API being called from another thread, process or app. But it could also be an automatic backup routine which locks the file while it backs it up. And in a non-Linux context I would also be suspicious of a virus-checker.

2021-09-14
14:48 Post: DELETE FROM … RETURNING (artifact: 9ceaa4a1e0 user: slavin)

The page https://sqlite.org/lang_delete.html includes the following:

The ORDER BY clause on a DELETE statement is used only to determine which rows fall within the LIMIT. The order in which rows are deleted is arbitrary and is not influenced by the ORDER BY clause. This means that if there is a RETURNING clause, the rows returned by the statement probably will not be in the order specified by the ORDER BY clause.

(The same thing happens with UPDATE). Someone told me, without even thinking about it, that that was a bug. I wanted to hear opinions.

I understand why SQLite does it. I don't need someone to explain the programming. Just whether an intelligent programmer would consider this a bug or not.

2021-09-12
14:09 Reply: Android and desktop Java library (artifact: 725a45707a user: slavin)

I assume you mean that all 10,000 rows are part of the same transaction. It might go faster if you try 1,000 rows and use ten transactions. Or it might not.

SQLite's processing is extremely fast. Almost all the time taken by SQLite is about storage access. Don't think about cores and GHz, think about memory bus speed, and time taken to read and write a sector.

Your Samsung phone is writing to Flash memory. Your laptop is passing the data to a storage subsystem, which stores it in a RAM cache then says "job done" (also in the background writes the cache to the real storage). Flash memory is slower than RAM.

2021-09-11
16:39 Reply: Android and desktop Java library (artifact: 495997e71e user: slavin)

Android:

https://devtut.github.io/android/sqlite.html

https://developer.android.com/jetpack/androidx/releases/sqlite

https://github.com/requery/sqlite-android

https://github.com/ArturVasilov/SQLite

There is no clear agreement that one of these is definitely the best option for all SQLite development. You will need to do some reading and make some choices.

I don't know enough about Java to answer that part of your question.

2021-09-10
06:10 Reply: Method to temporarily disable Not Null constraint? (artifact: f58551be36 user: slavin)

Option A: remove the constraints

Option B: make a table which is a copy of the entity table, but lacks the constraints. Load your data into that. Once the data is all there (which I think means there will be no NULLs left) copy that table to the real table using the INSERT … SELECT command which is optimized for speed. Then DELETE FROM your temporary table.

Comment on your post:

given that hundreds of tables are involved

This is always a red flag in a SQL database. If two tables have the same definition, or your table names include numbers or dates, it's probably a sign that they should be the same table, with one extra column. If you're right now at a stage where you are designing the schema, think hard about this because it will save you a lot of trouble in the long run.

02:15 Edit reply: NEXT VALUE FOR in SQLite (artifact: 9d90f945e7 user: slavin)

In your situation I might keep the counter in another table of the same database. Make a Config table, and in one column of one row, keep your counter.

UPDATE Config
    SET counter TO counter + 5
    WHERE configItem='customers'
    RETURNING counter

This does the update in one operation and returns a value which lets you figure out the ids for the 5 rows you want to insert. it is ACID, and threadsaf, given that you are correctly using separate connections.

02:15 Reply: NEXT VALUE FOR in SQLite (artifact: f1524c8da4 user: slavin)

In your situation I might keep the counter in another table of the same database. Make a Config table, and in one column of one row, keep your counter.

UPDATE Config
    SET counter TO counter + 5
    WHERE configItem='customers'
    RETURNING counter

This does the update in one operation and returns a value which lets you figure out the ids for the 5 rows you want to insert. it is ACID, and threadsafe (given that you are correctly using separate connections.

2021-09-09
13:47 Reply: How to insert duplicate rows? (artifact: 335930bfb9 user: slavin)

Thanks for the headsup. I saw a comment about the formatting above but didn't understand it. You explained it.

Okay, so the question isn't what I thought it was. Please ignore my previous post. Here's what I should have responded.

There's no reason why duplicate INSERTs shouldn't work. What happens when you try it ?

13:43 Edit reply: NEXT VALUE FOR in SQLite (artifact: a04e556795 user: slavin)

https://sqlite.org/capi3ref.html#sqlite3_last_insert_rowid

But what are you going to do with it ? You don't need to know it for the next INSERT. Will you be using it for a FOREIGN KEY ?

Also, assuming that your application really is multi-threading and not just multi-processing, are your multiple threads all using the same connection to the database ? That's not considered safe unless you understand exactly how they interact. They should be using different connections.

13:37 Reply: NEXT VALUE FOR in SQLite (artifact: 78b66a3c9b user: slavin)

https://sqlite.org/capi3ref.html#sqlite3_last_insert_rowid

But what are you going to do with it ? You don't need to know it for the next INSERT. Will you be using it as a FOREIGN KEY ?

07:59 Reply: How to insert duplicate rows? (artifact: f70dc8384e user: slavin)

Your table definition has incorrect syntax. Doing it that way gives you a column called id TEXT which has no affinity. The double quotes should not be there at all:

id TEXT

If you must use double quotes for your column names then they should be around the column name, not the affinity:

"id" TEXT

and you should use them everywhere you refer to a column name.

2021-09-08
18:13 Reply: solved disk I/O error on F2FS (artifact: 63a651757f user: slavin)

Most likely that your hard disk is corrupt, and SQLite is running into it when trying to make temporary files. Especially since you report problems with FireFox and Discord too.

In your situation I'd be looking for things like fsck and ntfsfix. Not to mention backing up all my files on another drive.

18:11 Reply: WAL/SHM files do not get deleted with ReadOnly flag (artifact: 3ac8cfca59 user: slavin)

The 'ReadOnly' status tells SQLite that it should not make any changes.

12:49 Reply: Segmentation fault in function isLikeOrGlob() (artifact: 39ccb68762 user: slavin)

Just wanted to praise this report.

  1. Test the right version of the source code: source tree, not amalgamation, current version.
  2. Find a genuine crash.
  3. Find how to reproduce the crash with 100% reliability.
  4. (optional) find suspicious lines of source code
  5. (optional) bisect previous versions to find which version introduced bug
  6. Send a polite and informative message to the correct forum including the above.

I've been receiving and submitting bug reports for the last 40 years and wish they were all this good. Apologies for interrupting your scheduled technical discussions.

2021-09-07
15:24 Reply: Automatic indexing (idle question) (artifact: 1912e63e6b user: slavin)

Not in this context, because the order of the columns matters.

I don't understand why you mentioned it in the first place.

2021-09-06
18:58 Reply: Automatic indexing (idle question) (artifact: 594bed7b7c user: slavin)

I was envisioning SQLite keeping a set of statistics, like the ones prepared by ANALYZE. In its simplest state, for each set of search/sort conditions (combinations of WHERE and ORDER BY), keep stats of how often it is used. Every so often analyze this data to figure out which indexes would be most useful. Then decide whether to make the changes right now or not.

Yes, there are a ton of considerations not included in the above, but that was my top-level understanding of how it would work.

And as stated upthread, making an index on each column is not a solution to any reasonable problem. When I find databases where people have done this they usually betray other misunderstandings of SQL.

2021-09-05
21:53 Post: Automatic indexing (idle question) (artifact: d6677078fd user: slavin)

I'm just pondering this. I don't have a specific project or use in mind.

Various parts of SQLite look like they're part of a move towards automatic indexing. I'm wondering how far we are away from this. The average programmer would not bother using CREATE INDEX … at all, it might be left to programmers with unusually good understanding of SQL. I'm thinking of SQLite not only creating its own indexes, but also deleting indexes which go unused, or should be subsumed by a longer index.

Presumably the programmer would somewhere set a number which changes the balance between filespace used and time saved. And another number which says whether actual index creation can be done by everyday API calls, or whether it should be left for runs of a special PRAGMA.

Is this a solved problem ? Or perhaps a problem that someone proved cannot be usefully solved ?

2021-09-04
14:51 Reply: The characters to be escaped in Sqlite3 to prevent Sql Injection (artifact: eca1100f5f user: slavin)

Tim's reply is the key one here. Prepared statements have no dangerous characters, including 0x00. But to your point, the apostrophe character is the only character you need to worry about, and you've already found what to do about it.

You might want to escape other characters including the percent sign if you're using user-sourced strings for searching, but that's a detail of how your program works, and a dangerous thing to do anyway. If you want to do it I suggest you read about the ESCAPE clause, as described in

https://sqlite.org/lang_expr.html#the_like_glob_regexp_and_match_operators

2021-09-03
13:52 Reply: What happens if I define LONGDOUBLE_TYPE as double? (artifact: 506dd87ea5 user: slavin)

That's one use for the test suite(s). Try it, run the entire test suite, and see what fails.

2021-09-01
12:32 Reply: Finding overlap of boxed coordinates (artifact: e9408c7224 user: slavin)

Can be done by SQLite using multiple CASE constructions, or nested IF statements. However, It's not going to be fast, compact, neat, or easy to debug. IMO it's a task which should be performed in a programming language rather than trying to make a complicated SQLite command.

Given two isometric (same axes) rectangles A and B, with boundaries l, r, b, t, intersection rectangle C is as follows:

C <-- A
IF B.l > C.l, C.b <-- B.l
IF B.b > C.b, C.b <-- B.b
IF B.r < C.r, C.r <-- B.r
IF B.t < C.t, C.t <-- B.t

If C.l >= C.r, there is no overlap
If C.b >= C.t, there is no overlap
Otherwise overlap is C.

Edge cases (e.g. left line of A is exactly the same as right line of B, or wrap around at -180/+180) must be considered within the context of your requirements.

Suppose you have the coordinates of a rectangle A, and your left longitude column of the database is indexed. You can quickly dismiss a swathe of rectangles B which won't intersect with A using

SELECT … WHERE B.l < A.r

2021-08-26
21:01 Reply: Recursively Import 10 GB sized csv file to sqlite fast without blocking reads (artifact: ed5f8061f2 user: slavin)

If blocking a database is your major problem, do the above CSV import to a different database file, then write your own code to copy rows from that database to the one being read. That way you can use whatever transaction sizes you want. Or perhaps the single optimised command INSERT INTO table SELECT ... will be good for you.

The ATTACH command is used to open two databases on the same connection.

2021-08-25
01:36 Reply: Why WAL file (-wal) may disappear? (artifact: fef23cf2ff user: slavin)

Something just occurred to me. SQLite does automatically delete the WAL file if there are no open connections to it. Is it possible that you're checking while all connections are closed ? Perhaps whatever SQLite library you're using closes connections automatically if your program is not in the foreground, or something.

2021-08-23
02:42 Reply: about "strict" mode (artifact: 2ef5e46b63 user: slavin)

There's an argument for not having STRICT TABLEs at all. Just have a LAX keyword, or whatever a better word would be.

To make the whole database STRICT use the PRAGMA. If you have some legacy table data you can't get rid of which violates STRICT ,declare the table as LAX before you use the PRAGMA. This automatically makes appropriate indexes and views LAX too.

00:37 Reply: Coverting 305GB CSV to sqlite database (artifact: 64e5159ff7 user: slavin)

I would test it with the top 100 lines first. Apart from that, you seem to know what you're doing.

2021-08-22
16:26 Post: New Hipp podcast (artifact: d768ddc945 user: slavin)

https://changelog.com/podcast/454

" This week, Richard Hipp returns to catch us up on all things SQLite, his single file webserver written in C called Althttpd, and Fossil – the source code manager he wrote and uses to manage SQLite development instead of Git. "

No transcript yet, but that channel generally adds them to the page later.

15:56 Post: About STRICT tables (artifact: ac9d8f7248 user: slavin)

A column about strict tables has appeared in the draft site:

https://www.sqlite.org/draft/stricttables.html

Possibly a good idea to raise a discussion on it. I'll open with a few things:

  1. The syntax to mark a table as strict puts the word STRICT at the end of the CREATE line. Is there a good reason why the word doesn't go after CREATE ? I'm likely to 'lose' a word at the end of the line: my eyes could pass over it and not see it.
  2. Could correct use of single and double quotes be enforced for the strict CREATE commands ? Or is that better associated with the strict PRAGMA ?
  3. Could the strict mode make all tables STRICT, whether declared STRICT or not ?

For reference, here's the page about strict mode:

https://sqlite.org/src/wiki?name=StrictMode

06:55 Reply: about "strict" mode (artifact: 7456cd275b user: slavin)

SQL engines which do support DATE, TIME, or DATETIME don't store in the database the thing you put in the SQL command. They convert it to an integer, and store that. For the sake of argument, you could say that all DATEs are stored as days since 1 January 1970, and all TIMEs are stored as milliseconds after midnight. When you ask for a value from a DATE or TIME field it gets produced as a string in one specific format.

So SQLite could introduce a DATE datatype by accepting only a string in one specific format. A later version of SQLite could accept dates in another format too. It just won't convert into the second format when you read a DATE value from a database. It won't break compatibility, either backward or forward.

2021-08-21
13:39 Reply: about "strict" mode (artifact: 99472fab32 user: slavin)

I'm not against your suggestion, but both the web page and you missed out a vital consideration, so I'm going to bring it up here.

There's a nasty question of whether the strict setting should be stored in each database file. Or has to be set as each connection is opened like the connection timeout. But that's beyond the scope of my post.

Consider an existing database which was created without strict mode. It has all the sorts of faults listed in https://sqlite.org/src/wiki?name=StrictMode: missing keys, table definitions and TRIGGER with the wrong quotes, NULL primary keys values, all that badness, and more that people haven't thought of yet. A new programmer takes over the project and uses their own code (not a custom utility like the CLI) to turn on strict mode. What happens ?

Should turning on strict mode involve a lengthy check for all these things ?

  1. Running the checks when switching to strict mode: Could take minutes or, rarely, hours.
  2. Not running the checks when switching to strict mode: All operations throughout all programs which access the database now have to deal with formerly unanticipated error reports from a lot of API calls.
  3. A strict setting is stored in each database file, and is set like PRAGMA page_size. To convert an existing database to strict mode you must VACUUM it. The extra checks take place during the VACUUM. VACUUM is changed so that it can return syntax error and other error results. VACUUM is changed so that it will check the integrity of foreign keys if strict mode has just been turned on.

Given that the check for strict-compliance could already be lengthy, and relies on the integrity of the database, should it start off with an integrity_check ?

2021-08-20
13:04 Reply: Trying to "Open Database" Safari History.db file and get Error: "could not open safari database file reason: unable to open.. (artifact: fcc0327ba1 user: slavin)

trying to use this software

The SQLite team made only one piece of software a non-programmer would use. It's very technical, and it's unlikely you used it. On a Mac you would have to be running Terminal.app to get at it.

I'm guessing you used SQLite Browser or something like that. Those programs are written by other people and the SQLite team can't support them. SQLite itself does not have error messages like 'unable to open database file'.

Can I ask why you're not using Safari to look at your Safari history ? That would seem the obvious way to do it. If I know why that isn't working I might be able to help.

Also, do you have the pages you need bookmarked, or just in your history ?

More ↓