﻿B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=9.8
@EndOfDesignText@
#IgnoreWarnings:12
#Event: Changes (e As Map)
#Event: Change (Action As String, Record As Map, TableName As String)
#Event: AuthChange (Token As String, Model As Map)

Private Sub Class_Globals
	Public const DB_BOOL As String = "BOOL"
	Public const DB_INT As String = "INT"
	Public const DB_FILE As String = "FILE"
	Public const DB_STRING As String = "STRING"
	Public const DB_REAL As String = "REAL"
	Public const DB_BLOB As String = "BLOB"
	Public const DB_FLOAT As String = "FLOAT"
	Public const DB_INTEGER As String = "INTEGER"
	Public const DB_TEXT As String = "TEXT"
	Public const DB_DOUBLE As String = "DOUBLE"
	Public const DB_NUMBER As String = "NUMBER"
	Public const DB_RELATION As String = "RELATION"
	Public const DB_JSON As String = "JSON"
	Public const DB_DATE As String = "DATE"
	'
	Private mCallBack As Object			'ignore
	Private baseURL As String
	Private whereField As Map
	Private ops As List
	Private orderByL As List
	Private flds As List
	Public RowCount As Int
	Private lastPosition As Int
	Public Record As Map
	Public result As List
	Private BANano As BANano 'ignore
	Public Success As Boolean
	Private client As BANanoObject
	Private mEvent As String
	Private sTableName As String
	Public Tag As Object
	Public Schema As Map
	Public PrimaryKey As String
	Public DisplayField As String
	Public Singular As String
	Public Plural As String
	Public DisplayValue As String
	Public UserProfile As profileType
	Private formData As BANanoObject
	Private fileFields As List
	Public IsAuthenticated As Boolean
	Private combineL As List
	Public ShowLog As Boolean
	Public Operations as list
End Sub

'<code>
''initialize the connection to pocketbase with a collection to access
'pb.Initialize(Me, "pb", "http://127.0.0.1:8090", "projects")
'pb.SchemaAddText(Array("id", "name"))
'</code>
Public Sub Initialize(Module As Object, eventName As String, url As String, TableName As String) As SDUIPocketBase
	sTableName = TableName
	mCallBack = Module
	baseURL = url
	whereField.Initialize
	ops.Initialize
	orderByL.Initialize
	flds.Initialize
	Record.Initialize
	lastPosition = -1
	result.Initialize
	mEvent = eventName
	PrimaryKey = "id"
	Schema.Initialize
	client.Initialize2("PocketBase", baseURL)
	SchemaAddText1("id")
	fileFields.Initialize
	combineL.Initialize
	ShowLog = False
	
	If SubExists(Module, $"${eventName}_AuthChange"$) Then
		Dim stoken As String
		Dim smodel As Object
		Dim aCB As BANanoObject = BANano.CallBack(Module, $"${eventName}_AuthChange"$, Array(stoken, smodel))
		client.GetField("authStore").RunMethod("onChange", aCB)
	End If
	Return Me
End Sub

'for file fields, get its url
Sub BuildFileURL(id As String, fileName As String) As String
	Dim fPath As String = $"${baseURL}/api/files/${sTableName}/${id}/${fileName}"$
	Return fPath
End Sub

'for file fields, get its thumbnail
Sub BuildFileThumbNailURL(id As String, fileName As String, width As String, height As String) As String
	Dim fPath As String = $"${baseURL}/api/files/${sTableName}/${id}/${fileName}?thumb=${width}x${height}"$
	Return fPath
End Sub

Sub getFileURL(rec As Map, filesFieldName As String) As String
	'get list of files
	Dim docs As List = rec.Get(filesFieldName)
	'get the first file
	Dim firstFilename As String = docs.Get(0)
	'
	Dim url As String = client.RunMethod("getFileUrl", Array(rec, firstFilename)).result
	Return url
End Sub

Sub setTableName(s As String)
	sTableName = s
End Sub

Sub SchemaAddBlob(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_BLOB)
	Next
	Return Me
End Sub

Sub SchemaAddFile(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_FILE)
	Next
	Return Me
End Sub

Sub SchemaAddFile1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_FILE)
	Return Me
End Sub

Sub SchemaAddBlob1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_BLOB)
	Return Me
End Sub
'schema add boolean
Sub SchemaAddBoolean(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_BOOL)
	Next
	Return Me
End Sub
Sub SchemaAddBoolean1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_BOOL)
	Return Me
End Sub
Sub SchemaAddDouble1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_DOUBLE)
	Return Me
End Sub
'add double fields
Sub SchemaAddDouble(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_DOUBLE)
	Next
	Return Me
End Sub
Sub SchemaAddFloat1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_FLOAT)
	Return Me
End Sub
Sub SchemaAddFloat(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_FLOAT)
	Next
	Return Me
End Sub
Sub SchemaAddText1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_STRING)
	Return Me
End Sub
Sub SchemaAddText(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_STRING)
	Next
	Return Me
End Sub
Sub SchemaAddInt1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_INT)
	Return Me
End Sub
Sub SchemaAddInt(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_INT)
	Next
	Return Me
End Sub

Sub SchemaAddNumber(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_NUMBER)
	Next
	Return Me
End Sub

Sub SchemaAddNumber1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_NUMBER)
	Return Me
End Sub

Sub SchemaAddRelation(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_RELATION)
	Next
	Return Me
End Sub

Sub SchemaAddRelation1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_RELATION)
	Return Me
End Sub

Sub SchemaAddJson(bools As List) As SDUIPocketBase
	For Each b As String In bools
		Schema.Put(b, DB_JSON)
	Next
	Return Me
End Sub

Sub SchemaAddJson1(b As String) As SDUIPocketBase
	Schema.Put(b, DB_JSON)
	Return Me
End Sub

'get records from a collection
'<code>
'BANano.Await(pbComponents.SELECT_ALL)
'BANano.Await(pb.EstablishFileUrl("fileobj", "fileurl"))
'Do While pbComponents.NextRow
'Dim rec As Map = pbComponents.Record
'Dim sid As String = pbComponents.GetString("id")
'Loop
'</code>
Sub SELECT_ALL As List
	If ShowLog Then
		Log($"SDUIPocketBase.SELECT_ALL"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.SELECT_ALL. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	lastPosition = -1
	result.Initialize
	Dim qsort As String = SDUIShared.Join(",", orderByL)
	'
	Dim nl As List
	nl.Initialize
	Try
		Dim opt As Map = CreateMap()
		If qsort <> "" Then opt.Put("sort", qsort)
		result = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("getFullList", Array(200, opt)))
	Catch
	End Try			'ignore
	RowCount = result.Size
	Return result
End Sub

