I'm sure you're already onto this (given that your Google Search result mentions it also) but just in case ? : if the BLOBs are images, then there is a lot to be said for storing them as normal image files, with just a reference to them in the database (eg, the image filename or serial number).
I agree that sometimes this is outweighed by the convenience of having everything in a single file (but is a database ever truly just one file?!) or the extra robustness of having everything protected by database preimaging and transactions and rollbacks and backups.
1) Live with the Android limit (1mb cursor limit. Note: not row limit, cursor limit). Chunk your large data (split it into multiple pieces)
2) Try newest SQLCipher
Source: https://github.com/sqlcipher/android-database-sqlcipher/issues/47
3) Compile your and install own version of SQLite
I'm sure you're already onto this (given that your Google Search result mentions it also) but just in case ? : if the BLOBs are images, then there is a lot to be said for storing them as normal image files, with just a reference to them in the database (eg, the image filename or serial number).
I agree that sometimes this is outweighed by the convenience of having everything in a single file (but is a database ever truly just one file?!) or the extra robustness of having everything protected by database preimaging and transactions and rollbacks and backups.
Yes, I am absolutely with you, emexes! Thanks for your quick answer!!
In this case, my objects are images indeed - BUT : all of them are crypted with AES/SHA256. Therefore my wish, to have all such objects only in one DB. The crypted images may only be visible for someone who knows the correct password in order to decrypt them accordingly.
I suspect that will be the only solution.
But I'm not giving up hope yet.
Lol my whole body clenched at the thought of having to do this.
But a derivative approach might be to store the images in a different table of the same database file, and link your metadata table to them, so that the metadata query results aren't clogged up with MB of image data (if that is what's happening - I thought that the result set returned is simply pointers to the records, rather than the actual data).
Lol my whole body clenched at the thought of having to do this.
But a derivative approach might be to store the images in a different table of the same database file, and link your metadata table to them, so that the metadata query results aren't clogged up with MB of image data (if that is what's happening - I thought that the result set returned is simply pointers to the records, rather than the actual data).
But hey, If the sizes are smaller than 1 MB I can write and read.
If the sizes are bigger, then there is no exception while writing the data, but an exception (too big exception) if I try to read it.
So I guess that the writing works ok. My Insert doesnt work with DB cursor. Only the selecting of the data.
I also tried to work only with "Resultset"s .... but this is only a Wrapper for Cursors ... and I get the same exception.
1) Live with the Android limit (1mb cursor limit. Note: not row limit, cursor limit). Chunk your large data (split it into multiple pieces)
2) Try newest SQLCipher
Source: https://github.com/sqlcipher/android-database-sqlcipher/issues/47
3) Compile your and install own version of SQLite
Thx for your answer .... But I am not able to adapt and compile any SQLite sources or SQLite extensions.
Perhaps you can explain how to do this and then I can try.
You're probably right. I misread your description of the problem and naively assumed that it would be possible to read back at least a single record from the database.
Images are not ideal candidates for storing in databases, rather it is better to store something that indicates the image to be used (e.g. a path to the image). The image itself is comprised of bytes, often a very large number of bytes. Although SQLite can hold pretty large images.
The android SDK implementation, that extracts data into a Cursor is more restrictive.
The Cursor is effectively a buffer that holds a partial snapshot of the whole data. The underlying snapshot, a Cursor Window, is restricted in the Android SDK to 2M and that at a minimum must be able to hold a single row. You are guaranteed a failure if you have an image that is 2M or more. You are very likely to get a failure or issues if an image is say greater than 0.5M.
An example of an error where an image is too large for the Cursor Window, even though it has successfully been stored in the database is :-
Fix for Issue 2
There is no simple fix unless you can reduce the size of the images to an acceptable/manageable size.
The recommended approach is to store the images elsewhere and to then store the path or part thereof in the database.
I think I have a solution - probably a bad solution.
After taking a picture or after select a picture from Intent, I have access to the bitmap byte array.
With "WriteStream" command to output the bitmap data with a given quality level (format: JPEG / because PNG is lossless), I can reduce the byte data step for step (10% steps) until the size is lower than 1MB. The performance is really good because all manipulations of the bitmap is executed in the RAM. I imported a picture with 4000 x 3000 pixels (~ 3 MB file size) and I rewrite the bitmap data with 40% instead of 100% and the size was at one at about 730 KB. Also possible is a data reducing with percent values like a binary search ( <= 50% versus > 50%).
Tomorrow I will try this procedure - because it is not needed to have a super-quality picutre for printing or something like this. Only to see the content of the picture on android screen.
because it is not needed to have a super-quality picutre for printing or something like this. Only to see the content of the picture on android screen.
If no zooming/panning is required, you could also resize the image. I don’t think there are any 4000x3000 phone screens. That’s how iOS does it with their iCloud picture management. The full size is stored on iCloud and a reduced size (appropriate for the phone’s screen) is stored on the phone.
With "WriteStream" command to output the bitmap data with a given quality level (format: JPEG / because PNG is lossless), I can reduce the byte data step for step (10% steps) until the size is lower than 1MB. The performance is really good because all manipulations of the bitmap is executed in the RAM. I imported a picture with 4000 x 3000 pixels (~ 3 MB file size) and I rewrite the bitmap data with 40% instead of 100% and the size was at one at about 730 KB. Also possible is a data reducing with percent values like a binary search ( <= 50% versus > 50%).
Reduce the dimensions also, otherwise you will get some really strange artifacting going on (which is probably hidden at the moment when the image is downsampled to fit on the phone screen).
In fact, if the images are only for display on phones, why not reduce the dimensions to something approaching a typical phone resolution eg 800 x 600? (typing that gave me a SVGA spine tingle )
Lol while I was off making a test image, OliverA beat me to the same idea. Great minds think alike.
This is a 480k pixel (~800x600) JPEG at quality 80 with regular subsampling = 110237 bytes. Looks good to me. Still spewin about that Android SQLite cursor limit, tho.
This time you are wrong. It is a brilliant solution. Not only to skirt around the Android cursor problem, but also to keep your program from unnecessarily chewing up bandwidth and storage. ?
This time you are wrong. It is a brilliant solution. Not only to skirt around the Android cursor problem, but also to keep your program from unnecessarily chewing up bandwidth and storage. ?
Lol while I was off making a test image, OliverA beat me to the same idea. Great minds think alike.
This is a 480k pixel (~800x600) JPEG at quality 80 with regular subsampling = 110237 bytes. Looks good to me. Still spewin about that Android SQLite cursor limit, tho.
Thank you both for the great help. I am very annoyed about the cursor limit. Nevertheless, I think it's a combination between image quality and image resolution that leads to the goal here.