Previous Thread
Next Thread
Print Thread
A-Shell to MySQL data types #31055 21 Sep 09 02:40 PM
Joined: Nov 2006
Posts: 2,223
S
Stephen Funkhouser Offline OP
Member
OP Offline
Member
S
Joined: Nov 2006
Posts: 2,223
I'm working on creating a customer table which will be synced to a customer ISAM file, so I can use it for more advanced search routines.

I'm having trouble deciding on what the best/easiest way to match A-Shell data types to MySQL data types.

The customer record is like the following:
Code
DEFSTRUCT cust'record_struct
	MAP2 cust'number					,s,6
	MAP2 cust'name						,s,30
	MAP2 cust'address'1					,s,30
	MAP2 cust'address'2					,s,30
	MAP2 cust'address'3					,s,30
	MAP2 cust'city						,s,15
	MAP2 cust'state					,s,2
	MAP2 cust'zip						,s,9
	MAP2 cust'salesman'info
		MAP3 cust'salesman'numberx
			MAP4 cust'salesman'number(4)	,b,1
		MAP3 cust'salesman'commission(4)	,b,2
What is the best/easiest way to store the binary arrays in the table while being able to retrieve them in A-Shell?

1. Is there a way to do this with an overlay?
2. Maybe have the Table value be a double and then calculate the value shifting each array element the necessary # of bytes?


Stephen Funkhouser
Diversified Data Solutions
Re: A-Shell to MySQL data types #31056 22 Sep 09 07:37 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
In theory there should be no problem using overlays to combine multi-field structures (such as cust'salesman'numberx in the above example) using type BINARY(n). (where n is the size of the structure in bytes).

HOWEVER, there is definitely a problem in coming up with the appropriate syntax for an INSERT statement to insert it. (As it stands, the only method offered in ASQL for inserting data involves the application creating a valid INSERT statement, which is typically made up entirely of printable characters.) Offhand I'm not sure what standards exist for specifying binary data within an INSERT string made up of ASCII characters.

Packing an array of four 2-byte fields into a DOUBLE won't work either because of the difficulty of representing the resulting value in printable characters. (You might get close but are probably going to lose accuracy somewhere.)

You could, however, probably get away with packing four 1-byte fields into an INT, since nothing would be lost when displaying the resulting 32 bit INT in decimal notation.

I'm pretty sure that each database engine offers extensions in the form of functions, metacharacters, statement options, etc. for handling binary data, but I'm going to have to research this a bit before I can give you an answer.

On the retrieval side, I don't think there should be any problem, as long as you retrieve directly into the proper data type (using SQLOP_FETCH_ROW with the FETCHR_FIELDS option). Retrieving into a string and then converting will surely not work though.

Re: A-Shell to MySQL data types #31057 23 Sep 09 10:33 AM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
Actually, after further investigation, the situation seems nearly reversed from how I described it. It does appear to me that you can output a series of unformatted (raw, binary) bytes, at least using the MySQL API, with the CHAR(n1,...,nx) function:

Code
defstruct ST_REC
    map2 name,s,12
    map2 xarray
        map3 xa(8),b,1
endstruct

...
! create a table
xcall SQL, SQLOP_QUERY, cmdhdr, &
  "create table t1 ( name varchar(12), xarray binary(8) )"

...
! insert a rec
xcall SQL, SQLOP_QUERY, cmdhdr, &
  "insert into t1 (name, xarray) values ('Jack',CHAR(1,2,3,4,5,6,7,8))"
(Not that having to represent a large unformatted structure as a series of bytes using the CHAR function is particular convenient, but it does at least provide a path. And you can always overlay an array of bytes on top of any other structure.)

The problem is on the read side, where, at least in the MySQL API, the mechanism we are using starts with retrieving ASCII representations of the fields and only then converts them into the target types. That doesn't work so well with binary data.

For another perspective, here's what the MySQL command line query shows when I modified the sqltest4 program to add a binary/unformatted field (ratex) and populated it with CHAR(1,2,3,4,5,6,7,8):

[Linked Image]