'get records from a collection
'<code>
'BANano.Await(pbComponents.SELECT_ALL_USERS)
'BANano.Await(pb.EstablishFileUrl("fileobj", "fileurl"))
'Do While pbComponents.NextRow
'Dim rec As Map = pbComponents.Record
'Dim sid As String = pbComponents.GetString("id")
'Loop
'</code>
Sub SELECT_ALL_USERS As List
	If ShowLog Then
		Log($"SDUIPocketBase.SELECT_ALL_USERS"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.SELECT_ALL. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	lastPosition = -1
	result.Initialize
	Dim qsort As String = SDUIShared.Join(",", orderByL)
	'
	Dim nl As List
	nl.Initialize
	Try
		Dim opt As Map = CreateMap()
		If qsort <> "" Then opt.Put("sort", qsort)
		result = BANano.Await(client.RunMethod("collection", "users").RunMethod("getFullList", Array(200, opt)))
	Catch
	End Try			'ignore
	RowCount = result.Size
	Return result
End Sub

'get records from a collection
'<code>
'BANano.Await(pbComponents.SELECT_ALL_ADMINS)
'BANano.Await(pb.EstablishFileUrl("fileobj", "fileurl"))
'Do While pbComponents.NextRow
'Dim rec As Map = pbComponents.Record
'Dim sid As String = pbComponents.GetString("id")
'Loop
'</code>
Sub SELECT_ALL_ADMINS As List
	If ShowLog Then
		Log($"SDUIPocketBase.SELECT_ALL_ADMINS"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.SELECT_ALL_ADMINS. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	lastPosition = -1
	result.Initialize
	Dim qsort As String = SDUIShared.Join(",", orderByL)
	'
	Dim nl As List
	nl.Initialize
	Try
		Dim opt As Map = CreateMap()
		If qsort <> "" Then opt.Put("sort", qsort)
		result = BANano.Await(client.GetField("admins").RunMethod("getFullList", Array(200, opt)))
	Catch
	End Try			'ignore
	RowCount = result.Size
	Return result
End Sub

'get all table names
Sub SELECT_ALL_COLLECTIONS_NAMES As List
	If ShowLog Then
		Log($"SDUIPocketBase.SELECT_ALL_COLLECTIONS_NAMES"$)
	End If
	Dim tblNames As List = BANano.Await(SELECT_ALL_COLLECTIONS)
	Dim tbNames As List = SDUIShared.ListOfMapsGetProperty(tblNames, "name")
	Return tbNames
End Sub

'get records from a collection
'<code>
'BANano.Await(pbComponents.SELECT_ALL_COLLECTIONS)
'Do While pbComponents.NextRow
'Dim rec As Map = pbComponents.Record
'Dim sid As String = pbComponents.GetString("id")
'Loop
'</code>
Sub SELECT_ALL_COLLECTIONS As List
	If ShowLog Then
		Log($"SDUIPocketBase.SELECT_ALL_COLLECTIONS"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.SELECT_ALL_COLLECTIONS. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	lastPosition = -1
	result.Initialize
	Dim qsort As String = SDUIShared.Join(",", orderByL)
	'
	Dim nl As List
	nl.Initialize
	Try
		Dim opt As Map = CreateMap()
		If qsort <> "" Then opt.Put("sort", qsort)
		result = BANano.Await(client.GetField("collections").RunMethod("getFullList", Array(200, opt)))
	Catch
	End Try			'ignore
	RowCount = result.Size
	Return result
End Sub

'sub-scribe to changes in table
Sub Subscribe(Module As Object, TableName As String)
	If ShowLog Then
		Log($"SDUIPocketBase.Subscribe(${TableName})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.Subscribe. Please execute SchemaAdd?? first to define your table schema!"$)
		Return
	End If
	Try
		Dim eName As String = $"${mEvent}_changes"$
		If SubExists(Module, eName) Then
			Dim e As Object
			Dim cb As BANanoObject = BANano.CallBack(Module, $"${mEvent}_changes"$, Array(e))
			client.RunMethod("collection", TableName).RunMethod("subscribe", Array("*", cb))
		End If
		'
		Dim eName1 As String = $"${mEvent}_change"$
		If SubExists(mCallBack, eName1) Then
			Dim e As Object
			Dim cb As BANanoObject = BANano.CallBack(Me, "HandleChange", Array(e))
			client.RunMethod("collection", TableName).RunMethod("subscribe", Array("*", cb))
		End If
		
	Catch
	End Try			'ignore
End Sub

Private Sub HandleChange (e As Map)
	Dim saction As String = e.Get("action")
	Dim record1 As Map = e.Get("record")
	Dim sTableName1 As String = SDUIShared.GetRecuRsive(e, "record.collectionName")
	BANano.CallSub(mCallBack, $"${mEvent}_change"$, Array(saction, record1, sTableName1))
End Sub


'subscribe to a record
Sub SubscribeToRecord(Module As Object, TableName As String, id As String)
	If ShowLog Then
		Log($"SDUIPocketBase.SubscribeToRecord(${TableName},${id})"$)
	End If
	Try
		Dim eName As String = $"${mEvent}_changes"$
		If SubExists(Module, eName) Then
			Dim e As Object
			Dim cb As BANanoObject = BANano.CallBack(Module, $"${mEvent}_changes"$, Array(e))
			client.RunMethod("collection", TableName).RunMethod("subscribe", Array(id, cb))
		Else
			BANano.Console.Warn($"SDUIPocketBase.SubscribeToRecord.'${mEvent}_changes' callback is missing!"$)
		End If
	Catch
	End Try			'ignore
End Sub

'unsubscribe
Sub UnSubscribe(TableName As String)
	If ShowLog Then
		Log($"SDUIPocketBase.UnSubscribe(${TableName})"$)
	End If
	Try
		client.RunMethod("collection", TableName).RunMethod("unsubscribe", "*")
	Catch
	End Try			'ignore
End Sub

Sub UnSubscribeToRecord(TableName As String, id As String)
	If ShowLog Then
		Log($"SDUIPocketBase.UnSubscribeToRecord(${TableName},${id})"$)
	End If
	Try
		client.RunMethod("collection", TableName).RunMethod("unsubscribe", id)
	Catch
	End Try			'ignore
End Sub

'record is saved as json string
'returns the record id
'<code>
'BANano.Await(pb.CREATE_OR_UPDATE)
'</code>
Sub CREATE_OR_UPDATE As String
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_OR_UPDATE"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.CREATE_OR_UPDATE. Please execute SchemaAdd?? first to define your table schema!"$)
		Return ""
	End If
	Try
		'does the record exist
		Dim Key As String = Record.GetDefault("id", "")
		DisplayValue = Record.GetDEfault(DisplayField, "")
		'this will be blank if we are using PB own keys
		'if we use our keys, those need to be 15 in length
		Dim bThere As Boolean = False
		If Key <> "" Then
			bThere = BANano.Await(ContainsKey(Key))
			If ShowLog Then
				Log($"SDUIPocketBase.CREATE_OR_UPDATE:ContainsKey(id,${Key},${bThere})"$)
			End If
		End If
		'does not exit
		If bThere = False Then
			'create the record
			Dim res As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("create", Array(Record)))
			If res.ContainsKey("id") Then
				Dim k As String = res.Get("id")
				Return k
			End If
			Return ""
		Else
			'execute an update
			Dim id As String = Record.Get("id")
			Dim r As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("update", Array(id, Record)))
			If r.ContainsKey("id") Then
				Dim k As String = r.Get("id")
				Return k
			End If	
			Return ""
		End If	
	Catch
		Return ""
	End Try			' ignore
End Sub

'record is saved as json string
'returns the record id
'<code>
'BANano.Await(pb.CREATE_OR_UPDATE_BY_FIELD("email"))
'</code>
Sub CREATE_OR_UPDATE_BY_FIELD(fldName As String) As String
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_OR_UPDATE_BY_FIELD(${fldName})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.CREATE_OR_UPDATE_BY_FIELD. Please execute SchemaAdd?? first to define your table schema!"$)
		Return ""
	End If
	Try
		'does the record exist
		Dim sKey As String = Record.GetDefault(fldName, "")
		DisplayValue = Record.GetDEfault(DisplayField, "")
		'this will be blank if we are using PB own keys
		'if we use our keys, those need to be 15 in length
		Dim bThere As Boolean = False
		Dim id As String = ""
		If sKey <> "" Then
			Dim rec As Map = BANano.Await(READ_BY_STRING(fldName, sKey))
			id = rec.GetDefault("id", "")
			If id <> "" Then bThere = True
		End If
		'does not exit
		If bThere = False Then
			'create the record
			Dim res As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("create", Array(Record)))
			If res.ContainsKey("id") Then
				Dim k As String = res.Get("id")
				Return k
			End If
			Return ""
		Else
			'execute an update
			Record.Put("id", id)
			Dim r As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("update", Array(id, Record)))
			If r.ContainsKey("id") Then
				Dim k As String = r.Get("id")
				Return k
			End If	
			Return ""
		End If	
	Catch
		Return ""
	End Try			' ignore
End Sub

Sub UPDATE_FILE(sid As String, fileField As String, fileObj As Map) As String
	'prepare FormData
	formData.Initialize2("FormData", Null)
	formData.RunMethod("append", Array(fileField, fileObj))
	Dim r As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("update", Array(sid, formData)))
	If r.ContainsKey("id") Then
		Dim k As String = r.Get("id")
		Return k
	End If
	Return ""
End Sub


'record is saved as json string
'returns the record id
'<code>
'pb.PrepareRecord
'pb.SetField("id", 1)
'pb.SetField("username", "user1")
'BANano.Await(pb.CREATE)
'</code>
Sub CREATE As String
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.CREATE. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Try
		Dim m As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("create", Array(Record)))
		If m.ContainsKey("id") Then
			Dim k As String = m.Get("id")
			Return k
		End If
		Return ""
	Catch
		Return ""
	End Try
End Sub
'
'ceate a ecod using fomdata
'<code>
'pb.PrepareForm
'pb.SetFormFile("fileobj", fileObj)
'pb.SetFormField("username", "user1")
'dim m As map = BANano.Await(pb.CREATE_FORMDATA("fileobj"))
'dim id as String = m.get("id")
'dim url as String = m.get("fileurl")
'</code>
Sub CREATE_FORMDATA(fileField As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_FORMDATA"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.CREATE_FORMDATA. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Try
		Dim m As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("create", Array(formData)))
		Dim firstFilename As String = m.Get(fileField)
		Dim url As String = client.GetField("files").RunMethod("getUrl", Array(m, firstFilename)).result
		m.Put("fileurl", url)
		Return m
	Catch
		Return Null
	End Try
End Sub

'<code>
'BANano.Await(pb.EstablishFileUrl("fileobj", "fileurl"))
'</code>
Sub EstablishFileUrl(fileField As String, urlField As String)
	Dim rTot As Int = result.Size - 1
	Dim rCnt As Int
	For rCnt = 0 To rTot
		Dim r As Map = result.Get(rCnt)
		Dim firstFilename As String = r.Get(fileField)
		Dim url As String = client.GetField("files").RunMethod("getUrl", Array(r, firstFilename)).result
		r.Put(urlField, url)
		result.Set(rCnt, r)
	Next
End Sub

'<code>
'BANano.Await(pb.EstablishFileUrl1(rec, "fileobj", "fileurl"))
'</code>
Sub EstablishFileUrl1(rec As Map, fileField As String, urlField As String)
	Dim firstFilename As String = rec.Get(fileField)
	Dim url As String = client.GetField("files").RunMethod("getUrl", Array(rec, firstFilename)).result
	rec.Put(urlField, url)
End Sub


