Here's a PB module for the client side (mod-ns3.pb):
Code: Select all
;
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
;OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
;IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
;CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
;TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
;OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;
;Apart from the above use it however you like ;-)
DeclareModule NS3
#NS3_BEGIN = 0
#NS3_COMMIT = 1
#NS3_ROLLBACK = 2
#NS3_SELECT = 3
#NS3_EXECUTE = 4
#NS3_EXECUTEMANY = 5
Declare Bail(cnx.i,jsReq.i,jsRes.i,withRollback=#False)
Declare BindBoolean(js.i,n.i)
Declare BindDouble(js.i,n.d)
Declare BindFloat(js.i,n.f)
Declare BindInteger(js.i,n.i)
Declare BindNull(js.i)
Declare BindQuad(js.i,n.q)
Declare BindString(js.i,s$)
Declare Close(cnx.i)
Declare.i Connect(host$,port)
Declare.s ErrorText(js.i)
Declare.i HasError(js.i)
Declare.i NewRequest(method.i,sql$="",ejs=0)
Declare.i SubmitRequest(cnx.i,js.i,timeoutInterval.i=10000)
EndDeclareModule
Module NS3
;_send #True as the fourth parameter to save having to
; call rollback as a seperate exercise
Procedure Bail(cnx.i,jsReq.i,jsRes.i,withRollback=#False)
Protected txt$ = ""
If IsJSON(jsReq) : FreeJSON(jsReq) : EndIf
If IsJSON(jsRes)
txt$ = ErrorText(jsRes)
FreeJSON(jsRes)
EndIf
If withRollback
Protected jsRequest = NewRequest(#NS3_ROLLBACK)
Protected jsResponse = SubmitRequest(cnx,jsRequest)
If HasError(jsResponse)
If txt$ <> "" : txt$ = txt$ + " | " : EndIf
txt$ = txt$ + ErrorText(jsResponse)
EndIf
FreeJSON(jsRequest)
FreeJSON(jsResponse)
EndIf
Debug(txt$)
;MessageRequester("Error",txt$,0)
EndProcedure
; you wont call this procedure directly
Procedure.s NonDatabaseError(msg$)
Protected js.i = CreateJSON(#PB_Any)
If Not js : ProcedureReturn "" : EndIf
Protected req = SetJSONObject(JSONValue(js))
SetJSONNull(AddJSONMember(req,"result"))
nErr = SetJSONObject(AddJSONMember(req,"error"))
SetJSONString(AddJSONMember(nErr,"code"),"")
SetJSONString(AddJSONMember(nErr,"message"),msg$)
SetJSONInteger(AddJSONMember(nErr,"origin"),0)
ProcedureReturn ComposeJSON(js)
EndProcedure
; you wont call this procedure directly
Procedure.i GetNewParamForBinding(js.i)
Protected idx = GetJSONMember(JSONValue(js),"params")
Protected itm = AddJSONElement(idx)
ProcedureReturn itm
EndProcedure
Procedure BindBoolean(js.i,n.i)
Protected idx = GetNewParamForBinding(js)
SetJSONBoolean(idx, n)
EndProcedure
Procedure BindDouble(js.i,n.d)
Protected idx = GetNewParamForBinding(js)
SetJSONDouble(idx, n)
EndProcedure
Procedure BindFloat(js.i,n.f)
Protected idx = GetNewParamForBinding(js)
SetJSONFloat(idx, n)
EndProcedure
Procedure BindInteger(js.i,n.i)
Protected idx = GetNewParamForBinding(js)
SetJSONInteger(idx, n)
EndProcedure
Procedure BindNull(js.i)
Protected idx = GetNewParamForBinding(js)
SetJSONNull(idx)
EndProcedure
Procedure BindQuad(js.i,n.q)
Protected idx = GetNewParamForBinding(js)
SetJSONQuad(idx, n)
EndProcedure
Procedure BindString(js.i,s$)
Protected idx = GetNewParamForBinding(js)
SetJSONString(idx, s$)
EndProcedure
Procedure Close(cnx.i)
CloseNetworkConnection(cnx)
EndProcedure
Procedure.i Connect(host$,port)
ProcedureReturn OpenNetworkConnection(host$, port)
EndProcedure
Procedure.s ErrorText(js.i)
If js = #False
ProcedureReturn "Network error"
EndIf
Protected idx = GetJSONMember(JSONValue(js),"error")
Protected nMsg = GetJSONMember(idx,"message")
Protected msg.s = GetJSONString(nMsg)
ProcedureReturn msg
EndProcedure
Procedure.i HasError(js.i)
Protected idx = GetJSONMember(JSONValue(js),"error")
If JSONType(idx) = #PB_JSON_Null
ProcedureReturn #False
EndIf
ProcedureReturn #True
EndProcedure
; method options are begin,commit,rollback,execute,executeMany and select.
; the ejs parameter just helps with housekeeping, you can free your last
; request at the same time as starting a new one
Procedure.i NewRequest(method.i,sql$="",ejs=0)
If ejs > 0 And IsJSON(ejs) : FreeJSON(ejs) : EndIf
Protected js.i = CreateJSON(#PB_Any)
If Not js : ProcedureReturn #False : EndIf
Protected req = SetJSONObject(JSONValue(js))
SetJSONInteger(AddJSONMember(req, "method"), method.i)
SetJSONString(AddJSONMember(req, "sql"), sql$)
Protected p.i = AddJSONMember(req, "params")
SetJSONArray(p)
ProcedureReturn js
EndProcedure
Procedure.i SubmitRequest(cnx.i,js.i,timeoutInterval.i=10000)
Protected req$ = ComposeJSON(js)
Protected responseChunk$
Protected responseText$
Protected nTimeoutStart.i
#bufferLength = 1024
Protected *buffer = AllocateMemory(#bufferLength)
Protected res.i
If SendNetworkString(cnx,req$,#PB_UTF8) = 0
FreeMemory(*buffer)
ProcedureReturn ParseJSON(#PB_Any,NonDatabaseError("REQUEST_FAILED:Failed to send request"))
EndIf
nTimeoutStart = ElapsedMilliseconds() + timeoutInterval
Repeat
Select NetworkClientEvent(cnx)
Case #PB_NetworkEvent_None
If nTimeoutStart < ElapsedMilliseconds()
responseText$ = NonDatabaseError("TIMEOUT:The request timed out")
Break
EndIf
Case #PB_NetworkEvent_Data
res = ReceiveNetworkData(cnx,*buffer,#bufferLength)
If res = -1
responseText$ = NonDatabaseError("DISCONNECT:The connection to the server was lost")
Break
EndIf
responseChunk$ = PeekS(*buffer,res,#PB_UTF8)
responseText$ + responseChunk$
If PeekA(*buffer + res - 1) = '}' And res < #bufferLength
Break
EndIf
Case #PB_NetworkEvent_Disconnect
responseText$ = NonDatabaseError("DISCONNECT:The connection to the server was lost")
Break
EndSelect
ForEver
FreeMemory(*buffer)
ProcedureReturn ParseJSON(#PB_Any,responseText$)
EndProcedure
EndModule
Code: Select all
EnableExplicit
If InitNetwork() = 0 : End : EndIf
XIncludeFile "mod-ns3.pb"
Define h$ = "127.0.0.1"
Define pt = 2015
Define cnx = NS3::Connect(h$,pt)
If Not cnx
Debug "Failed to connect"
End
EndIf
Define jsRequest = NS3::NewRequest(NS3::#NS3_BEGIN)
Define jsResponse = NS3::SubmitRequest(cnx,jsRequest)
If NS3::HasError(jsResponse)
NS3::Bail(cnx,jsRequest,jsResponse)
End
EndIf
jsRequest = NS3::NewRequest(NS3::#NS3_EXECUTE,"DELETE FROM t1",jsRequest)
jsResponse = NS3::SubmitRequest(cnx,jsRequest)
If NS3::HasError(jsResponse)
NS3::Bail(cnx,jsRequest,jsResponse,#True)
End
EndIf
jsRequest = NS3::NewRequest(NS3::#NS3_COMMIT,"",jsRequest)
jsResponse = NS3::SubmitRequest(cnx,jsRequest)
If NS3::HasError(jsResponse)
NS3::Bail(cnx,jsRequest,jsResponse)
End
EndIf
jsRequest = NS3::NewRequest(NS3::#NS3_BEGIN,"",jsRequest)
jsResponse = NS3::SubmitRequest(cnx,jsRequest)
If NS3::HasError(jsResponse)
NS3::Bail(cnx,jsRequest,jsResponse)
End
EndIf
Define cntr = 0
While cntr < 1000
jsRequest = NS3::NewRequest(NS3::#NS3_EXECUTE,"INSERT INTO t1 (f1,f2) VALUES (?,?)",jsRequest)
NS3::BindInteger(jsRequest,cntr)
NS3::BindInteger(jsRequest,cntr)
jsResponse = NS3::SubmitRequest(cnx,jsRequest)
If NS3::HasError(jsResponse)
NS3::Bail(cnx,jsRequest,jsResponse,#True)
End
Else
If cntr = 0 : Debug ComposeJSON(jsResponse) : EndIf
EndIf
cntr = cntr + 1
Wend
jsRequest = NS3::NewRequest(NS3::#NS3_COMMIT,"",jsRequest)
jsResponse = NS3::SubmitRequest(cnx,jsRequest)
If NS3::HasError(jsResponse)
NS3::Bail(cnx,jsRequest,jsResponse)
End
EndIf
jsRequest = NS3::NewRequest(NS3::#NS3_SELECT,"SELECT * FROM t1 WHERE f1 <= ?",jsRequest)
NS3::BindInteger(jsRequest,500)
jsResponse = NS3::SubmitRequest(cnx,jsRequest)
If NS3::HasError(jsResponse)
NS3::Bail(cnx,jsRequest,jsResponse)
Else
Debug ComposeJSON(jsResponse,#PB_JSON_PrettyPrint)
EndIf
NS3::Close(cnx)
End