 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sat Jun 19, 2010 12:06 am
[320B] Some puzzlement about single db records (continued). <RESOLVED> |
I changed my data provider to emit JSON structures and I must say that it works like a champ. However, I am still having problems with single row returns. In JSON [......] is defined as an Array. CMUD converts this format to a string list. So far, so good. If I emit a multi-row return, I encase the row products in the brackets and CMUD converts it to a string list of db records, as it should. The problem that I am having is with the following record return:
| Code: |
$returned_rec --> [{"key1":"val1", "key2":"val2",.....,"keyN":"valN"}]
|
This will be turned into the following string list (after applying the %json function):
| Code: |
$processed_rec --> key1|val1|key2|val2|....|keyN|valN
|
However, if I return the record without the Array marker. I get this (after applying the %json function):
| Code: |
$returned_rec --> {"key1":"val1", "key2":"val2",.....,"keyN":"valN"}
;;
$processed_rec --> key=val1|key2=val2|....|keyN=valN
|
Which is what it is desired.
In other words, I must check to see that I am emitting a single row and not return it as a JSON array of values. Just as I had to check for the same thing when using the old CMUD format (well, the new-old format).
So my question is: Why can't CMUD process one single db record within the JSON array but can handle 2 or more?
Or, what am I doing wrong? |
|
_________________ Sic itur ad astra.
Last edited by Anaristos on Thu Jun 24, 2010 9:11 pm; edited 1 time in total |
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Jun 20, 2010 5:55 am |
Apparently, this doesn't seem to be considered a bug, and maybe it isn't. However, the following format is a perfectly valid JSON structure:
| Code: |
[{"Label":"The Cell","Zone":"Atlantis","Room":24453}]
|
If, for instance, this is run through a C# JSON parser, it will return an Arraylist consisting of a single Hashtable. Arraylists are the equivalent to CMUD string lists and Hashtables are equivalent to CMUD db records.
This currently does not work in CMUD. If you assign the above string to a variable, it will turn it into a string list.
| Code: |
Label=The Cell|Zone=Atlantis|Room=24453
|
Which is certainly not what the structure depicts.
The problem is similar to the one described with the single db record problem I posted elsewhere using the previous format. In that situation if you enclosed the single string in double quotes, it got turned into a string list rather than a db record. You stated that this was done for backward compatibility. However, there shouldn't be any backward compatibility concerns when using JSON structures, since the weren't being used prior to 3.18.
This means that if CMUD is used to send or receive JSON structures, then the JSON parser will have to be aware that CMUD is either the subject or object of these structures and have a special case to handle them.
The fact that the structure contains "key":"val" elements is an indication that is is a string list of db records (as the fact that if there are 2 or more such set of elements CMUD handles them correctly indicates).
A string list should only be created when the elements are "val1","val2",..."valN". I do realize that would make "=" a special character, and that a string list value would have to be double double-quoted. (""val1=val2""). But this would meet the JSON standard, imho. |
|
_________________ Sic itur ad astra. |
|
|
 |
