Converting VO memo field data to a SQL Db

Public support forum for peer to peer support with related to the Visual Objects and Vulcan.NET products
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Converting VO memo field data to a SQL Db

Post by wriedmann »

Hi Chris,

I have now made two different applications: a VO Console application that creates a DBF and reads all DLL files from a directory into a DBF, and a X# application that reads the DBF and compares with the data on the disk.

Unfortunately there are differences. Since I have to stop now until later today, I attach a zip file with both applications.
If you have time, maybe you can find my error.

Wolfgang
Attachments
WriteBinary.zip
(3.31 KiB) Downloaded 44 times
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Converting VO memo field data to a SQL Db

Post by Chris »

Hi Wolfgang,

That's because the dbf is generated in OEM mode, so you will need to use the appropriate codepage. Just add this in the beginning of your x# code and it should work correctly now (it does on my machine, hopefully it does on yours, too):

LOCAL nCodePage AS INT
nCodePage := (INT)Vulcan.Runtime.State.DosCodePage
AdjustBinaryData.Initialize(Encoding.GetEncoding(nCodepage))

as I said, if everything else works as expected, you will not need to do this manually, the code can read the codepage directly from the dbf instead.

Btw, I just realized that most of the code in the AdjustBinaryData class is redundant and it can be written in a lot more simple way:

#using System.Text

STATIC CLASS AdjustBinaryData
STATIC PRIVATE enc AS Encoding
STATIC CONSTRUCTOR()
Initialize(Encoding.Default)
RETURN
STATIC METHOD Initialize(oEncoding AS Encoding) AS VOID
enc := oEncoding
RETURN
STATIC METHOD BeforeSaveBytes(abInput AS BYTE[]) AS STRING
RETURN enc:GetString(abInput)
STATIC METHOD AfterReadToBytes(cInput AS STRING) AS BYTE[]
RETURN enc:GetBytes(cInput)
END CLASS

:-)

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Converting VO memo field data to a SQL Db

Post by wriedmann »

Hi Chris,

a short note: it works!

I'll complete it that it recognizes the ansi flag of the DBF and post both applications here and on my server. Of course I will add your copyright to the class.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Converting VO memo field data to a SQL Db

Post by wriedmann »

Hi Chris,

again: thank you very, very much!

Attached to this message you can find a corrected application for both VO and X# (XIDE export). The XIDE program checks the Ansi flag of the DBF file and initalizes the converter class accordingly.

The only thing I'm missing now is a VO compatible Crypt function that takes and returns a byte array.

And I have uploaded the same zip file to my webserver: https://riedmann.it/download/XS_DBFBinaryRead.zip, completed with your message as readme.

Wolfgang
Attachments
XS_DBFBinaryRead.zip
(4.46 KiB) Downloaded 44 times
DBFBinaryRead.zip
(3.32 KiB) Downloaded 44 times
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Converting VO memo field data to a SQL Db

Post by Chris »

Hi Wolfgang,

You're welcome, and thanks for testing! Glad to see after so many years that there's an easy solution for that after all.

Btw, the code I posted previously for getting the codepage was a quick and dirty way to do it, assuming the dbf was created in the same machine. Proper way to do it, by using a DBServer obejct is:

#define DBI_CODEPAGE 41
nCodePage := oServer:Info(DBI_CODEPAGE)
AdjustBinaryData.Initialize(Encoding.GetEncoding(nCodepage))

as for a VO-compatible Crypt() that works with a byte array, here it is below:

Chris


FUNCTION CryptByteArray(aBytes AS BYTE[] , cKey AS STRING) AS BYTE[]
LOCAL pKey := String2Psz(cKey) AS PSZ

LOCAL aRet AS BYTE[]
aRet := BYTE[]{aBytes:Length}

FOR LOCAL n := 1 AS INT UPTO aBytes:Length
aRet[n] := aBytes[n]
NEXT

// just make sure the GC does not move the array around
BEGIN FIXED LOCAL pBytes := aRet AS BYTE PTR
Crypt4(pBytes , pKey , (DWORD)aRet:Length , (DWORD)cKey:Length)
END
RETURN aRet
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
FFF
Posts: 1580
Joined: Fri Sep 25, 2015 4:52 pm
Location: Germany

Converting VO memo field data to a SQL Db

Post by FFF »

Crypt4(pBytes , pKey , (DWORD)aRet:Length , (DWORD)cKey:Length)
END
RETURN aRet
FWIW, "Crypt4" ? If that's no typo, the name is rather "burned", as google knows this as a probably undecryptable trojan <g>

Karl
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Converting VO memo field data to a SQL Db

Post by wriedmann »

Hi Chris,

great! Thank you!

I have to check the crypt() function next week, or maybe tomorrow, because now I have VO work to do.

Regarding the right encoding: I have added a second static Initialize method the the AdjustBinaryData class:

Code: Select all

static method Initialize( oServer as Vulcan.VO.DbServer ) as void
local nCodePage	as int
	
nCodePage := oServer:Info( DBI_CODEPAGE )
_oEncoding := Encoding.GetEncoding( nCodepage )
	
return
and have put that class into my VulcanInterface library.

The adjusted sample is both attached to this message and on my download page (it may be easier to find than down here in the forums).

Wolfgang
Attachments
XS_DBFBinaryRead.zip
(4.4 KiB) Downloaded 53 times
XS_DBFBinaryRead.zip
(4.52 KiB) Downloaded 44 times
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
User avatar
Chris
Posts: 4906
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Converting VO memo field data to a SQL Db

Post by Chris »

Hi Karl,

Heh, didn't know that! No, it's just the Crypt() function, but the strongly typed version with 4 params, thus the "4" in the name. Similar to SubStr2(), SubStr3() etc.

Chris
Chris Pyrgas

XSharp Development Team
chris(at)xsharp.eu
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

Converting VO memo field data to a SQL Db

Post by wriedmann »

Hi Karl,

this function is defined in the VulcanRTFuncs library (says at least XIDE...)

Wolfgang

I was curious too, and XIDE showed me the prototype:
crypt4.png
crypt4.png (3.81 KiB) Viewed 487 times
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
NickFriend
Posts: 248
Joined: Fri Oct 14, 2016 7:09 am

Converting VO memo field data to a SQL Db

Post by NickFriend »

Hi Chris,

Thanks for your input in this. I seem to have a slightly different issue as well.

For some unknown reason the original developers of our app chose to use RDDINFO(_SET_MEMOBLOCKSIZE,31). I include a call to this in my XSharp code, but I get a runtime error from the Vulcan assemblies when I try to do a FieldGet on the memo field. If I edit the DBF to use memoblock size 32 and remove the call to RDDINFO, then I can read the memofield correctly. The error is not very informative...

Vulcan.NET Runtime Error
Error Code: 0 [Unknown error]
Subsystem:
Function: FIELDGET
Call Stack:
at Vulcan.Error.Throw(__Usual[] $args)
at VulcanRTFuncs.Functions.DefError(Error oError)
at Codeblocks.$CB_$Error$_930_22.Eval(__Usual[] <evalargs>)
at VulcanRTFuncs.Functions.Eval(Codeblock cbCodeBlock, __Usual[] args)
at Vulcan.VO.DbServer.Error(__Usual[] $args)
at Vulcan.VO.DbServer.FIELDGET(__Usual[] $args)
at TestQW10.Exe.Functions.Start() in: C:UsersNickDocuments.....

Any ideas? Thanks

Nick
Post Reply