﻿B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=9.5
@EndOfDesignText@
#IgnoreWarnings:12
Sub Class_Globals
	Private db As BANanoSQL
	Private sDB As String
	Private BANano As BANano			'ignore
End Sub

'create an offline IndexedDB database
'<code>
'kvs.Initialize("mykvs")
'</code>
Public Sub Initialize(dbName As String) As BANanoKeyStore
	'open the database
	sDB = dbName
	Dim xName As String = dbName
	db.OpenWait(xName, xName)
	BANano.Await(CreateTable)
	Return Me
End Sub

'creates the main table (if it does not exist)
private Sub CreateTable
	'create the table
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	rs.SchemaCreateTable
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	rs = Null
End Sub

'Deletes all data from the store.
'<code>
'BANano.Await(kvs.DeleteAll)
'</code>
Public Sub DeleteAll
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	rs.DropTable
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	rs = Null
	BANano.Await(CreateTable)
End Sub

'Tests whether a key is available in the store.
'<code>
'Dim res as boolean = BANano.Await(kvs.ContainsKey("a"))
'</code>
Public Sub ContainsKey(Key As String) As Boolean
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	Dim fw As Map = CreateMap()
	fw.Put("k", Key)
	rs.SelectWhere(Array("k"), fw, Array("="), Array("k"))
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	If rs.affectedRows > 0 Then
		Return True
	Else
		Return False
	End If
End Sub

'<code>
'BANano.Await(kvs.Put("a", 1))
'</code>
Public Sub Put(Key As String, Value As Object) As Boolean
	'does the record exist
	Dim bThere As Boolean = BANano.Await(ContainsKey(Key))
	'convert to json
	Dim vToJson As String = BANano.ToJson(Value)
	
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	rs.PrepareRecord
	rs.SetField("k", Key)
	rs.SetField("v", vToJson)
	If bThere Then
		rs.Update(Key)
	Else
		rs.Insert
	End If	
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	rs = Null
	Return True
End Sub

'get a value using key
'<code>
'Dim res As String = BANano.Await(kvs.get("name"))
'</code>
Public Sub Get(Key As String) As Object
	Dim result As Object = Null
	Dim vFromJSON As String = ""
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	Dim fw As Map = CreateMap()
	fw.Put("k", Key)
	rs.SelectWhere(Array("v"), fw, Array("="), Array("k"))
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	If rs.NextRow Then
		rs.MoveFirst
		result = rs.GetString("v")
		vFromJSON = BANano.FromJson(result)
		result = vFromJSON
	End If
	rs = Null
	Return result
End Sub


'Asynchronously retrieves the values from the store for specific keys
'The result is a map with the keys and values.
'<code>
'Wait For (kvs.GetMapAsync(Array("a", "b", "c"))) Complete (Result As Map)
'</code>
Public Sub GetMapAsync (Keys As List) As Map
	Dim sb As StringBuilder
	sb.Initialize
	sb.Append("SELECT k, v FROM main WHERE ")
	For i = 0 To Keys.Size - 1
		If i > 0 Then sb.Append(" OR ")
		sb.Append(" k = ? ")
	Next
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	rs.Execute(sb.ToString)
	rs.result = db.ExecuteWait(rs.query, Keys)
	rs.FromJSON
	Dim m As Map
	m.Initialize
	Do While rs.NextRow
		Dim k As String = rs.GetString("k")
		Dim v As String = rs.GetString("v")
		v = BANano.FromJson(v)
		m.Put(k, v)
	Loop
	rs = Null
	Return m
End Sub

'Asynchronously retrieves the values from the store for all keys
'The result is a map with the keys and values.
'<code>
'Wait For (kvs.GetMapAllAsync) Complete (Result As Map)
'</code>
Public Sub GetMapAllAsync As Map
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	rs.SelectEverything
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	Dim m As Map
	m.Initialize
	Do While rs.NextRow
		Dim k As String = rs.GetString("k")
		Dim v As String = rs.GetString("v")
		v = BANano.FromJson(v)
		m.Put(k, v)
	Loop
	rs = Null
	Return m
End Sub


'Asynchronously inserts the keys and values from the map.
'Note that each pair is inserted as a separate item.
'Call it with Wait For if you want to wait for the insert to complete.
'<code>
'Wait For (kvs.GetMapAsync(CreateMap("a":1, "b":2, "c":3)))) Complete (Result As Boolean)
'</code>
Public Sub PutMapAsync (thisMap As Map) As Boolean
	For Each k As String In thisMap.Keys
		Dim v As String = thisMap.Get(k)
		BANano.Await(Put(k, v))
	Next
	Return True
End Sub

'<code>
'Dim res As String = BANano.Await(kvs.GetDefault("a", 1))
'</code>
Public Sub GetDefault(Key As String, DefaultValue As Object) As Object
	Dim res As Object = BANano.await(Get(Key))
	If res = Null Then Return DefaultValue
	Return res
End Sub

'Returns a list with all the keys.
'<code>
'Dim res As List = BANano.Await(kvs.ListKeys)
'</code>
Public Sub ListKeys As List
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	rs.SelectAll(Array("k"), Array("k"))
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	Dim res As List
	res.Initialize
	Do While rs.NextRow
		res.Add(rs.GetString("k"))
	Loop
	rs = Null
	Return res
End Sub

'Removes the key and value mapped to this key.
'<code>
'BANano.Await(kvs.Remove("a"))
'</code>
Public Sub Remove(Key As String)
	Dim rs As BANanoALASQLE
	rs.Initialize(sDB, "main", "k", "")
	rs.SchemaAddText(Array("k", "v"))
	rs.Delete(Key)
	rs.result = db.ExecuteWait(rs.query, rs.args)
	rs.FromJSON
	rs = Null
End Sub