B4J Library [B4X] KVS2 / KeyValueStore 2 - Simple & Powerful Local Datastore

Status
Not open for further replies.
Recommended to use the newer b4xlib: https://www.b4x.com/android/forum/threads/b4x-kvs2-keyvaluestore2-library.120234/
KeyValueStore is a persistent key/value based data store. It is similar to the useful Map collection, however unlike Map which stores the data in memory, KVS stores the data in a database. This means that you don't need to worry about losing data or saving the state when the program ends.

This version replaces the older version. It is not backwards compatible. You cannot use it with databases created with the previous version.

The main differences between v2 and v1:
The new version is based on B4XSerializator to serialize the values and on B4XCipher to encrypt it.
This means that the data can be shared between B4A, B4J and B4i. For example you can create the data store in B4J and embed it in your mobile app.
B4XSerializator is also faster and simpler to use.

Using KVS is similar to using a Map. You initialize it once (use the Starter service in B4A) and then you can put or get items with Put, Get or GetDefault methods.
You can use PutEncrypted to encrypt the value before it is stored. Use GetEncrypted to get an encrypted value.
If you want to put bitmaps then use PutBitmap and GetBitmap.

The supported types of objects are:

Lists, Maps, Strings, primitives (numbers), user defined types and arrays (only arrays of bytes and arrays of objects are supported).
Custom types should be declared in the main module.
Including combinations of these types (a list that holds maps for example).

KeyValueStore depends on the following libraries: SQL, RandomAccessFile and B4XEncryption (iEncryption on B4i).
Note that in B4J you need to download the bouncy castle jar and add the following two lines to the main module:
B4X:
#AdditionalJar: sqlite-jdbc-3.7.2
#AdditionalJar: bcprov-jdk15on-154


A B4A example is attached. The class module is compatible with B4A, B4J and B4i.

Tip: Check CloudKVS for an auto-synchronizing solution: https://www.b4x.com/android/forum/threads/b4x-cloudkvs-synchronized-key-value-store.63536/#content

Updates:

- V2.20 - Adds support for GetMapAsync and PutMapAsync. These methods allow to asynchronously insert or retrieve multiple items.
Examples:
B4X:
'getting all items:
Wait For (Starter.kvs.GetMapAsync(Starter.kvs.ListKeys)) Complete (Result As Map)
Log(Result)
'getting specific items:
Wait For (Starter.kvs.GetMapAsync(Array("Key1", "Key2", "Key3")) Complete (Result As Map)
Log(Result)

Note that starting from B4A v8.0 KeyValueStore2 is included as an internal library.
 

Attachments

  • B4A_KVS2.zip
    9.8 KB · Views: 2,888
  • KeyValueStore.bas
    4.8 KB · Views: 2,573
Last edited:

ilan

Expert
Licensed User
Longtime User
hi

i have 2 questions related to KVS please

1) when i remove entries or delete all entries from the database the file size does not change.
so if the database had 10 entries including images and was 10mb after deleting everything from the database the db file has the same size, why?

B4X:
database.DeleteAll

B4X:
Public Sub DeleteAll
    sql1.ExecNonQuery("DROP TABLE main")
    CreateTable
End Sub

2) when i put an image to the database with the size of 60kb the file size is much bigger (about 214kb) why?

i user:

B4X:
    Dim out As OutputStream
    out.InitializeToBytesArray(0)
    Value.WriteToStream(out)
    Put(Key, out.ToBytesArray)
    out.Close

thanx
 
Last edited:

ilan

Expert
Licensed User
Longtime User
ok for the first question i have the answer

B4X:
sql1.ExecNonQuery("VACUUM")

but not for the second. if i put an image with size 61KB why do my database file size increase to 214kb ?
 

rboeck

Well-Known Member
Licensed User
Longtime User
I think its a normal database function; internaly the often use pages; so sometime for one record a new page is used and the database size increases. With next insert the database size is possible the same. The database try to optimize for speed and not for space, you see it cleary, that zipping databases has the most effect.
 

ilan

Expert
Licensed User
Longtime User
I think its a normal database function; internaly the often use pages; so sometime for one record a new page is used and the database size increases. With next insert the database size is possible the same. The database try to optimize for speed and not for space, you see it cleary, that zipping databases has the most effect.

1.6 mb images made a db file of 14 mb :(
 

DonManfred

Expert
Licensed User
Longtime User
Add the class from post #1 to your project and use it then...
 

OliverA

Expert
Licensed User
Longtime User
Yes but how do you declare and initialize it since B4J does not have a starter service.
See attached. Please read the notes in the main file.
 

Attachments

  • b4j_kvs_example_nonui.zip
    3 KB · Views: 637

Ricky D

Well-Known Member
Licensed User
Longtime User
Thanks Erel. I just came across this and it's excellent :)
 

asubias

Member
Licensed User
Hi, I get this error with the function getEncrypted
B4X:
javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT

The stored data is an IP address

Thank you in advance :)
 
Status
Not open for further replies.
Top