GeneralStonewall Magician
Joined: 02 Feb 2004 Posts: 364 Location: USA
|
Posted: Sun Jun 20, 2010 7:38 am |
Where is it showing it as 'Label=The Cell|Zone=Atlantis|Room=24453'?
If you're just #printing the variable, that's the correct output. |
|
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Jun 20, 2010 7:53 am |
It is correct for a string list, but that's not what the JSON structure has. The JSON structure has a string list of db records. This fails to be rendered by CMUD only in the case where the JSON list only has one db record. What I showed is what the variable looks like. I know it looks like a db record, but it isn't.
I guess this will make the problem clearer:
| Code: |
#VAR temp %json("[{""Label"":""The Cell"","Zone"":""Atlantis"",""Room"":24453}]")
|
gets turned into a string list.
| Code: |
#VAR temp %json("{""Label"":""The Cell"",""Zone"":""Atlantis"",""Room"":24453}")
|
gets turned into a db record.
| Code: |
#VAR temp %json("[{""Label"":""The Cell"",""Zone"":""Atlantis"",""Room"":24453},{""Label"":""The Grand City of Aylor (G)"",""Zone"":""Grand City of Aylor"",""Room"":1}]")
|
gets correctly turned into a string list of db records. There is only a problem when the JSON array (list) only contains one entry. |
|
_________________ Sic itur ad astra.
Last edited by Anaristos on Mon Jun 21, 2010 12:50 am; edited 1 time in total |
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Mon Jun 21, 2010 12:46 am |
Further problems:
| Code: |
$rec = {"RoomID":13892}
;;
$rec = %json($rec)
;;
post-json record: RoomID=13892
//
//Now I if try to access the db records in the sting list, I get nothing.
//
#FORALL $rec {#ECHO roomID = %db( %i ,RoomID)}
|
If I do a #FORALL on $rec, I get nothing. Which, when considering what has been said, makes sense. Since $rec IS a db record. But to make it so, I had to remove the JSON list marker. Had I not, the %json function would have returned a string list, not a db record.
However, if
| Code: |
$rec = [{"RoomID":13887}, {"RoomID":13889}, {"RoomID":13891}, {"RoomID":13892}]
;;
$rec = %json($rec)
;;
post-json record: RoomID=RoomID=13887|RoomID=13889|RoomID=13891|RoomID=13892
//
//Now I if try to access the db records in the sting list, it works.
//
#FORALL $rec {#ECHO roomID = %db( %i ,RoomID)}
|
and the #FORALL works like a champ, which again, makes sense. Prior to the implementation of JSON structures, #FORALL would have worked on both. I am not arguing in favor of the old ways, my point is that at that time CMUD could handle a string list consisting of a single db record. Now, it can't.
If I take the kludge out and let the single db record JSON structure float through, it will turn it into a string list, which is not the intent.
| Code: |
$rec = [{"RoomID":13892}]
|
The above is not processed correctly. To argue this position further I will make the claim the if $rec were a string list then it should look like this:
| Code: |
$rec = ["RoomID=13892"]
|
Now, with that format, it is certainly a string list consisting of a single item. The {"key":"val"} format should be a dead giveaway that a structure is a db record (Hashtable in the Microsoft C languages and in Java, an object in Javascript). |
|
_________________ Sic itur ad astra. |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Jun 21, 2010 4:54 pm |
I'm going to look into #FORALL to see if I can make it work with DB variables. Essentially, #FORALL and #LOOPDB will end up doing the same thing.
However, I think you are also getting a bit confused. To implement your example further above, I enter this command:
| Code: |
| #var list %json("[{""Label"":""The Cell"",""Zone"":""Atlantis"",""Room"":24453}]") |
To properly display the stored contents of the @list variable, I type "#VAR list" and get this:
| Code: |
list (StringList) "Label=The Cell|Zone=Atlantis|Room=24453"
json: [{"Label":"The Cell","Zone":"Atlantis","Room":24453}] (array) |
First, notice that the json representation of what CMUD has stored internally for @list is perfectly correct. Also notice that the (StringList) value in the first line has " quotes around it. The indicates the entire database variable is a single item in a string list. So all of this is correct.
If you just use #PRINT to see the output, the quotes are going to get stripped.
IMPORTANT: You cannot just use "#PRINT @var" to display the correct underlying table structure. That's the whole point of using JSON internally! The old string list and database variable string formats CANNOT properly show the internal structure of nested lists and tables.
Using the above variable, if I type:
#SHOW %numitems(@list)
then I get the correct answer of "1" which shows that CMUD *is* storing your database record as a single element of a string list. If I do
#FORALL @List {#SHOW %i}
then it properly shows a single line with the proper database record.
The problem with your second examples is that you are not creating proper STRING values. Here is your code from above:
| Code: |
$rec = {"RoomID":13892}
$rec = %json($rec) |
That is WRONG. Your first line is not assigning a STRING value to $rec, it is using {} to create a string list or database variable. This is the one case where {} does NOT act as "quotes with allowed variable expansion". To maintain backwards compatibility with lines like
list = {a|b|c}
I was forced to kludge the {} delimiters to work as "string list creation" delimiters when assigning values to a variable.
So, the correct syntax for your example above should be this instead:
| Code: |
$rec = "{""RoomID"":13892}"
$rec = %json($rec) |
and then it will work properly.
Same with your [] syntax at the end. You need to put it into quotes, like this:
| Code: |
| $rec = "[{""RoomID"":13892}]" |
|
|
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Jun 22, 2010 1:01 am |
I apologize for not correctly displaying the process. I do understand that the string has to be encased in double-quotes. I was just displaying what was being input into the %json function. However, I am still confused. I do nothing different for a JSON string containing a single db-record as I do for a JSON containing multiple db records. I didn't feel that I had to. My assumption was that the process would be the same. Since there is no problem when there are multiple records, then there shouldn't be any problems when there is just one. Or am I wrong in assuming that a string list can contain one or more records and not just more than one record?
|
|
_________________ Sic itur ad astra. |
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Jun 22, 2010 5:54 am |
OK, I am really baffled now. Everything works. I haven't changed the code and everything works as it should. Go figure. Thanks for listening, Zugg.
EDIT: However, something strange does happen with the single db record (JSON Object) embedded in a string list (JSON Array): if you use %numitems on the string list, it will return the number of key/value pairs(!) instead of returning 1. However, if there are 2 or more db records, %numitems will return the correct value.
Again:
| Code: |
rec = [{"LevelLock":0, "Area":"Aylorian Academy", "Index":2, "EntryPoint":"Outside the Aylorian Academy", "FromLevel":1, "ShortID":"", "ZoneID":285, "ToLevel":5}, {"LevelLock":0, "Area":"Grand City of Aylor", "Index":17, "EntryPoint":"Grand City of Aylor", "FromLevel":1, "ShortID":"", "ZoneID":21, "ToLevel":201}]
|
gets treated currectly (a string list consisting of 2 db records).
But this:
| Code: |
rec = {"LevelLock":0, "Area":"Grand City of Aylor", "Index":17, "EntryPoint":"Grand City of Aylor", "FromLevel":1, "ShortID":"", "ZoneID":21, "ToLevel":201}
|
is treated incorrectly (a string list consiting of 8 string values).
The displays were obtained by echoing the output of the %json function to the screen.
The oddest thing is that the Editor will display the variable as db record (!!).
| Zugg wrote: |
The problem with your second examples is that you are not creating proper STRING values. Here is your code from above:
| Code: |
$rec = {"RoomID":13892}
$rec = %json($rec) |
That is WRONG. Your first line is not assigning a STRING value to $rec, it is using {} to create a string list or database variable. This is the one case where {} does NOT act as "quotes with allowed variable expansion". To maintain backwards compatibility with lines like
list = {a|b|c}
I was forced to kludge the {} delimiters to work as "string list creation" delimiters when assigning values to a variable.
So, the correct syntax for your example above should be this instead:
| Code: |
$rec = "{""RoomID"":13892}"
$rec = %json($rec) |
and then it will work properly.
Same with your [] syntax at the end. You need to put it into quotes, like this:
| Code: |
| $rec = "[{""RoomID"":13892}]" |
|
What I showed in the post is not something I created. It was generated by a JSON encoder. The {} are not meant to be the CMUD evaluation indicator (which I use sometimes) it indicates a JSON object, as the the documentation shows here. The reason they don't look as they should be coded is because they have already been internalized and I am showing what the %json function outputs by using #ECHO. When I use them they are, in fact, in the format you showed. Again, the problem only occurs when the list only has one db record and that's the key. |
|
_________________ Sic itur ad astra. |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Jun 22, 2010 5:09 pm |
OK, sorry I was confused by your post. I was assuming that the assignment statements you were showing were CMUD assignments for the command line. In the future you should be clear when you show code like this:
| Code: |
| rec = {"LevelLock":0, "Area":"Grand City of Aylor", "Index":17, "EntryPoint":"Grand City of Aylor", "FromLevel":1, "ShortID":"", "ZoneID":21, "ToLevel":201} |
That you are *not* talking about a CMUD command syntax.
In any case, I still cannot reproduce your problems within CMUD. Here are the two situations that I tested:
1) Here is the test for a string list containing a single database record. Here is the correct code to test this within CMUD:
| Code: |
$rec = "{""RoomID"":13892}"
$rec = %json($rec)
#SHOW Count: %numitems($rec) |
This properly displays 1
| Code: |
| #FORALL $rec {#SHOW Value is: %i} |
properly shows 13892. So this is working fine as far as I can test here.
2) Testing a string list with a single item that is a database record. Again, here is the proper CMUD testing code:
| Code: |
$rec = "{""LevelLock"":0, ""Area"":""Grand City of Aylor"", ""Index"":17, ""EntryPoint"":""Grand City of Aylor"", ""FromLevel"":1, ""ShortID"":"""", ""ZoneID"":21, ""ToLevel"":201}"
$rec = %json($rec)
#SHOW Count: %numitems($rec) |
This correctly shows 8 because you have a db record here with 8 elements. This is *not* a string list, it is a JSON Object Table. To make this into a string list with a single database record, you need [] around it. So yes, the Editor correctly displays this as a RECORD and NOT a string list. Here is the correct CMUD code:
| Code: |
$rec = "[{""LevelLock"":0, ""Area"":""Grand City of Aylor"", ""Index"":17, ""EntryPoint"":""Grand City of Aylor"", ""FromLevel"":1, ""ShortID"":"""", ""ZoneID"":21, ""ToLevel"":201}]"
$rec = %json($rec)
#SHOW Count: %numitems($rec) |
and this gives the correct result of 1. |
|
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Jun 22, 2010 8:58 pm |
I don't know what to think anymore. I find that you are entirely correct. I just keep getting inconsistent results.
I just ran the following experiment:
| Code: |
// at the command line I entered:
#VAR memdb @commem.exec("select [Mob] from [dgmaze] where [Index] = 2",@noparam)
#VAR memdb %json(@memdb)
// have to do as above since using the COM call inside the %json function doesn't work yet.
//Then I entered:
#VAR memdb
//This is the what it shows:
Variable: + memdb (Record) Mob=The Rabid Tiger-man
json: {"Mob":"The Rabid Tiger-man"} (object)
//Which is absolutely correct.
//This is what I get whe I extract the data.
#ECHO %db(@memdb,Mob) ----> The Rabid Tiger Man
|
Which is precisely what it is intended.
So things are working now. Let me take out the kludge from the data provider and allow it to emit single object lists...
I will edit this post with the results.
EDIT:
OK, I took out the kludge from the data provider and allowed it to create single object arrays. I re-started CMUD since the initialization routine reads a single db record at some point. Here is the result of the read:
| Code: |
Variable: + defvtab (StringList) "Default_ConnStr=dbManager.Agent|Default_ScriptPath=C:\USER01\SQLite Expert\Scripts\|Default_TestUser=Anaristos|Default_TestPath=C:\USER01\SQLite Expert\Databases\Test\|Index=1|Default_User=Anaristos|Default_Path=C:\USER01\SQLite Expert\Databases\|Default_TestConnStr=dbManager.Agent|Default_TestScriptPath=C:\USER01\SQLite Expert\TestScripts\"
json: [{"Default_ConnStr":"dbManager.Agent","Default_ScriptPath":"C:\USER01\SQLite Expert\Scripts\","Default_TestUser":"Anaristos","Default_TestPath":"C:\USER01\SQLite Expert\Databases\Test\","Index":1,"Default_User":"Anaristos","Default_Path":"C:\USER01\SQLite Expert\Databases\","Default_TestConnStr":"dbManager.Agent","Default_TestScriptPath":"C:\USER01\SQLite Expert\TestScripts\"}] (array)
|
As you can see, therein lies the problem. If I put in the kludge and send the object without putting into an array, it works. If I take out the kludge, it fails. I will now put the kludge back in and show you the same variable:
| Code: |
Variable: + defvtab (Record) Default_ConnStr=dbManager.Agent|Default_ScriptPath=C:\USER01\SQLite Expert\Scripts\|Default_TestUser=Anaristos|Default_TestPath=C:\USER01\SQLite Expert\Databases\Test\|Index=1|Default_User=Anaristos|Default_Path=C:\USER01\SQLite Expert\Databases\|Default_TestConnStr=dbManager.Agent|Default_TestScriptPath=C:\USER01\SQLite Expert\TestScripts\
json: {"Default_ConnStr":"dbManager.Agent","Default_ScriptPath":"C:\USER01\SQLite Expert\Scripts\","Default_TestUser":"Anaristos","Default_TestPath":"C:\USER01\SQLite Expert\Databases\Test\","Index":1,"Default_User":"Anaristos","Default_Path":"C:\USER01\SQLite Expert\Databases\","Default_TestConnStr":"dbManager.Agent","Default_TestScriptPath":"C:\USER01\SQLite Expert\TestScripts\"} (object)
|
As you can see, it works fine.
The argument is not the it shouldn't be a string list, the argument is that it should be a string list consisting of a single db-record.
instead each key/value pair becomes an item in the string list as attested by the result of %numitems. |
|
_________________ Sic itur ad astra. |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Jun 22, 2010 9:34 pm |
Looking at the output of the #VAR command for the first defvtab, you can see that it did not create any JSON table. So something failed with the call to %json. Can you show the string variable @memdb that is returned from your COM call before you pass it to %json so I can test it here?
| Quote: |
| // have to do as above since using the COM call inside the %json function doesn't work yet. |
You probably won't ever be able to place a COM call directly into the argument for %json. This is because %json is a dual-purposed function...it either *creates* a table given a string value, or it returns the string value of an existing table structure. So the argument is not handled as a "normal" string value, which prevents a direct COM reference from working. |
|
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Jun 22, 2010 10:15 pm |
OK, this is the pre-%json() view of defvtab with the kludge put in:
| Code: |
Variable: + defvtab (Auto) {"Default_TestUser":"Anaristos", "Default_TestScriptPath":"C:\USER01\SQLite Expert\TestScripts\", "Index":1, "Default_User":"Anaristos", "Default_ScriptPath":"C:\USER01\SQLite Expert\Scripts\", "Default_TestConnStr":"dbManager.Agent", "Default_ConnStr":"dbManager.Agent", "Default_Path":"C:\USER01\SQLite Expert\Databases\", "Default_TestPath":"C:\USER01\SQLite Expert\Databases\Test\"}
|
and this is the post-%json() view:
| Code: |
Variable: + defvtab (Record) Default_ConnStr=dbManager.Agent|Default_ScriptPath=C:\USER01\SQLite Expert\Scripts\|Default_TestUser=Anaristos|Default_TestPath=C:\USER01\SQLite Expert\Databases\Test\|Index=1|Default_User=Anaristos|Default_Path=C:\USER01\SQLite Expert\Databases\|Default_TestConnStr=dbManager.Agent|Default_TestScriptPath=C:\USER01\SQLite Expert\TestScripts\
json: {"Default_ConnStr":"dbManager.Agent","Default_ScriptPath":"C:\USER01\SQLite Expert\Scripts\","Default_TestUser":"Anaristos","Default_TestPath":"C:\USER01\SQLite Expert\Databases\Test\","Index":1,"Default_User":"Anaristos","Default_Path":"C:\USER01\SQLite Expert\Databases\","Default_TestConnStr":"dbManager.Agent","Default_TestScriptPath":"C:\USER01\SQLite Expert\TestScripts\"} (object)
|
which is as I show in the post above:
Now with the kludge taken out this is what the pre- and post- views (in that order) look like:
| Code: |
Variable: + defvtab (Auto) [{"Default_TestUser":"Anaristos", "Default_TestScriptPath":"C:\USER01\SQLite Expert\TestScripts\", "Index":1, "Default_User":"Anaristos", "Default_ScriptPath":"C:\USER01\SQLite Expert\Scripts\", "Default_TestConnStr":"dbManager.Agent", "Default_ConnStr":"dbManager.Agent", "Default_Path":"C:\USER01\SQLite Expert\Databases\", "Default_TestPath":"C:\USER01\SQLite Expert\Databases\Test\"}]
|
| Code: |
Variable: + defvtab (StringList) "Default_ConnStr=dbManager.Agent|Default_ScriptPath=C:\USER01\SQLite Expert\Scripts\|Default_TestUser=Anaristos|Default_TestPath=C:\USER01\SQLite Expert\Databases\Test\|Index=1|Default_User=Anaristos|Default_Path=C:\USER01\SQLite Expert\Databases\|Default_TestConnStr=dbManager.Agent|Default_TestScriptPath=C:\USER01\SQLite Expert\TestScripts\"
json: [{"Default_ConnStr":"dbManager.Agent","Default_ScriptPath":"C:\USER01\SQLite Expert\Scripts\","Default_TestUser":"Anaristos","Default_TestPath":"C:\USER01\SQLite Expert\Databases\Test\","Index":1,"Default_User":"Anaristos","Default_Path":"C:\USER01\SQLite Expert\Databases\","Default_TestConnStr":"dbManager.Agent","Default_TestScriptPath":"C:\USER01\SQLite Expert\TestScripts\"}] (array)
|
Again, the problem is not that it is a string list, which is what I want, the problem is that it is not a string list of db records. This only happens when there is only one such db record. As you can see above, 2 or more db records are stored in the string list correctly. |
|
_________________ Sic itur ad astra. |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Jun 23, 2010 4:43 pm |
I think I might have found the problem. Your JSON text contains \ characters. According to the JSON spec, the \ character is used as an "escape" character, which causes the character following it to be treated as a normal character. So where you have \" at the end of your paths, the " quote ends up not getting parsed correctly.
If you go to the Online JSON Parser at http://json.parser.online.fr/ you can test your JSON text to see what I mean.
For CMUD, I used the following commands to test a "fixed" version of your code where I doubled each \ character. Here is the test:
| Code: |
rec="[{""Default_ConnStr"":""dbManager.Agent"",""Default_ScriptPath"":""C:\USER01\SQLite Expert\Scripts\"",""Default_TestUser"":""Anaristos"",""Default_TestPath"":""C:\USER01\SQLite Expert\Databases\Test\"",""Index"":1,""Default_User"":""Anaristos"",""Default_Path"":""C:\USER01\SQLite Expert\Databases\"",""Default_TestConnStr"":""dbManager.Agent"",""Default_TestScriptPath"":""C:\USER01\SQLite Expert\TestScripts\""}]"
db = %json(@rec)
#show %numitems(@db) // returns 1
#show %numitems(@db.1) // returns 9
#forall @db {#loopdb %i {#show $key ":" $val}} |
The last line loops through the string list, then loops through the database record within the string list and displays:
| Code: |
Default_ConnStr : dbManager.Agent
Default_ScriptPath : C:\USER01\SQLite Expert\Scripts\
Default_TestUser : Anaristos
Default_TestPath : C:\USER01\SQLite Expert\Databases\Test\
Index : 1
Default_User : Anaristos
Default_Path : C:\USER01\SQLite Expert\Databases\
Default_TestConnStr : dbManager.Agent
Default_TestScriptPath : C:\USER01\SQLite Expert\TestScripts\ |
which is all correct as far as I can tell.
If I do a "#VAR db" then I get this:
| Code: |
db (StringList) "Default_ConnStr=dbManager.Agent|Default_ScriptPath=C:\USER01\SQLite Expert\Scripts\|Default_TestUser=Anaristos|Default_TestPath=C:\USER01\SQLite Expert\Databases\Test\|Index=1|Default_User=Anaristos|Default_Path=C:\USER01\SQLite Expert\Databases\|Default_TestConnStr=dbManager.Agent|Default_TestScriptPath=C:\USER01\SQLite Expert\TestScripts\"
json: [{"Default_ConnStr":"dbManager.Agent","Default_ScriptPath":"C:\USER01\SQLite Expert\Scripts\","Default_TestUser":"Anaristos","Default_TestPath":"C:\USER01\SQLite Expert\Databases\Test\","Index":1,"Default_User":"Anaristos","Default_Path":"C:\USER01\SQLite Expert\Databases\","Default_TestConnStr":"dbManager.Agent","Default_TestScriptPath":"C:\USER01\SQLite Expert\TestScripts\"}] (array) |
So first, I have no idea how you even got the json output of your @defvtab variable to work without adding the extra \ characters. And second, I still don't see any problem with the results that I am getting, so I'm clearly still not understanding your exact problem. |
|
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Jun 23, 2010 4:45 pm |
Edited: Well, nevermind on one issue. I can see from my post above that the Forum code is stripping the extra \ characters. In the code that I pasted, there were two \ characters but the forum post only shows one. Annoying. So maybe you had the correct json after all?
|
|
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Wed Jun 23, 2010 10:46 pm |
Yes, the JSON is correct, my "\\" were also edited out.
|
|
_________________ Sic itur ad astra. |
|
|
 |
Taz GURU
Joined: 28 Sep 2000 Posts: 1395 Location: United Kingdom
|
Posted: Wed Jun 23, 2010 10:47 pm |
I did an edit of the posts with the paths and can see that the forum database is holding double slash for Anaristos' posts so it does indeed look like he has the correct json.
|
|
_________________ Taz :) |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Jun 24, 2010 4:42 pm |
OK, but even with the fixed json I'm still clueless about the exact problem you are having. As I show above, the proper json is working fine as a database record within a string list for me. As shown by my calls to %numitems, it is a single element string list containing a 9 element database record. So if you are still having trouble with this, I need to see the exact CMUD commands that are not working the way you expect.
|
|
|
|
 |
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Thu Jun 24, 2010 7:31 pm |
RESOLUTION:
This puzzle has been the product of a misunderstanding in my part. As Taz pointed out, I did have the correct JSON structure and yet I couldn't get it to work the way I expected it to work. I went back and reread another post I made regarding the internal representation of db records and string lists. You can find the post here.
I realized after reading that post again, that the problem was the same but seen from another perspective. In fact, that problem was solved by the implementation of JSON structures. I was so used to having CMUD distinguishing between a single db record and a string list when I was using the old (and obsolete) internal structures that I literally failed to see the forest for the trees.
When using the old structures I never had to worry about whether the string list contained one or more records because CMUD would effectively interpret any string as a string list consisting of one item. So if I "looped" through the single-db record string list or used the db record directly didn't make a difference. After I made the other post and was told that my structures were obsolete and that I should upgrade to the actual CMUD structures (which were to become supplanted by JSON structures) I first encountered the one-db record problem.
This is what you said on the subject:
| Zugg wrote: |
Yes, I can confirm this. However, I can't change it. The problem is that doing something like this:
#VAR db "key1=val1|key2=val2|.....|keyN=valN"
needs to create a Database variable and NOT a string list for backwards compatibility. Yes, backwards compatibility is a bitch. To accomplish what you want, you might need to add another set of doubled quotes (for a total of 3 " quote marks at each end of the string).
|
While that is not the solution to my present problem, it points to the right solution!
The fact is, that if I know a script (or application) is sending me a string list I must always treat it as a string list. This was not required with the old format (the one inherited from ZMUD) but does solve the problem in the previous post and in this one.
So this is the proper way to handle the data (imho):
| Code: |
rec = %json("[{"LevelLock":0, "Area":"Grand City of Aylor", "Index":17, "EntryPoint":"Grand City of Aylor", "FromLevel":1, "ShortID":"", "ZoneID":21, "ToLevel":201}]")
//Method 1:
//
$rec = %item(@rec,1)
//
//or Method 2:
//
#FORALL @rec {$rec = %1;...}
//
|
The point made by those examples is that the item must be extracted in some way and/or assigned in some manner before it can be processed.
So what must change, really, is the perspective. One must always treat a string list as a string list (though I haven't experimented with treating a single-item string list as a string, I suspect it won't work correctly or at all).
I am sure this was obvious to most others but, unfortunately, it wasn't obvious to me until now. I apologize for the size of this post. |
|
_________________ Sic itur ad astra. |
|
|
 |
Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Thu Jun 24, 2010 9:02 pm |
Thanks for clarifying this. Hopefully this will help other people that might run into this problem. I'm sure we'll need to help a lot of people who depending upon the intricacies of the old format and were kludging their scripts to handle nested lists in the past.
As you said, the conversion to json fixes how nested lists are handled by treating everything more consistently. Even if that does cause some odd problems in old scripts.
You are correct that one of the fundamental changes is that in old CMUD and zMUD, a "database variable" was ALSO a "string list". In Old CMUD/zMUD, if you have a database variable like this:
dbvar = {name=zugg|level=20}
and then did a "#FORALL @dbvar {#PRINT %i}" then it would print the two values within the string list:
name=zugg
level=20
With the new consistent json tables, the %i value of a object table is the *value* and not the "key=value" result. So in CMUD 3.2x, the result of the above #FORALL command is this:
zugg
20
This is actually consistent with how arrays work in other languages that use associative arrays (arrays with string keys) like Lua, PHP, Perl, etc. You can think of a table object as just an array with string keys instead of numeric keys. But these items still form an "array" and you can still ask for the first item in the array. In the above example, the first item in the array has a key of "name" and a value of "zugg", so when you ask for the first value in the array, it returns "zugg" just like if the array only had numeric indexes.
In 3.2x, any script that depends upon a database variable as also being a string list with the "key=value" result is going to break. This was unfortunate and will probably cause many problems with people upgrading, but I didn't see any way around this change. It just no longer made sense to return "key=value" when fetching the Nth item of a table.
Btw, in 3.21 I am adding a new function called %dbkey. This function will return the "key" string of the Nth element in the table. Syntax is:
%dbkey(dbvar, n)
and it's the same as doing %dbkeys(dbvar).n but is much faster because it doesn't need to build the entire array of all of the keys. |
|
|
|
 |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|