'record is saved as json string
'returns the record id
'<code>
'pb.PrepareForm
'pb.SetFormField("id", 1)
'pb.SetFormFile("avatar", fileObj)
'pb.SetFormField("username", "user1")
'BANano.Await(pb.UPDATE_FORMDATA)
'</code>
Sub UPDATE_FORMDATA As String
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_FORMDATA"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.UPDATE. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Try
		Dim id As String = Record.Get("id")
		Dim r As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("update", Array(id, formData)))
		If r.ContainsKey("id") Then
			Dim k As String = r.Get("id")
			Return k
		End If
		Return ""
	Catch
		Return ""
	End Try
End Sub


Sub GET_ID_BY_FIELD(fldName As String, fldValue As String) As String
	If ShowLog Then
		Log($"SDUIPocketBase.GET_ID_BY_FIELD(${fldName},${fldValue})"$)
	End If
	Dim rec As Map = BANano.Await(READ_BY_STRING(fldName, fldValue))
	Dim sid As String = rec.GetDefault("id", "")
	Return sid
End Sub


Sub UPDATE_BY_STRING(fldName As String, fldValue As String) As String
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_BY_STRING(${fldName},${fldValue})"$)
	End If
	Dim rec As Map = BANano.Await(READ_BY_STRING(fldName, fldValue))
	Dim sid As String = rec.GetDefault("id", "")
	Record.Put("id", sid)
	Dim nid As String = BANano.Await(UPDATE)
	Return nid
End Sub

Sub UPDATE_BY(fldName As String, fldValue As String) As String
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_BY(${fldName},${fldValue})"$)
	End If
	Dim rec As Map = BANano.Await(READ_BY(fldName, fldValue))
	Dim sid As String = rec.GetDefault("id", "")
	Record.Put("id", sid)
	Dim nid As String = BANano.Await(UPDATE)
	Return nid
End Sub

'record is saved as json string
'returns the record id
'<code>
'pb.PrepareRecord
'pb.SetField("id", 1)
'pb.SetField("username", "user1")
'BANano.Await(pb.UPDATE)
'</code>
Sub UPDATE As String
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.UPDATE. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Try
		Dim id As String = Record.Get("id")
		Dim r As Map = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("update", Array(id, Record)))
		If r.ContainsKey("id") Then
			Dim k As String = r.Get("id")
			Return k
		End If
		Return ""
	Catch
		Return ""
	End Try
End Sub