That makes it clear that the binary data is getting written, but also that retrieving it in ASCII representation isn't very practical. So, I need to modify the connector to find a different method for retrieving fields that is more binary friendly. I also need to upgrade the connectors to be compatible with the new dynamic variable architecture.

As an aside, it seems odd to me that, at least under MySQL, the syntax for embedding control characters in strings by escaping them with backslash (e.g. '\t' = TAB) doesn't appear to support arbitrary numeric bytes (e.g. '\005' for chr(5)). It only supports a limited set of control characters that are commonly found in otherwise normal text. So the fancy routines which escape and unescape data don't really help us much.

One more aside: considering the complications of unformatted binary data, perhaps it would be easier to just define each of the array elements as separate columns (e.g TINYINT for B1, SMALLINT for B2, MEDIUMINT for B3, INT for B4, etc)?

Re: A-Shell to MySQL data types #31058 23 Sep 09 10:50 AM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
Uh, amend that last post: I had a simple bug in my test program. Retrieving the binary data works fine, as long as you retrieve it into the proper (in this case unformatted) type variable directly and use the FETCHR_FIELDS mode of SQLOP_FETCH_ROW.

So to recap, my rec structure look something like the example above (with the unformatted structure xarray redefined as an array of 1 byte binaries, although it could also be over-layed with some other structure at the same time.) I defined the column as BINARY(8), wrote it out using "CHAR(";xa(1);",";xa(2);"," )" and then retrieved it using SQLOP_FETCH_ROW with the FETCHR_FIELDS option directly into the xarray field.

Here's a modified version of the sqltest4 test program that demonstrates it: sqltest4a.bp

Re: A-Shell to MySQL data types #31059 25 Sep 09 05:39 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
One more note about this problem of inserting binary data:

Contrary to the "(not yet implemented)" note in the SQLOP_QUERY documentation, the feature is implemented, and does seem to work, as least in the MySQL connector. (I probably should have said "not yet tested").

Admittedly, it is a bit trickY building an "insert..." string containing components which may involve nulls, but one way to do it is via substring assignments to an unformatted variable, e.g.:

Code
map1 queryx,x,1000
map1 ratex          ! = x,12
    map2 r(4),b,2
    map2 f4,f,4

...
r(1) = 200 : r(2) = 0 : r(3) = 65535 : f4 = 123.45
queryx = "insert into tbl (ratex) values ('............')"
queryx[34;12] = ratex

cmdhdr.cmdarg1 = 48  ! tot query len
cmdhdr.opflags = QRYF_REAL
xcall SQL, SQLOP_QUERY, cmdhdr, queryx

Re: A-Shell to MySQL data types #31060 06 Oct 09 10:13 AM
Joined: Nov 2006
Posts: 2,223
S
Stephen Funkhouser Offline OP
Member
OP Offline
Member
S
Joined: Nov 2006
Posts: 2,223
Just to give an update on my findings.

Using the QRYF_REAL mode is the only way I've gotten the results I was looking for; which, was to store an A-Shell binary array (i.e. r(4),b,2) in an SQL data type of Binary(4).

The only trouble I had was with "cmdhdr.cmdarg1 = 48". This was a problem for me because my SQL table contains Varchar() data types, so my SQL string is different lengths depending upon the data. So, I've just made my SQL variable a dynamic "X" variable, and all is well.


Stephen Funkhouser
Diversified Data Solutions
Re: A-Shell to MySQL data types #31061 08 Oct 09 01:17 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
In the process of studying this, we've just identified some interesting idiosyncrasies involving concatenation of unformatted variables, which has motivated me to make a subtle change to the way dynamic X variables behave (which will be in 1161.0). As soon as I resolve that, I'll follow up with further explanation.

On a related note, we're giving some thought to coming up with an alternate/simpler mechanism for inserting fields containing binary data that doesn't require so much concatenation and escaping. More on that later too.

Re: A-Shell to MySQL data types #31062 08 Oct 09 06:44 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794


Moderated by  Jack McGregor, Ty Griffin 

Powered by UBB.threads™ PHP Forum Software 7.7.3