'get a value using key
'<code>
'Dim res As Map = BANano.Await(pb.READ("name"))
'</code>
Sub READ(id As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.READ(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.READ. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Dim m As Map = CreateMap()
	Try
		m = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("getOne", Array(id)))
		Record = m
		Return m
	Catch
		Record = m
		Return m
	End Try
End Sub

'get a value using key
'<code>
'Dim res As Map = BANano.Await(pb.READ_USER("name"))
'</code>
Sub READ_USER(id As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.READ_USER(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.READ_USER. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Dim m As Map = CreateMap()
	Try
		m = BANano.Await(client.RunMethod("collection", "users").RunMethod("getOne", Array(id)))
		Record = m
		Return m
	Catch
		Record = m
		Return m
	End Try
End Sub

'get a value using key
'<code>
'Dim res As Map = BANano.Await(pb.READ_ADMIN("name"))
'</code>
Sub READ_ADMIN(id As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.READ_ADMIN(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.READ_USER. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Dim m As Map = CreateMap()
	Try
		m = BANano.Await(client.GetField("admins").RunMethod("getOne", Array(id)))
		Record = m
		Return m
	Catch
		Record = m
		Return m
	End Try
End Sub

'get a value using key
'<code>
'Dim res As Map = BANano.Await(pb.READ_COLLECTION("name"))
'</code>
Sub READ_COLLECTION(id As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.READ_COLLECTION(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.READ_USER. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	Dim m As Map = CreateMap()
	Try
		m = BANano.Await(client.GetField("collections").RunMethod("getOne", Array(id)))
		Record = m
		Return m
	Catch
		Record = m
		Return m
	End Try
End Sub

'<code>
'Dim result As Map = BANano.Await(pbComponents.READ_BY_STRING("name", "xxx"))
'pb.EstablishFileUrl1(result, "fileobj", "fileurl")
'</code>
Sub READ_BY_STRING(fldName As String, fldValue As Object) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.READ_BY_STRING(${fldName},${fldValue})"$)
	End If
	CLEAR_WHERE
	ADD_WHERE_STRING(fldName, "=", fldValue)
	Dim res As List = BANano.Await(SELECT_WHERE)
	Dim m As Map = CreateMap()
	If res.size = 0 Then
		Return m
	Else
		m = res.Get(0)
		Return m
	End If
End Sub

Sub READ_ID_BY_STRING(fldName As String, fldValue As String) As String
	If ShowLog Then
		Log($"SDUIPocketBase.READ_ID_BY_STRING(${fldName},${fldValue})"$)
	End If
	Dim rec As Map = BANano.Await(READ_BY_STRING(fldName, fldValue))
	Dim sid As String = rec.GetDefault("id", "")
	Return sid
End Sub

'<code>
'Dim result As Map = BANano.Await(pbComponents.READ_BY("name", "xxx"))
'pb.EstablishFileUrl1(result, "fileobj", "fileurl")
'</code>
Sub READ_BY(fldName As String, fldValue As Object) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.READ_BY(${fldName},${fldValue})"$)
	End If
	CLEAR_WHERE
	ADD_WHERE(fldName, "=", fldValue)
	Dim res As List = BANano.Await(SELECT_WHERE)
	Dim m As Map = CreateMap()
	If res.size = 0 Then
		Return m
	Else
		m = res.Get(0)
		Return m
	End If
End Sub


'Tests whether a key is available in the store.
'<code>
'Dim res as boolean = BANano.Await(pb.ContainsKey("a"))
'</code>
Sub ContainsKey(id As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.ContainsKey(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.ContainsKey. Please execute SchemaAdd?? first to define your table schema!"$)
		Return ""
	End If
	CLEAR_WHERE
	ADD_WHERE("id", "=", $"'${id}'"$)
	Dim res As List = BANano.Await(SELECT_WHERE)
	If res.Size = 0 Then
		Return False
	Else
		Return True
	End If
End Sub

Sub ContainsField(fldName As String, id As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.ContainsField(${fldName},${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.ContainsField. Please execute SchemaAdd?? first to define your table schema!"$)
		Return ""
	End If
	CLEAR_WHERE
	ADD_WHERE(fldName, "=", $"'${id}'"$)
	Dim res As List = BANano.Await(SELECT_WHERE)
	If res.Size = 0 Then
		Return False
	Else
		Return True
	End If
End Sub


'Returns a list with all the keys.
'<code>
'Dim res As List = BANano.Await(pb.ListKeys)
'</code>
Public Sub ListKeys As List
	If ShowLog Then
		Log($"SDUIPocketBase.ListKeys"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.ListKeys. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	CLEAR_WHERE
	result = BANano.Await(SELECT_WHERE)
	Dim res As List
	res.Initialize
	For Each rec As Map In result
		Dim k As String = rec.GetDefault("id", "")
		k = SDUIShared.CStr(k)
		res.Add(k)
	Next
	Return res
End Sub

Sub DELETE_ALL
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE_ALL"$)
	End If

	Dim keys As List = BANano.Await(ListKeys)
	If keys.size = 0 Then Return
	Dim collection As BANanoObject = client.RunMethod("collection", sTableName)
	For Each k As String In keys
		BANano.Await(collection.RunMethod("delete", Array(k)))
	Next
End Sub

'get keyvalues for combos etc
'<code>
'Dim mExpenseCategories As Map = banano.Await(pbExpenseCategories.GetKeyValues(True, "id", "name"))
'</code>
Sub GetKeyValues(bHasNothing As Boolean, k As String, v As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.GetKeyValues(${bHasNothing},${k},${v})"$)
	End If

	Dim mx As Map = CreateMap()
	If bHasNothing Then
		mx.Put("", "-- Nothing Selected --")
	End If
	CLEAR_WHERE
	ADD_FIELD(k)
	ADD_FIELD(v)
	ADD_ORDER_BY(v)
	result = BANano.Await(SELECT_WHERE)
	For Each row As Map In result
		Dim f1 As String = row.get(k)
		Dim f2 As String = row.get(v)
		mx.Put(f1, f2)
	Next
	Return mx
End Sub

'get keyvalues for combos etc
'<code>
'Dim mExpenseCategories As Map = banano.Await(pbExpenseCategories.GetKeyValuesFromList(lst, True, "id", "name"))
'</code>
Sub GetKeyValuesFromList(source As List, bHasNothing As Boolean, k As String, v As String) As Map
	Dim mx As Map = CreateMap()
	If bHasNothing Then
		mx.Put("", "-- Nothing Selected --")
	End If
	For Each row As Map In source
		Dim f1 As String = row.get(k)
		Dim f2 As String = row.get(v)
		mx.Put(f1, f2)
	Next
	Return mx
End Sub


'Removes the key and value mapped to this key.
'<code>
'Dim b As Boolean = BANano.Await(pb.DELETE("a"))
'</code>
Sub DELETE(id As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.DELETE. Please execute SchemaAdd?? first to define your table schema!"$)
		Return False
	End If
	Try
		Dim r As Boolean = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("delete", Array(id)))
		Return r
	Catch
		Return False
	End Try
End Sub

'to delete the file set the fldValue = null
Sub SetField(fldName As String, fldValue As Object) As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.SetField(${fldName}, ${fldValue})"$)
	End If
	Dim dt As String = Schema.Get(fldName)
	Select Case dt
	Case DB_BOOL
		fldValue = SDUIShared.CBool(fldValue)
	Case DB_INT
		fldValue = SDUIShared.CInt(fldValue)
	Case DB_FILE
	Case DB_STRING
		fldValue = SDUIShared.CStr(fldValue)
	Case DB_REAL
		fldValue = SDUIShared.CDbl(fldValue)
	Case DB_BLOB
	Case DB_FLOAT
		fldValue = SDUIShared.CDbl(fldValue)
	Case DB_INTEGER
		fldValue = SDUIShared.CInt(fldValue)
	Case DB_TEXT
		fldValue = SDUIShared.CStr(fldValue)
	Case DB_DOUBLE
		fldValue = SDUIShared.CDbl(fldValue)
	End Select
	Record.Put(fldName, fldValue)
	Return Me
End Sub

Sub RecordFromMap(sm As Map)
	Record.Initialize
	For Each k As String In sm.Keys
		Dim v As Object = sm.Get(k)
		Record.Put(k, v)
	Next
End Sub

Sub FirstRecord As Map
	Dim rec As Map = result.Get(0)
	Return rec
End Sub

'clear where clause
Sub CLEAR_WHERE As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.CLEAR_WHERE"$)
	End If
	whereField.Initialize
	ops.Initialize
	orderByL.Initialize
	flds.Initialize
	combineL.Initialize
	Return Me
End Sub

Sub Reset As SDUIPocketBase
	whereField.Initialize
	ops.Initialize
	orderByL.Initialize
	flds.Initialize
	combineL.Initialize
	RowCount = 0
	lastPosition = -1
	Record.Initialize
	result.Initialize
	Success = False
	Tag = Null
	Schema.Initialize 
	DisplayField = ""
	Singular = ""
	Plural = ""
	DisplayValue = ""
	UserProfile.Initialize 
	fileFields.Initialize
	IsAuthenticated = False
	SchemaAddText1("id")
	Return Me
End Sub

Sub ADD_FIELD(fld As String) As SDUIPocketBase
	flds.Add(fld)
	Return Me
End Sub

Sub ADD_FIELDS(fields As List) As SDUIPocketBase
	For Each fld As String In fields
		ADD_FIELD(fld)
	Next
	Return Me
End Sub

'add a where clause for your select where
'LIKE
Sub ADD_WHERE(fld As String, operator As String, value As Object) As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.ADD_WHERE(${fld},${operator},${value})"$)
	End If
	Select Case operator
	Case "<>"
		operator = "!="
	Case "like"
		operator = "~"
	End Select
	whereField.Put(fld, value)
	ops.Add(operator)
	combineL.Add("&&")
	Return Me
End Sub

Sub ADD_WHERE_STRING(fld As String, operator As String, value As Object) As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.ADD_WHERE_STRING(${fld},${operator},${value})"$)
	End If
	ADD_WHERE(fld, operator, $"'${value}'"$)
	Return Me
End Sub

'change the selection at position from AND to OR
Sub WHERE_OR(pos As Int) As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.WHERE_OR(${pos})"$)
	End If
	combineL.Set(pos, "||")
	Return Me
End Sub

'change the selection at position to AND
Sub WHERE_AND(pos As Int) As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.WHERE_AND(${pos})"$)
	End If
	combineL.Set(pos, "&&")
	Return Me
End Sub

'add a sort field
Sub ADD_ORDER_BY(fld As String) As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.ADD_ORDER_BY(${fld})"$)
	End If
	orderByL.Add(fld)
	Return Me
End Sub

Sub ADD_ORDER_BY_DESC(fld As String) As SDUIPocketBase
	If ShowLog Then
		Log($"SDUIPocketBase.ADD_ORDER_BY_DESC(${fld})"$)
	End If
	orderByL.Add($"-${fld}"$)
	Return Me
End Sub

'<code>
'Do while rs.NextRow
'Loop
'</code>
Sub NextRow As Boolean
	lastPosition = lastPosition + 1
	Dim realSize As Int = RowCount - 1
	If lastPosition > realSize Then
		Return False
	Else
		setPosition(lastPosition)
		Return True
	End If
End Sub

Sub SetRecord(rec As Map)
	Record.Initialize 
	'only process schema fields
	For Each k As String In rec.Keys
		Dim fldPos As Boolean = Schema.ContainsKey(k)
		If fldPos = False Then rec.Remove(k)
	Next
	For Each k As String In rec.Keys
		Dim v As Object = rec.GetDefault(k, "")
		Dim dt As String = Schema.Get(k)
		Select Case dt
		Case DB_BOOL
			v = SDUIShared.CBool(v)
		Case DB_INT
			v = SDUIShared.CInt(v)
		Case DB_FILE
		Case DB_STRING
			v = SDUIShared.CStr(v)
		Case DB_REAL
			v = SDUIShared.CDbl(v)
		Case DB_BLOB
		Case DB_FLOAT
			v = SDUIShared.CDbl(v)
		Case DB_INTEGER
			v = SDUIShared.CInt(v)
		Case DB_TEXT
			v = SDUIShared.CStr(v)
		Case DB_DOUBLE
			v = SDUIShared.CDbl(v)
		End Select
		Record.Put(k, v)
	Next
	DisplayValue = Record.GetDEfault(DisplayField, "")
	If ShowLog Then
		Log($"SDUIPocketBase.SetRecord(${BANano.ToJson(Record)})"$)
	End If
End Sub

'prepare a new record
Sub PrepareRecord
	Record.Initialize
End Sub

'prepare FormData
'to subfile file
Sub PrepareForm
	formData.Initialize2("FormData", Null)
End Sub

'set a field for file, this appends to fomData
'to delete the file set the fileObj = null
Sub SetFormFile(fldName As String, fileObj As Object) As SDUIPocketBase
	formData.RunMethod("append", Array(fldName, fileObj))
	Return Me
End Sub

'set a field for form
'to delete the file set the fileObj = null
Sub SetFormField(fldName As String, fldValue As Object) As SDUIPocketBase
	formData.RunMethod("append", Array(fldName, fldValue))
	Return Me
End Sub

'set the position of the current record
Sub setPosition(pos As Int)
	If result.Size > pos Then
		Record = result.Get(pos)
		lastPosition = pos
	Else
		lastPosition = -1
		Record.Initialize
	End If
End Sub

Sub getPosition As Int
	Return lastPosition
End Sub

'get an integer from the current record
Sub GetInt(fld As String) As Int
	fld = fld.tolowercase
	If BANano.IsUndefined(Record) Then Return 0
	If Record.ContainsKey(fld) Then
		Dim obj As Int = Record.GetDefault(fld, 0)
		obj = SDUIShared.CInt(obj)
		Return obj
	Else
		Return 0
	End If
End Sub

'get a long from the current record
Sub GetLong(fld As String) As Long
	Return GetInt(fld)
End Sub

'get a string from the current record
Sub GetString(fld As String) As String
	fld = fld.tolowercase
	If BANano.IsUndefined(Record) Then Return ""
	If Record.ContainsKey(fld) Then
		Dim obj As String = Record.GetDefault(fld, "")
		obj = SDUIShared.cstr(obj)
		Return obj
	Else
		Return ""
	End If
End Sub

'returns a placeholder if there is no image
Sub GetImage(fld As String) As String
	Dim simage As String = GetString(fld)
	If simage = "" Then Return "./assets/placeholderimg.jpg"
	Return simage
End Sub

'get a boolean from the current record
Sub GetBoolean(fld As String) As Boolean
	fld = fld.tolowercase
	If BANano.IsUndefined(Record) Then Return False
	If Record.ContainsKey(fld) Then
		Dim obj As Boolean = Record.GetDefault(fld, False)
		obj = SDUIShared.parseBool(obj)
		Return obj
	Else
		Return False
	End If
End Sub

'get a double from the current record
Sub GetDouble(fld As String) As Double
	fld = fld.tolowercase
	If Record.ContainsKey(fld) Then
		Dim obj As Double = Record.GetDefault(fld, 0)
		obj = SDUIShared.CDbl(obj)
		Return obj
	Else
		Return 0
	End If
End Sub

'get record at position
Sub GetRecord(pos As Int) As Map
	Dim rec As Map = result.Get(pos)
	Return rec
End Sub

'movefirst
'<code>
'rs.MoveFirst
'Do while rs.NextRow
'Loop
'</code>
Sub MoveFirst
	setPosition(0)
End Sub

'movelast
'<code>
'rs.MoveLast
'Do while rs.NextRow
'Loop
'</code>
Sub MoveLast
	setPosition(RowCount - 1)
End Sub

'moveprevious
Sub MovePrevious
	lastPosition = lastPosition - 1
	If lastPosition < 0 Then
		lastPosition = 0
	End If
	setPosition(lastPosition)
End Sub

'movenext
Sub MoveNext
	lastPosition = lastPosition + 1
	If lastPosition > RowCount Then
		lastPosition = RowCount - 1
	End If
	setPosition(lastPosition)
End Sub


'Execute a where clause on the records
'The result is a list with the values.
'<code>
'Dim WhereRecords As List = BANano.Await(pb.findWhereOrderBy(m, array("="), orderBy)
'</code>
Sub findWhereOrderBy(whereMap As Map, whereOps As List, orderBy As List) As List
	If ShowLog Then
		Log($"SDUIPocketBase.findWhereOrderBy(${BANano.ToJson(whereMap)},${whereOps},${orderBy})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.findWhereOrderBy. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	'we build the filter
	Dim sb As StringBuilder
	sb.Initialize
	Dim i As Int
	Dim iWhere As Int = whereMap.Size - 1
	For i = 0 To iWhere
		'If i > 0 Then
		'	sb.Append(" && ")
		'End If
		Dim col As String = whereMap.GetKeyAt(i)
		col = col.replace("&","")
		Dim val As String = whereMap.GetValueAt(i)
		Dim opr As String = whereOps.Get(i)
		Dim com As String = combineL.Get(i)
		sb.Append(col)
		sb.Append($" ${opr} "$)
		sb.append(val)
		sb.Append($" ${com} "$)
	Next
	'
	Dim qfilter As String = sb.tostring
	Dim afilter As String = SDUIShared.remdelim(qfilter, $" ${com} "$)
	qfilter = afilter.Trim
	'
	Dim qsort As String = ""
	If BANano.IsNull(orderBy) = False Then
		qsort = SDUIShared.Join(",", orderBy)
	End If	
	'
	Dim nl As List
	nl.Initialize
	Try
		Dim opt As Map = CreateMap()
		If qsort <> "" Then opt.Put("sort", qsort)
		If qfilter <> "" Then opt.Put("filter", qfilter)
		nl = BANano.Await(client.RunMethod("collection", sTableName).RunMethod("getFullList", Array(200, opt)))
	Catch
	End Try			'ignore
	Return nl
End Sub
'
'Execute a where clause on the records
'The result is a list with the values.
'<code>
'Dim WhereRecords As List = BANano.Await(pb.findWhereOR(m, array("="))
'</code>
Sub findWhere(whereMap As Map, whereOps As List) As List
	If ShowLog Then
		Log($"SDUIPocketBase.findWhere(${BANano.ToJson(whereMap)},${whereOps})"$)
	End If
	Dim res As List = BANano.Await(findWhereOrderBy(whereMap, whereOps, Null))
	Return res
End Sub

Sub DELETE_BY(fldName As String, fldValue As String)
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE_BY(${fldName},${fldValue})"$)
	End If
	CLEAR_WHERE
	ADD_WHERE(fldName, "=", fldValue)
	deleteWhere("id", whereField, ops)
End Sub

Sub DELETE_BY_STRING(fldName As String, fldValue As String)
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE_BY_STRING(${fldName},${fldValue})"$)
	End If
	CLEAR_WHERE
	ADD_WHERE(fldName, "=", $"'${fldValue}'"$)
	deleteWhere("id", whereField, ops)
End Sub


'Execute a delete clause on the records
'<code>
'BANano.Await(pb.deleteWhere("id", m, array("=")))
'</code>
Sub deleteWhere(priKey As String, whereMap As Map, whereOps As List) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.deleteWhere(${priKey},${BANano.ToJson(whereMap)},${whereOps})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.deleteWhere. Please execute SchemaAdd?? first to define your table schema!"$)
		Return Null
	End If
	'get all the records
	Dim recs As List = BANano.Await(findWhere(whereMap, whereOps))
	For Each rec As Map In recs
		Dim pvalue As String = rec.Get(priKey)
		BANano.Await(DELETE(pvalue))
	Next
	Return True
End Sub

Sub DELETE_WHERE
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE_WHERE"$)
	End If
	deleteWhere("id", whereField, ops)
End Sub

'<code>
'Dim result As Boolean = BANano.Await(pbComponents.ExistsByString("name", "xxx"))
'</code>
Sub ExistsByString(fldName As String, fldValue As Object) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.ExistsByString(${fldName},${fldValue})"$)
	End If
	CLEAR_WHERE
	ADD_WHERE_STRING(fldName, "=", fldValue)
	Dim res As List = BANano.Await(SELECT_WHERE)
	If res.size = 0 Then
		Return False
	Else
		Return True
	End If
End Sub

'<code>
'Dim result As Boolean = BANano.Await(pbComponents.Exists("id", 1))
'</code>
Sub Exists(fldName As String, fldValue As Object) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.Exists(${fldName},${fldValue})"$)
	End If
	CLEAR_WHERE
	ADD_WHERE(fldName, "=", fldValue)
	Dim res As List = BANano.Await(SELECT_WHERE)
	If res.size = 0 Then
		Return False
	Else
		Return True
	End If
End Sub

'<code>
'Dim result As Boolean = BANano.Await(pbComponents.Exists("id", 1))
'</code>
Sub ExistsWhere(where As Map) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.ExistsWhere(${BANano.ToJson(where)})"$)
	End If
	CLEAR_WHERE
	For Each k As String In where.Keys
		Dim v As String = where.Get(k)
		ADD_WHERE_STRING(k, "=", v)
	Next
	Dim res As List = BANano.Await(SELECT_WHERE)
	If res.size = 0 Then
		Return False
	Else
		Return True
	End If
End Sub


'<code>
'pbComponents.CLEAR_WHERE
'pbComponents.ADD_WHERE_STRING("attractive", "=", "true")
'pbComponents.ADD_ORDER_BY("attrname")
'Dim result As List = BANano.Await(pbComponents.SELECT_WHERE)
'For Each record As Map In result
'pb.EstablishFileUrl1(record, "fileobj", "fileurl")
'Dim sid As String = record.Get("id")
'Next
'</code>
Sub SELECT_WHERE As List
	If ShowLog Then
		Log($"SDUIPocketBase.SELECT_WHERE"$)
	End If
	Dim res As List = BANano.Await(findWhereOrderBy(whereField, ops, orderByL))
	Return res
End Sub

'<code>
'pbComponents.CLEAR_WHERE
'pbComponents.ADD_WHERE_STRING("attractive", "=", "true")
'pbComponents.ADD_ORDER_BY("attrname")
'BANano.Await(pbComponents.SELECT_WHERE1)
'BANano.Await(pb.EstablishFileUrl("fileobj", "fileurl"))
'Do While pbComponents.NextRow
'Dim rec As Map = pbComponents.Record
'Dim sid As String = pbComponents.GetString("id")
'Loop
'</code>
Sub SELECT_WHERE1 As List
	If ShowLog Then
		Log($"SDUIPocketBase.SELECT_WHERE1"$)
	End If
	result = BANano.Await(findWhereOrderBy(whereField, ops, orderByL))
	lastPosition = -1
	RowCount = result.Size
	Return result
End Sub


'get own unique key with 15 chars
Sub NextID As String
	Dim ni As String = SDUIShared.guidAlpha(15)
	Return ni
End Sub

'define the real record from the db record
'using the schema defined fields
Sub AssignRealRecord(dbRecord As Map)
	Record.Initialize 
	For Each k As String In Schema.Keys
		Dim v As Object = dbRecord.Get(k)
		Record.Put(k, v)
	Next
	Record.Remove("collectionId")
	Record.Remove("collectionName")
	DisplayValue = Record.GetDEfault(DisplayField, "")
End Sub

Sub GetRealRecord(dbRecord As Map) As Map
	dbRecord.Remove("collectionId")
	dbRecord.Remove("collectionName")
	Return dbRecord
End Sub

'<code>
''THIS SHOULD MATCH
''this returns a new profile on success
'dim user As Map = CreateMap()
'user.put("email", "")
'user.put("password", "")
'user.put("passwordConfirm", "")
'user.put("name", "")
'user.put("avatar", "")
'user.put("username", "")
'user.put("emailVisibility", True)
'BANano.Await(pb.CREATE_USER(user))
'dim up As profileType = pb.UserProfile
'if up.size = 0 then
'else
'end if
'</code>
Sub CREATE_USER(profile As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_USER(${profile})"$)
	End If
	UserProfile.Initialize
	UserProfile.size = 0
	Try
		Dim fOK As Int = 0
		If profile.ContainsKey("email") = False Then fOK = BANano.parseint(fOK) + 1
		If profile.ContainsKey("password") = False Then fOK = BANano.parseint(fOK) + 1
		If profile.ContainsKey("passwordConfirm") = False Then fOK = BANano.parseint(fOK) + 1
		'
		If fOK <> 0 Then Return Null
			
		'create the record
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("create", profile))
		UserProfile.id = res.GetDefault("id", "")
		UserProfile.email = res.GetDefault("email","")
		UserProfile.avatar = res.GetDefault("avatar","")
		UserProfile.name = res.GetDefault("name","")
		UserProfile.verified = res.GetDefault("verified",False)
		UserProfile.username = res.GetDefault("username","")
		UserProfile.size = 7
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
''THIS SHOULD MATCH
''this returns a new profile on success
'dim user As Map = CreateMap()
'user.put("email", "")
'user.put("password", "")
'user.put("passwordConfirm", "")
'user.put("name", "")
'user.put("avatar", "")
'user.put("username", "")
'user.put("emailVisibility", True)
'BANano.Await(pb.CREATE_ADMIN(user))
'dim up As profileType = pb.UserProfile
'if up.size = 0 then
'else
'end if
'</code>
Sub CREATE_ADMIN(profile As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_ADMIN(${profile})"$)
	End If
	UserProfile.Initialize 
	UserProfile.size = 0
	Try
		Dim fOK As Int = 0
		If profile.ContainsKey("email") = False Then fOK = BANano.parseint(fOK) + 1
		If profile.ContainsKey("password") = False Then fOK = BANano.parseint(fOK) + 1
		If profile.ContainsKey("passwordConfirm") = False Then fOK = BANano.parseint(fOK) + 1
		'
		If fOK <> 0 Then Return Null
			
		'create the record
		Dim res As Map = BANano.Await(client.GetField("admins").RunMethod("create", profile))
		UserProfile.id = res.GetDefault("id", "")
		UserProfile.email = res.GetDefault("email","")
		UserProfile.avatar = res.GetDefault("avatar","")
		UserProfile.name = res.GetDefault("name","")
		UserProfile.verified = res.GetDefault("verified",False)
		UserProfile.username = res.GetDefault("username","")
		UserProfile.size = 7
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim profile As Map = BANano.Await(pb.CREATE_COLLECTION("people", "base", schema))
'</code>
Sub CREATE_COLLECTION(nameOf As String, colType As String, colSchema As List) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_COLLECTION(${nameOf})"$)
	End If
	Try
		Dim col As Map = CreateMap()
		col.Put("name", nameOf)
		col.Put("type", colType)
		col.Put("schema", colSchema)
		'create the record
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("create", col))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim profile As Map = BANano.Await(pb.CREATE_COLLECTION1("people", schema, "", "", "", "", ""))
'</code>
Sub CREATE_COLLECTION1(nameOf As String, colSchema As List, createRule As String, updateRule As String, deleteRule As String, _
	 listRule As String, viewRule As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_COLLECTION1(${nameOf})"$)
	End If
	Try
		Dim col As Map = CreateMap()
		col.Put("name", nameOf)
		col.Put("type", "base")
		col.Put("createRule", createRule)
		col.Put("updateRule", updateRule)
		col.Put("deleteRule", deleteRule)
		col.Put("listRule", listRule)
		col.Put("viewRule", viewRule)
		col.Put("schema", colSchema)
		'create the record
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("create", col))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

Sub CREATE_COLLECTION2(nameOf As String, typeOf As String, colSchema As List, createRule As String, updateRule As String, deleteRule As String, _
	 listRule As String, viewRule As String, indexes As List, options As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_COLLECTION2(${nameOf})"$)
	End If
	Try
		Dim col As Map = CreateMap()
		col.Put("name", nameOf)
		col.Put("type", typeOf)
		col.Put("createRule", createRule)
		col.Put("updateRule", updateRule)
		col.Put("deleteRule", deleteRule)
		col.Put("listRule", listRule)
		col.Put("viewRule", viewRule)
		col.Put("schema", colSchema)
		col.Put("indexes", indexes)
		col.Put("options", options)
		'create the record
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("create", col))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub
'
Sub CREATE_COLLECTION_ORIGINAL(col As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.CREATE_COLLECTION_ORIGINAL"$)
	End If
	Try
		'create the record
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("create", col))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub


'<code>
'dim uprofile As Map = BANano.Await(pb.UPDATE_COLLECTION("people", schema))
'</code>
Sub UPDATE_COLLECTION(colName As String, colSchema As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_COLLECTION(${colName})"$)
	End If
	Try
		Dim col As Map = CreateMap()
		col.Put("schema", colSchema)
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("update", Array(colName, col)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim uprofile As Map = BANano.Await(pb.UPDATE_COLLECTION_ORIGINAL(schema))
'</code>
Sub UPDATE_COLLECTION_ORIGINAL(col As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_COLLECTION()"$)
	End If
	Try
		dim colName as String = col.get("name")
		Dim nc As Map = CreateMap()
		nc.put("name", colName)
		nc.put("schema", col.get("schema"))
		nc.put("type", col.get("type"))
		nc.put("system", col.get("system"))
		nc.put("listRule", col.get("listRule"))
		nc.put("viewRule", col.get("viewRule"))
		nc.put("createRule", col.get("createRule"))
		nc.put("updateRule", col.get("updateRule"))
		nc.put("deleteRule", col.get("deleteRule"))
		nc.put("indexes", col.get("indexes"))
		nc.put("options", col.get("options"))
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("update", Array(colName, nc)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim profile As Map = BANano.Await(pb.UPDATE_COLLECTION1("people", schema, "", "", "", "", ""))
'</code>
Sub UPDATE_COLLECTION1(nameOf As String, colSchema As List, createRule As String, updateRule As String, deleteRule As String, _
	 listRule As String, viewRule As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_COLLECTION1(${nameOf})"$)
	End If
	Try
		Dim col As Map = CreateMap()
		col.Put("name", nameOf)
		col.Put("type", "base")
		col.Put("createRule", createRule)
		col.Put("updateRule", updateRule)
		col.Put("deleteRule", deleteRule)
		col.Put("listRule", listRule)
		col.Put("viewRule", viewRule)
		col.Put("schema", colSchema)
		'create the record
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("update", Array(nameOf, col)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

Sub UPDATE_COLLECTION2(nameOf As String, typeOf As String, colSchema As List, createRule As String, updateRule As String, deleteRule As String, _
	 listRule As String, viewRule As String, indexes As List, options As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_COLLECTION2(${nameOf})"$)
	End If
	Try
		Dim col As Map = CreateMap()
		col.Put("name", nameOf)
		col.Put("type", typeOf)
		col.Put("createRule", createRule)
		col.Put("updateRule", updateRule)
		col.Put("deleteRule", deleteRule)
		col.Put("listRule", listRule)
		col.Put("viewRule", viewRule)
		col.Put("schema", colSchema)
		col.Put("indexes", indexes)
		col.Put("options", options)
		'create the record
		Dim res As Map = BANano.Await(client.GetField("collections").RunMethod("update", col))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub


'<code>
'dim pid As string = pb.UserProfile.id
'dim uuser As Map = CreateMap()
'uuser.put("name", "")
'dim uprofile As Map = BANano.Await(pb.UPDATE_USER(pid, uuser))
'</code>
Sub UPDATE_USER(id As String, profile As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_USER(${id}, ${profile})"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("update", Array(id, profile)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim pid As string = pb.UserProfile.id
'dim uuser As Map = CreateMap()
'uuser.put("name", "")
'dim uprofile As Map = BANano.Await(pb.UPDATE_ADMIN(pid, uuser))
'</code>
Sub UPDATE_ADMIN(id As String, profile As Map) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.UPDATE_ADMIN(${id}, ${profile})"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.GetField("admins").RunMethod("update", Array(id, profile)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub



'Removes the key and value mapped to this key.
'<code>
'Dim b As Boolean = BANano.Await(pb.DELETE_USER("a"))
'</code>
Sub DELETE_USER(id As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE_USER(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.DELETE_USER. Please execute SchemaAdd?? first to define your table schema!"$)
		Return False
	End If
	Try
		Dim r As Boolean = BANano.Await(client.RunMethod("collection", "users").RunMethod("delete", Array(id)))
		Return r
	Catch
		Return False
	End Try
End Sub

'Removes the key and value mapped to this key.
'<code>
'Dim b As Boolean = BANano.Await(pb.DELETE_ADMIN("a"))
'</code>
Sub DELETE_ADMIN(id As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE_ADMIN(${id})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.DELETE_ADMIN. Please execute SchemaAdd?? first to define your table schema!"$)
		Return False
	End If
	Try
		Dim r As Boolean = BANano.Await(client.GetField("admins").RunMethod("delete", Array(id)))
		Return r
	Catch
		Return False
	End Try
End Sub

'Removes the key and value mapped to this key.
'<code>
'Dim b As Boolean = BANano.Await(pb.DELETE_COLLECTION("a"))
'</code>
Sub DELETE_COLLECTION(colName As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.DELETE_COLLECTION(${colName})"$)
	End If
	If Schema.Size = 0 Then
		BANano.Throw($"SDUIPocketBase.DELETE_COLLECTION. Please execute SchemaAdd?? first to define your table schema!"$)
		Return False
	End If
	Try
		Dim r As Boolean = BANano.Await(client.GetField("collections").RunMethod("delete", Array(colName)))
		Return r
	Catch
		Return False
	End Try
End Sub

'<code>
'dim pemail As string = pb.UserProfile.email
'dim vEmail as Map = banano.await(pb.USER_REQUEST_VERIFICATION(pemail))
'</code>
Sub USER_REQUEST_VERIFICATION(email As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_REQUEST_VERIFICATION(${email})"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("requestVerification", Array(email)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim pemail As string = pb.UserProfile.email
'dim vEmail as Map = banano.await(pb.USER_REQUEST_PASSWORD_RESET(pemail))
'</code>
Sub USER_REQUEST_PASSWORD_RESET(email As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_REQUEST_PASSWORD_RESET(${email})"$)
	End If

	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("requestPasswordReset", Array(email)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim pemail As string = pb.UserProfile.email
'dim vEmail as Map = banano.await(pb.USER_REQUEST_EMAIL_CHANGE(pemail))
'</code>
Sub USER_REQUEST_EMAIL_CHANGE(email As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_REQUEST_EMAIL_CHANGE(${email})"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("requestEmailChange", Array(email)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim vEmail as Map = banano.await(pb.USER_CONFIRM_EMAIL_CHANGE(pToken, pEmail))
'</code>
Sub USER_CONFIRM_EMAIL_CHANGE(token As String, email As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_CONFIRM_EMAIL_CHANGE(${email})"$)
	End If

	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("confirmEmailChange", Array(token, email)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub


'<code>
'dim pToken As string = "xxx"
'dim vEmail as Map = banano.await(pb.USER_CONFIRM_VERIFICATION(pToken))
'</code>
Sub USER_CONFIRM_VERIFICATION(token As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_CONFIRM_VERIFICATION"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("confirmVerification", Array(token)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim vEmail as Map = banano.await(pb.USER_CONFIRM_PASSWORD_RESET(pToken, pPass, pConfirmPass))
'</code>
Sub USER_CONFIRM_PASSWORD_RESET(token As String, newPassword As String, confimPassword As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_CONFIRM_PASSWORD_RESET"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("confirmPasswordReset", Array(token, newPassword, confimPassword)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'banano.await(pb.USER_AUTH_WITH_PASSWORD(pemail, pwd))
'Dim up As profileType = pb.UserProfile
'If up.Size = 0 then
'Else
'End if 
'</code>
Sub USER_AUTH_WITH_PASSWORD(email As String, pwd As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_AUTH_WITH_PASSWORD(${email})"$)
	End If
	UserProfile.Initialize 
	UserProfile.size = 0
	IsAuthenticated = False
	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("authWithPassword", Array(email, pwd)))
		UserProfile.token = res.GetDefault("token", "")
		If res.ContainsKey("record") Then
			UserProfile.id = SDUIShared.getrecursive(res, "record.id")
			UserProfile.email = SDUIShared.getrecursive(res, "record.email")
			UserProfile.avatar = SDUIShared.getrecursive(res, "record.avatar")
			UserProfile.name = SDUIShared.getrecursive(res, "record.name")
			UserProfile.verified = SDUIShared.getrecursive(res, "record.verified")
			UserProfile.username = SDUIShared.getrecursive(res, "record.username")
			UserProfile.size = 7
			IsAuthenticated = True
		End If
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'banano.await(pb.USER_AUTH_REFRESH(pemail, pwd))
'dim up As profileType = pb.UserProfile
'if up.size = 0 then
'else
'end if
'</code>
Sub USER_AUTH_REFRESH As Map
	If ShowLog Then
		Log($"SDUIPocketBase.USER_AUTH_REFRESH"$)
	End If
	UserProfile.Initialize 
	UserProfile.size = 0
	Try
		Dim res As Map = BANano.Await(client.RunMethod("collection", "users").RunMethod("authRefresh", Null))
		Log(res)
		UserProfile.token = res.GetDefault("token", "")
		If res.ContainsKey("record") Then
			UserProfile.id = SDUIShared.getrecursive(res, "record.id")
			UserProfile.email = SDUIShared.getrecursive(res, "record.email")
			UserProfile.avatar = SDUIShared.getrecursive(res, "record.avatar")
			UserProfile.name = SDUIShared.getrecursive(res, "record.name")
			UserProfile.verified = SDUIShared.getrecursive(res, "record.verified")
			UserProfile.username = SDUIShared.getrecursive(res, "record.username")
			UserProfile.size = 7
		End If
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub


'<code>
'banano.await(pb.ADMIN_AUTH_WITH_PASSWORD(pemail, pwd))
'Dim up As profileType = pb.UserProfile
'If up.Size = 0 then
'Else
'End if 
'</code>
Sub ADMIN_AUTH_WITH_PASSWORD(email As String, pwd As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.ADMIN_AUTH_WITH_PASSWORD"$)
	End If
	UserProfile.Initialize 
	UserProfile.size = 0
	IsAuthenticated = False
	Try
		Dim res As Map = BANano.Await(client.GetField("admins").RunMethod("authWithPassword", Array(email, pwd)))
		UserProfile.token = res.GetDefault("token", "")
		If res.ContainsKey("admin") Then
			UserProfile.id = SDUIShared.getrecursive(res, "admin.id")
			UserProfile.email = SDUIShared.getrecursive(res, "admin.email")
			UserProfile.avatar = SDUIShared.getrecursive(res, "admin.avatar")
			UserProfile.name = SDUIShared.getrecursive(res, "admin.name")
			UserProfile.verified = SDUIShared.getrecursive(res, "admin.verified")
			UserProfile.username = SDUIShared.getrecursive(res, "admin.username")
			UserProfile.size = 7
			IsAuthenticated = True
		End If
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim pemail As string = pb.UserProfile.email
'dim vEmail as Map = banano.await(pb.ADMIN_REQUEST_PASSWORD_RESET(pemail))
'</code>
Sub ADMIN_REQUEST_PASSWORD_RESET(email As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.ADMIN_REQUEST_PASSWORD_RESET"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.GetField("admins").RunMethod("requestPasswordReset", Array(email)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub

'<code>
'dim vEmail as Map = banano.await(pb.USER_CONFIRM_PASSWORD_RESET(pToken, pPass, pConfirmPass))
'</code>
Sub ADMIN_CONFIRM_PASSWORD_RESET(token As String, newPassword As String, confimPassword As String) As Map
	If ShowLog Then
		Log($"SDUIPocketBase.ADMIN_CONFIRM_PASSWORD_RESET"$)
	End If
	Try
		Dim res As Map = BANano.Await(client.GetField("admins").RunMethod("confirmPasswordReset", Array(token, newPassword, confimPassword)))
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub


'<code>
'banano.await(pb.ADMIN_AUTH_REFRESH(pemail, pwd))
'Dim up As profileType = pb.UserProfile
'if up.size = 0 then
'else
'end if
'</code>
Sub ADMIN_AUTH_REFRESH As Map
	If ShowLog Then
		Log($"SDUIPocketBase.ADMIN_AUTH_REFRESH"$)
	End If
	UserProfile.Initialize 
	UserProfile.size = 0
	Try
		Dim res As Map = BANano.Await(client.GetField("admins").RunMethod("refresh", Null))
		UserProfile.token = res.GetDefault("token", "")
		If res.ContainsKey("admin") Then
			UserProfile.id = SDUIShared.getrecursive(res, "admin.id")
			UserProfile.email = SDUIShared.getrecursive(res, "admin.email")
			UserProfile.avatar = SDUIShared.getrecursive(res, "admin.avatar")
			UserProfile.name = SDUIShared.getrecursive(res, "admin.name")
			UserProfile.verified = SDUIShared.getrecursive(res, "admin.verified")
			UserProfile.username = SDUIShared.getrecursive(res, "admin.username")
			UserProfile.size = 7
		End If
		Return res
	Catch
		Return Null
	End Try			' ignore
End Sub


Sub USER_SIGNOUT
	If ShowLog Then
		Log($"SDUIPocketBase.USER_SIGNOUT"$)
	End If
	client.getfield("authStore").RunMethod("clear", Null)
	UserProfile.Initialize 
	UserProfile.size = 0
End Sub

Sub USER_TOKEN As String
	If ShowLog Then
		Log($"SDUIPocketBase.USER_TOKEN"$)
	End If

	Dim out As String = client.getfield("authStore").GetField("token").Result
	Return out
End Sub

Sub USER_ISVALID As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.USER_ISVALID"$)
	End If
	Dim out As Boolean = client.getfield("authStore").GetField("isValid").Result
	Return out
End Sub

'convert schema to pocketbase like schema
Sub SchemaToPocketBase As Map
	Dim nl As List
	nl.Initialize 
	For Each k As String In Schema.Keys
		Dim v As String = Schema.Get(k)
		Select Case v
		Case DB_BOOL
			nl.Add(CreateMap("name":k, "type":"bool"))
		Case DB_INT, DB_REAL, DB_REAL, DB_FLOAT, DB_INTEGER, DB_DOUBLE, DB_NUMBER
			nl.Add(CreateMap("name":k, "type":"number"))
		Case DB_FILE, DB_BLOB
			nl.Add(CreateMap("name":k, "type":"file"))
		Case DB_STRING, DB_TEXT
			nl.Add(CreateMap("name":k, "type":"text"))
		Case DB_RELATION
			nl.Add(CreateMap("name":k, "type":"relation"))
		Case DB_JSON
			nl.Add(CreateMap("name":k, "type":"json"))
		Case DB_DATE
			nl.Add(CreateMap("name":k, "type":"date"))
		Case Else
				nl.Add(CreateMap("name":k, "type":"text"))
		End Select
	Next
	Return nl
End Sub

'<code>
'Dim dbSchema As SDUIPocketBase
'dbSchema.Initialize(Me, "dbSchema", "http://127.0.0.1:8090", "")
'Dim bres As Boolean = BANano.Await(dbSchema.SchemaRestoreFromAsset("./assets/minicrm_schema.json", "adminemail", "adminpassword"))
'</code>
Sub SchemaRestoreFromAsset(sassetFile As String, semail As String, spassword As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.SchemaRestoreFromAsset"$)
	End If
	Dim collections As List = BANano.Await(BANano.GetFileAsJSON(sassetFile, Null))
	Dim bres As Boolean = BANano.Await(SchemaRestore(baseURL, semail, spassword, collections))
	Return bres
End Sub

'<code>
'Dim dbSchema As SDUIPocketBase
'dbSchema.Initialize(Me, "dbSchema", "http://127.0.0.1:8090", "")
'Dim bres As Boolean = BANano.Await(dbSchema.SchemaAddFromAsset("./assets/update_schema.json", "adminemail", "adminpassword"))
'</code>
Sub SchemaAddFromAsset(sassetFile As String, semail As String, spassword As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.SchemaAddFromAsset"$)
	End If
	Dim collections As List = BANano.Await(BANano.GetFileAsJSON(sassetFile, Null))
	Dim bres As Boolean = BANano.Await(SchemaAdd(baseURL, semail, spassword, collections))
	Return bres
End Sub

'<code>
'Dim dbSchema As SDUIPocketBase
'dbSchema.Initialize(Me, "sourceDB", surl, "")
'Dim bres As Boolean = BANano.Await(dbSchema.SchemaRestore(surl, semail, spassword, collections))
'</code>		
Sub SchemaRestore(surl As String, semail As String, spassword As String, collections As List) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.SchemaRestore"$)
	End If
	'connect to host
	Dim dbSource As SDUIPocketBase
	dbSource.Initialize(Me, "sourceDB", surl, "")
	BANano.await(dbSource.ADMIN_AUTH_WITH_PASSWORD(semail, spassword))
	Dim sProfile As profileType = dbSource.UserProfile
	If sProfile.Size = 0 Then Return False
	'
	'get collection names
	Dim tblNames As List = BANano.Await(dbSource.SELECT_ALL_COLLECTIONS_NAMES)
	'
	For Each collection As Map In collections
		Dim screateRule As String = collection.Get("createRule")
		Dim sdeleteRule As String = collection.Get("deleteRule")
		Dim slistRule As String = collection.Get("listRule")
		Dim sname As String = collection.Get("name")
		Dim lschema As List = collection.Get("schema")
		Dim supdateRule As String = collection.Get("updateRule")
		Dim sviewRule As String = collection.Get("viewRule")
		Dim stype As String = collection.Get("type")
		Dim options As Map = collection.Get("options")
		Dim indexes As List = collection.Get("indexes")
		'
		'search for the table name
		Dim tblIndex As Int = tblNames.IndexOf(sname)
		If tblIndex = -1 Then
			'the table is not found, make it
			BANano.Await(dbSource.CREATE_COLLECTION2(sname, stype, lschema, screateRule, supdateRule, sdeleteRule, slistRule, sviewRule, indexes, options))
		Else
			'update collection
			BANano.Await(dbSource.UPDATE_COLLECTION2(sname, stype, lschema, screateRule, supdateRule, sdeleteRule, slistRule, sviewRule, indexes, options))
		End If
	Next
	Return True
End Sub
'
'<code>
'Dim dbSchema As SDUIPocketBase
'dbSchema.Initialize(Me, "sourceDB", surl, "")
'Dim bres As Boolean = BANano.Await(dbSchema.SchemaAdd(surl, semail, spassword, collections))
'</code>		
Sub SchemaAdd(surl As String, semail As String, spassword As String, collections As List) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.SchemaUpdate"$)
	End If
	Operations.Initialize
	'connect to host
	Dim dbSource As SDUIPocketBase
	dbSource.Initialize(Me, "sourceDB", surl, "")
	BANano.await(dbSource.ADMIN_AUTH_WITH_PASSWORD(semail, spassword))
	Dim sProfile As profileType = dbSource.UserProfile
	If sProfile.Size = 0 Then Return False
	'
	'get collection names
	Dim tblNames As List = BANano.Await(dbSource.SELECT_ALL_COLLECTIONS_NAMES)
	'
	For Each collection As Map In collections
		Dim sname As String = collection.Get("name")
		'search for the table name
		Dim tblIndex As Int = tblNames.IndexOf(sname)
		If tblIndex = -1 Then 
			dim m as map = BANano.Await(dbSource.CREATE_COLLECTION_ORIGINAL(collection))
			Operations.add(m)
		End if
 	Next
	Return True
End Sub
'
'<code>
'Dim dbSchema As SDUIPocketBase
'dbSchema.Initialize(Me, "sourceDB", surl, "")
'Dim bres As Boolean = BANano.Await(dbSchema.SchemaUpdate(surl, semail, spassword, collections))
'</code>		
Sub SchemaUpdate(surl As String, semail As String, spassword As String, collections As List) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.SchemaUpdate"$)
	End If
	Operations.Initialize
	'connect to host
	Dim dbSource As SDUIPocketBase
	dbSource.Initialize(Me, "sourceDB", surl, "")
	BANano.await(dbSource.ADMIN_AUTH_WITH_PASSWORD(semail, spassword))
	Dim sProfile As profileType = dbSource.UserProfile
	If sProfile.Size = 0 Then Return False
	'
	'get collection names
	Dim tblNames As List = BANano.Await(dbSource.SELECT_ALL_COLLECTIONS_NAMES)
	'
	For Each collection As Map In collections
		Dim sname As String = collection.Get("name")
		'search for the table name
		Dim tblIndex As Int = tblNames.IndexOf(sname)
		If tblIndex >= 0 Then 
			dim m as map = BANano.Await(dbSource.UPDATE_COLLECTION_ORIGINAL(collection))
			Operations.add(m)
		End if
	Next
	Return True
End Sub


'<code>
'Dim dbSchema As SDUIPocketBase
'dbSchema.Initialize(Me, "dbSchema", modSDPB.ServerLocation, "")
'Dim bres As Boolean = BANano.Await(dbSchema.SchemaBackUp(sname, surl, semail, spassword))
'</code>
Sub SchemaBackUp(prjName As String, surl As String, semail As String, spassword As String) As Boolean
	If ShowLog Then
		Log($"SDUIPocketBase.SchemaBackUp"$)
	End If
	'connect to host
	Dim dbSource As SDUIPocketBase
	dbSource.Initialize(Me, "sourceDB", surl, "")
	BANano.await(dbSource.ADMIN_AUTH_WITH_PASSWORD(semail, spassword))
	Dim sProfile As profileType = dbSource.UserProfile
	If sProfile.Size = 0 Then Return False
	'
	prjName = prjName.Replace(" ", "")
	prjName = prjName.ToLowerCase
	Dim prjSearch As String = $"${prjName}_"$
	'get all collection
	BANano.Await(dbSource.SELECT_ALL_COLLECTIONS)
	'
	Dim prjTables As List
	prjTables.Initialize
	'extract collections for project
	Do While dbSource.NextRow
		Dim rec As Map = dbSource.Record
		Dim tblname As String = dbSource.GetString("name")
		If tblname.StartsWith(prjSearch) Then
			prjTables.Add(rec)
		End If
	Loop
	'convert to json
	Dim prjTablesJSON As String = BANano.ToJson(prjTables)
	Dim prjFileName As String = $"${prjName}_schema.json"$
	'download
	SDUIShared.Download(prjTablesJSON, prjFileName)
	Return True
End Sub
'
Sub SetRecordAsIs(rec As Map)
	Record.Initialize 
	'only process schema fields
	For Each k As String In rec.Keys
		Dim v As Object = rec.get(k)
		Record.put(k, v)
	Next
	DisplayValue = Record.GetDEfault(DisplayField, "")
	If ShowLog Then
		Log($"SDUIPocketBase.SetRecordAsIs(${BANano.ToJson(Record)})"$)
	End If
End Sub


'<code>
'Dim dbSchema As SDUIPocketBase
'dbSchema.Initialize(Me, "dbSchema", modSDPB.ServerLocation, "")
'Dim schema As List = BANano.Await(dbSchema.SchemaGet(sname, surl, semail, spassword))
'</code>
Sub SchemaGet(prjName As String, surl As String, semail As String, spassword As String) As List
	Dim prjTables As List
	prjTables.Initialize
	If ShowLog Then
		Log($"SDUIPocketBase.SchemaGet"$)
	End If
	'connect to host
	Dim dbSource As SDUIPocketBase
	dbSource.Initialize(Me, "sourceDB", surl, "")
	BANano.await(dbSource.ADMIN_AUTH_WITH_PASSWORD(semail, spassword))
	Dim sProfile As profileType = dbSource.UserProfile
	If sProfile.Size = 0 Then Return prjTables
	'
	prjName = prjName.Replace(" ", "")
	prjName = prjName.ToLowerCase
	Dim prjSearch As String = $"${prjName}_"$
	'get all collection
	BANano.Await(dbSource.SELECT_ALL_COLLECTIONS)
	'extract collections for project
	Do While dbSource.NextRow
		Dim rec As Map = dbSource.Record
		Dim tblname As String = dbSource.GetString("name")
		If tblname.StartsWith(prjSearch) Then
			prjTables.Add(rec)
		End If
	Loop
	Return prjTables
End Sub