I am just starting to use PL/JSON and I am able to parse non-array data, such as first name, for example:
json_ext.get_string (json (l_list.get (i)), 'firstName');
However I can't figure out how to parse array data such as addresses, for example:
street1 := json_ext.get_string (json (l_list.get (i)), 'addresses.street1');
does not work.
How would I correctly parse array data, using:
street1 := json_ext.get_string (json (l_list.get (i)), 'addresses.street1');
using as an example?
Here is an example of the JSON:
[
{
"firstName": "Edward",
"middleName": "Wolfgang",
"lastName": "Munster",
"addresses": [
{
"city": "",
"addressType": "home",
"state": "CA",
"street1": "1313 Mockingbird Lane",
"street2": ""
},
{
"city": "",
"addressType": "business",
"state": "CA",
"street1": "123 Morgan Rd.",
"street2": ""
}
],
}
Here is the an example of the code I am using:
BEGIN
SELECT json
INTO l_json
FROM json_table
WHERE id = 1;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
l_json := NULL;
END;
l_list := json_list (l_json);
FOR i IN 1 .. l_list.COUNT
LOOP
--These parse correctly
firstname := json_ext.get_string (json (l_list.get (i)), 'firstName');
middlename := json_ext.get_string (json (l_list.get (i)), 'middleName');
lastname := json_ext.get_string (json (l_list.get (i)), 'lastName');
--These do not parse at all
addresstype := json_ext.get_string (json (l_list.get (i)), 'addresses.addressType');
street1 := json_ext.get_string (json (l_list.get (i)), 'addresses.street1');
street2 := json_ext.get_string (json (l_list.get (i)), 'addresses.street2');
city := json_ext.get_string (json (l_list.get (i)), 'addresses.city');
state := json_ext.get_string (json (l_list.get (i)), 'addresses.state');
The example above didn't work for me. I managed to get the following working.
declare
json_data2 json;
json_data json := json('{ "foo": "bar", "list": [ {"key": "value1"}, {"key": "value2"} ] }');
list_value json_list;
begin
list_value := pljson_ext.get_json_list(json_data, 'list');
dbms_output.put_line('Count = '||list_value.count);
for i in 1 .. list_value.count
loop
-- json_data2 := json(list_value.get(i));
json(list_value.get(i)).get('key').print;
-- dbms_output.put_line('key = ' || json_data2.get('key')); -- "key = value"
-- json_data2.get('key').print;
end loop;
end;
/
It's quite simple. Just retrieve the list and iterate it:
-- {
-- "foo": "bar",
-- "list": [
-- {"key": "value"},
-- {"key": "value"}
-- ]
-- }
declare
json_data json := '<the above JSON>';
list_value json_list;
begin
list_value := json_data.get('list');
for i in 1 .. list_value.count
loop
dbms_output.put_line('key = ' || list_value[i].get('key')); -- "key = value"
end;
end;
/
check this example:
DECLARE
OBJ JSON := JSON( '{"pjDATOS_CITAS":[{"SDACLAVE":"32709","PENDIENTES_CITAR":"3","CANTIDAD":"1"},{"SDACLAVE":"32708","PENDIENTES_CITAR":"3","CANTIDAD":"0"}]}' );
LIST_VALUE JSON_LIST;
BEGIN
LIST_VALUE := JSON_LIST(OBJ.GET('pjDATOS_CITAS'));
FOR I IN 1 .. LIST_VALUE.COUNT LOOP
DBMS_OUTPUT.PUT_LINE( 'SDACLAVE->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'SDACLAVE') );
DBMS_OUTPUT.PUT_LINE( 'PENDIENTES_CITAR->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'PENDIENTES_CITAR') );
DBMS_OUTPUT.PUT_LINE( 'CANTIDAD->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'CANTIDAD') );
DBMS_OUTPUT.PUT_LINE( '-------------------------------------------------' );
END LOOP;
END;
and you need fix your JSON FILE... check this example with your JSON:
DECLARE
OBJ JSON := JSON( '{"info_any": {"middleName": "Wolfgang","lastName": "Munster","addresses": [{"city": "","state": "CA","addressType": "home","street2": "","street1": "1313 Mockingbird Lane"},{"city": "","state": "CA","addressType": "business","street2": "","street1": "123 Morgan Rd."}],"firstName": "Edward"}}' );
LIST_VALUE JSON_LIST;
BEGIN
OBJ := JSON ( OBJ.GET('info_any') );
DBMS_OUTPUT.PUT_LINE( 'middleName->'||JSON_EXT.GET_STRING( OBJ , 'middleName') );
DBMS_OUTPUT.PUT_LINE( 'firstName->' ||JSON_EXT.GET_STRING( OBJ , 'firstName') );
DBMS_OUTPUT.PUT_LINE( 'lastName->' ||JSON_EXT.GET_STRING( OBJ , 'lastName') );
DBMS_OUTPUT.PUT_LINE( '-------------------------------------------------' );
LIST_VALUE := JSON_LIST(OBJ.GET('addresses'));
FOR i IN 1 .. LIST_VALUE.COUNT LOOP
DBMS_OUTPUT.PUT_LINE( 'city->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'city') );
DBMS_OUTPUT.PUT_LINE( 'state->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'state') );
DBMS_OUTPUT.PUT_LINE( 'addressType->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'addressType') );
DBMS_OUTPUT.PUT_LINE( 'street2->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'street2') );
DBMS_OUTPUT.PUT_LINE( 'street1->'||JSON_EXT.GET_STRING( JSON(LIST_VALUE.GET(I)) , 'street1') );
DBMS_OUTPUT.PUT_LINE( '-------------------------------------------------' );
END LOOP;
END;
Result:
middleName->Wolfgang
firstName->Edward
lastName->Munster
-------------------------------------------------
city->
state->CA
addressType->home
street2->
street1->1313 Mockingbird Lane
-------------------------------------------------
city->
state->CA
addressType->business
street2->
street1->123 Morgan Rd.
-------------------------------------------------
Related
I want to check if the JSON object has the key "error". If it has, I want to "continue" the loop, otherwise the program can go to all the loop.
This is the JSON:
[
{
"cenario": {
"origem": "",
"out": "SNC",
"country": "",
},
"item": "0015963",
"cod": "17894904009319",
"nat_rec": null
},
{
"item": "0012868",
"error": "product unavailable",
"status": "unavailable",
}
]
How can I check if the object that I'm reading has the key "error" or not?
I tried:
jValue.FindValue('error') // The problem it's going to search for all objects.
jValue.TryGetValue('error', jArray) // if it doesn't find the key in the index that it's searching at the moment, it breaks the application.
I'm doing:
response:= IdHTTP.Get(url);
jValue:= TJsonObject.ParseJSONValue(response);
for x := 0 to 2 do
begin
if jValue.TryGetValue('error', jvalue) then
begin
continue;
end;
memo.Lines.Add('cod_item :' + jValue.GetValue<string>('['+intToStr(x)+'].item'));
memo.Lines.Add('cod: ' + jValue.GetValue<string>('['+intToStr(x)+'].cod'));
end;
In your code, jValue is pointing at a TJSONArray, so when you call TryGetValue('error') on it, you are looking for a field named 'error' on the array itself, which obviously is not going to work. That would only work when called on a TJONObject instead.
You would need to include each object's index when querying for the 'error' field on the array itself, eg:
response := IdHTTP.Get(url);
jValue := TJsonObject.ParseJSONValue(response);
try
jArray := jValue as TJSONArray;
for x := 0 to jArray.Count-1 do
begin
if jArray.FindValue('['+IntToStr(x)+'].error') = nil then
continue;
Memo.Lines.Add('cod_item :' + jArray.GetValue<string>('['+IntToStr(x)+'].item'));
Memo.Lines.Add('cod: ' + jArray.GetValue<string>('['+IntToStr(x)+'].cod'));
end;
finally
jValue.Free;
end;
Alternatively, you can iterate the actual objects in memory instead of searching via paths, eg:
response := IdHTTP.Get(url);
jValue := TJsonObject.ParseJSONValue(response);
try
jArray := jValue as TJSONArray;
for x := 0 to jArray.Count-1 do
begin
jObj := jArray[x] as TJSONObject;
if jObj.GetValue('error') = nil then
begin
Memo.Lines.Add('cod_item :' + jObj.GetValue('item').Value);
Memo.Lines.Add('cod: ' + jObj.GetValue('cod').Value);
end;
end;
finally
jValue.Free;
end;
You can parse it to an array and iterate the array. The two functions HasValueAtObjectKey & GetValueAtObjectKey demonstrate two different ways of checking the object for the key.
program JsonTest;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.JSON;
const TEST_JSON = '[' +
' {' +
' "cenario": {' +
' "origem": "",' +
' "out": "SNC",' +
' "country": ""' +
' },' +
' "item": "0015963",' +
' "cod": "17894904009319",' +
' "nat_rec": null' +
' },' +
' {' +
' "item": "0012868",' +
' "error": "product unavailable",' +
' "status": "unavailable"' +
' }' +
']';
function HasValueAtObjectKey(AKeyName: String; AJsonObject: TJsonObject): Boolean;
var
LValue: TJsonValue;
begin
Result := AJsonObject.TryGetValue(AKeyName, LValue);
end;
function GetValueAtObjectKey(AKeyName: String; AJsonObject: TJsonObject; var AHasValue: Boolean): String;
begin
try
Result := AJsonObject.GetValue(AKeyName).Value;
AHasValue := TRUE;
except
AHasValue := FALSE;
end;
end;
begin
try
var LArray := TJSONObject.ParseJSONValue(TEST_JSON) as TJSONArray;
try
var i:=1;
for var LArrayValue in LArray do
begin
var LHasValue: Boolean;
var LErroVal := ValueAtObjectKey('error', (LArrayValue As TJSONObject), LHasValue);
if LHasValue then
Writeln('Object ', i, ' Has error: ', LErroVal)
else
Writeln('Object ', i, ' Has no error: ');
Writeln('Object ', i, ' HasValueAtObjectKey: ', HasValueAtObjectKey('error', (LArrayValue As TJSONObject)));
Inc(i);
end;
finally
LArray.Free;
end;
ReadLn;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
{
"code": 0,
"data": {
"KAVAUSDT": {
"name": "KAVAUSDT",
"min_amount": "0.5",
"maker_fee_rate": "0.003",
"taker_fee_rate": "0.003",
"pricing_name": "USDT",
"pricing_decimal": 4,
"trading_name": "KAVA",
"trading_decimal": 8
},
"CFXUSDT": {
"name": "CFXUSDT",
"min_amount": "5",
"maker_fee_rate": "0.003",
"taker_fee_rate": "0.003",
"pricing_name": "USDT",
"pricing_decimal": 6,
"trading_name": "CFX",
"trading_decimal": 8
},
... continue
}
}
If there were [ and ] symbols, I could solve it quickly with TJsonArray:
...
JsonArray := JsonValue.GetValue<TJSONArray>('data');
for ArrayElement in JsonArray do
begin
tempName := ArrayElement.GetValue<String>('name');
tempPricingName := ArrayElement.GetValue<String>('pricing_name');
...
end;
There are no [and ] symbols in this Json type.
Without the [ and ] symbols, I cannot access the data, as it is using a for loop.
Is there a simple solution?
There is no array in the JSON document you have shown. "KAVAUSDT", "CFXUSDT", etc are not array elements, they are simply named object fields of the "data" object. If you need to loop through the child fields of the "data" object, you can use TJSONObject (not TJSONArray!) for that, eg:
...
JsonObj := JsonValue.GetValue<TJSONObject>('data');
for Field in JsonObj do
begin
FieldObj := Field.JsonValue as TJSONObject;
tempName := FieldObj.GetValue<String>('name');
tempPricingName := FieldObj.GetValue<String>('pricing_name');
...
end;
I'm not familiar with Pascal. I would like to show 10 checkbox before installing.
The user can check several checkboxes according to the group of catalogs he wants to install (10 checkboxes = 10 groups of catalogs).
These checkboxes have to be tested in FILES section and in CODE section.
In FILES section only catalogs of a checked group will be installed.
In CODE section, the pictures will be downloaded and unzipped according to the group of catalogs checked.
I made 100 hundred tries but an error occurs because the local variables can not be used in other sections.
Thanks for your Help
Icho
[Languages]
Name: fr; MessagesFile: compiler:Languages\French.isl; LicenseFile: C:\Dev\Phi8\licensefr.TXT
Name: en; MessagesFile: compiler:Default.isl; LicenseFile: C:\Dev\Phi8\licenseen.TXT
[Setup]
#include "C:\Dev\Inno Download Plugin\idp.iss"
#include "C:\Dev\Inno Download Plugin\french.iss"
[Tasks]
Name: "chkbInstallFR"; Description: "France"; MinVersion: 0.0,5.0
Name: "chkbInstallMO"; Description: "Monaco, Andorre, TAAF, SPM"; MinVersion: 0.0,5.0
Name: "chkbInstallBELUX"; Description: "Belgique, Luxembourg"; MinVersion: 0.0,5.0
Name: "chkbInstallSUI"; Description: "Suisse, Liechtenstein"; MinVersion: 0.0,5.0
Name: "chkbInstallITA"; Description: "Italie"; MinVersion: 0.0,5.0
Name: "chkbInstallALL"; Description: "Allemagne"; MinVersion: 0.0,5.0
Name: "chkbInstallEURONU"; Description: "Europa, Nations Unies, sepac"; MinVersion: 0.0,5.0
Name: "chkbInstallILE"; Description: "Ile des Antilles, Pacifique, Océan indien"; MinVersion: 0.0,5.0
Name: "chkbInstallAFR"; Description: "Anciennes colonies françaises"; MinVersion: 0.0,5.0
Name: "chkbInstallBUR"; Description: "Bureaux français en Europe, Asie, Moyen-Orient"; MinVersion: 0.0,5.0
[Dirs]
Name: {app}\Datas
Name: {app}\Pic
Name: {app}\Pic\AN
Name: {app}\Pic\ANE
Name: {app}\Pic\UNY
[Files]
Source: C:\Sources\Phi\Exe\Datas\UNY_BIN20P.s2db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallFR;
Source: C:\Sources\Phi\Exe\Datas\UNY_BIN20D.s2db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallFR;
Source: C:\Sources\Phi\Exe\Datas\AN_BIN20P.s2db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\AN_BIN20D.s2db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\ANE_BIN20P.s2db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\ANE_BIN20D.s2db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallMO;
Source: C:\Dev\Philatelix8\Install\7za.exe; DestDir: "{app}"; Flags: deleteafterinstall;
[Icons]
[Run]
Filename: {app}\7za.exe; Parameters: "x ""{tmp}UNY.zip"" -o""{app}\Pic\UNY"" * -aoa"; Flags: runascurrentuser;
Filename: {app}\7za.exe; Parameters: "x ""{tmp}AN.zip"" -o""{app}\Pic\AN"" * -aoa"; Flags: runascurrentuser;
Filename: {app}\7za.exe; Parameters: "x ""{tmp}ANE.zip"" -o""{app}\Pic\ANE"" * -aoa"; Flags: runascurrentuser;
[INI]
[Code]
{ RedesignWizardFormBegin } // Don't remove this line!
// Don't modify this section. It is generated automatically.
var
chkbInstallFR: TNewCheckBox;
chkbInstallMO: TNewCheckBox;
chkbInstallBELUX: TNewCheckBox;
chkbInstallSUI: TNewCheckBox;
chkbInstallITA: TNewCheckBox;
chkbInstallALL: TNewCheckBox;
chkbInstallEURONU: TNewCheckBox;
chkbInstallILE: TNewCheckBox;
chkbInstallAFR: TNewCheckBox;
chkbInstallBUR: TNewCheckBox;
procedure RedesignWizardForm;
begin
with WizardForm.SelectTasksLabel do
begin
Visible := False;
Left := ScaleX(392);
end;
{ chkbInstallFR }
chkbInstallFR := TNewCheckBox.Create(WizardForm);
with chkbInstallFR do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(16);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'France';
end;
{ chkbInstallMO }
chkbInstallMO := TNewCheckBox.Create(WizardForm);
with chkbInstallMO do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(40);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Monaco, Andorre, TAAF, SPM';
end;
{ chkbInstallBELUX }
chkbInstallBELUX := TNewCheckBox.Create(WizardForm);
with chkbInstallBELUX do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Belgique et Luxembourg';
end;
{ chkbInstallSUI }
chkbInstallSUI := TNewCheckBox.Create(WizardForm);
with chkbInstallSUI do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Suisse et Liechtenstein';
end;
{ chkbInstallITA }
chkbInstallITA := TNewCheckBox.Create(WizardForm);
with chkbInstallITA do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Italie';
end;
{ chkbInstallALL }
chkbInstallALL := TNewCheckBox.Create(WizardForm);
with chkbInstallALL do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Allemagne';
end;
{ chkbInstallEURONU }
chkbInstallEURONU := TNewCheckBox.Create(WizardForm);
with chkbInstallEURONU do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := False;
Caption := 'Europa, Nations Unies, sepac';
end;
{ chkbInstallILE }
chkbInstallILE := TNewCheckBox.Create(WizardForm);
with chkbInstallILE do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Iles des antilles, Pacifique et Océan indien';
end;
{ chkbInstallAFR }
chkbInstallAFR := TNewCheckBox.Create(WizardForm);
with chkbInstallAFR do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Colonies françaises en Afrique';
end;
{ chkbInstallBUR }
chkbInstallBUR := TNewCheckBox.Create(WizardForm);
with chkbInstallBUR do
begin
Parent := WizardForm.WelcomePage;
Left := ScaleX(8);
Top := ScaleY(64);
Width := ScaleX(97);
Height := ScaleY(17);
Checked := True;
Caption := 'Bureaux français en Europe, Asie, Moyen-Orient';
end;
chkbInstallFR.TabOrder := 0;
chkbInstallMO.TabOrder := 1;
chkbInstallBELUX.TabOrder := 2;
chkbInstallSUI.TabOrder := 3;
chkbInstallITA.TabOrder := 4;
chkbInstallALL.TabOrder := 5;
chkbInstallEURONU.TabOrder := 6;
chkbInstallILE.TabOrder := 7;
chkbInstallAFR.TabOrder := 8;
chkbInstallBUR.TabOrder := 9;
{ ReservationBegin }
// This part is for you. Add your specialized code here.
if chkbInstallFR.checked then
begin
idpAddFile('http://www.philatelix.fr/Divers/PHI/UNY.zip', ExpandConstant('{tmp}UNY.zip'));
end;
if chkbInstallMO.checked then
begin
idpAddFile('http://www.philatelix.fr/Divers/PHI/AN.zip', ExpandConstant('{tmp}AN.zip'));
idpAddFile('http://www.philatelix.fr/Divers/PHI/ANE.zip', ExpandConstant('{tmp}ANE.zip'));
end;
{ ReservationEnd }
end;
// Don't modify this section. It is generated automatically.
{ RedesignWizardFormEnd } // Don't remove this line!
procedure InitializeWizard;
begin
{ Download after "Ready" wizard page }
idpDownloadAfter(wpReady);
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
if chkbInstallFR.checked then
begin
FileCopy(ExpandConstant('{tmp}\UNY.zip'), ExpandConstant('{app}\UNY.zip'), false);
end;
if chkbInstallMO.checked then
begin
FileCopy(ExpandConstant('{tmp}\AN.zip'), ExpandConstant('{app}\AN.zip'), false);
FileCopy(ExpandConstant('{tmp}\ANE.zip'), ExpandConstant('{app}\ANE.zip'), false);
end;
end;
end;
function InstallFR: Boolean;
begin
if chkbInstallFR.checked then
begin
Result := TRUE
end;
else
begin
Result := FALSE
end;
else
end;
function InstallMO: Boolean;
begin
if chkbInstallMO.checked then
begin
Result := TRUE
end;
else
begin
Result := FALSE
end;
end;
with the following code, the checkboxes are displaid exactly where i want but :
The source files are not installed
The installer downloads all ZIP files
I don't know how to arrange the code for the source files are copied and the ZIP are downloaded according to the checkboxes.
[Setup]
OutputBaseFilename=Install_Phi_21
...
DisableWelcomePage=no
WizardImageFile=logoPHI.bmp
;
#include "C:\Dev\Inno Download Plugin\idp.iss"
#include "C:\Dev\Inno Download Plugin\french.iss"
[Tasks]
Name: desktopicon; Description: Créer une &icône sur le bureau; GroupDescription: Additional icons:
[Dirs]
Name: {app}\Pic
Name: {app}\Pic\FR
Name: {app}\Pic\MO
[Files]
...
Source: C:\Sources\Phi\Exe\Datas\UNY_BIN20P2D.s2db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallFR;
Source: C:\Sources\Phi\Exe\Datas\UNY_BIN20D.s2db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallFR;
Source: C:\Sources\Phi\Exe\Datas\AN_BIN20P2D.s2db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\AN_BIN20D.s2db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\ANE_BIN20P2D.s2db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\ANE_BIN20D.s2db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallMO;
Source: C:\Dev\Phi\Install\7za.exe; DestDir: "{app}"; Flags: deleteafterinstall;
[Run]
Filename: {app}\7za.exe; Parameters: "x ""{tmp}UNY.zip"" -o""{app}\Pic\UNY"" * -aoa"; Flags: runascurrentuser;
Filename: {app}\7za.exe; Parameters: "x ""{tmp}AN.zip"" -o""{app}\Pic\AN"" * -aoa"; Flags: runascurrentuser;
Filename: {app}\7za.exe; Parameters: "x ""{tmp}ANE.zip"" -o""{app}\Pic\ANE"" * -aoa"; Flags: runascurrentuser;
[INI]
Filename: {app}\phi.url; Section: InternetShortcut; Key: URL; String: http://www.phi.com
[Code]
var
Page : TWizardPage;
chkbInstallFR: TCheckBox;
chkbInstallMO: TCheckBox;
chkbInstallBELUX: TCheckBox;
chkbInstallSUI: TCheckBox;
chkbInstallITA: TCheckBox;
chkbInstallALL: TCheckBox;
chkbInstallEURONU: TCheckBox;
chkbInstallILE: TCheckBox;
chkbInstallAFR: TCheckBox;
chkbInstallBUR: TCheckBox;
procedure RPage;
begin
Page := CreateCustomPage(wpWelcome, 'Sélection des pays','');
chkbInstallFR := TCheckBox.Create(Page);
chkbInstallFR.Top := ScaleY(8);
chkbInstallFR.Left := ScaleX(0);
chkbInstallFR.Width := Page.SurfaceWidth;
chkbInstallFR.Height := ScaleY(17);
chkbInstallFR.Caption := 'France';
chkbInstallFR.Checked := True;
chkbInstallFR.Parent := Page.Surface;
chkbInstallMO := TCheckBox.Create(Page);
chkbInstallMO.Top := ScaleY(35);
chkbInstallMO.Left := ScaleX(0);
chkbInstallMO.Width := Page.SurfaceWidth;
chkbInstallMO.Height := ScaleY(17);
chkbInstallMO.Caption := 'Monaco, Andorre, TAAF, SPM';
chkbInstallMO.Checked := True;
chkbInstallMO.Parent := Page.Surface;
end;
procedure InitializeWizard;
begin
RPage;
if chkbInstallFR .State= cbchecked then
begin
idpAddFile('http://www.phi.com/Divers/PHI/UNY.zip', ExpandConstant('{tmp}UNY.zip'));
end;
if chkbInstallMO .State= cbchecked then
begin
idpAddFile('http://www.phi.com/Divers/PHI/AN.zip', ExpandConstant('{tmp}AN.zip'));
idpAddFile('http://www.phi.com/Divers/PHI/ANE.zip', ExpandConstant('{tmp}ANE.zip'));
end;
{ Download after "Ready" wizard page }
idpDownloadAfter(wpReady);
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
if chkbInstallFR .State= cbchecked then
begin
FileCopy(ExpandConstant('{tmp}\UNY.zip'), ExpandConstant('{app}\UNY.zip'), false);
end;
if chkbInstallMO .State= cbchecked then
begin
FileCopy(ExpandConstant('{tmp}\AN.zip'), ExpandConstant('{app}\AN.zip'), false);
FileCopy(ExpandConstant('{tmp}\ANE.zip'), ExpandConstant('{app}\ANE.zip'), false);
end;
end;
end;
function InstallFR: Boolean;
begin
Result := chkbInstallFR .State;
end;
function InstallMO: Boolean;
begin
Result := chkbInstallMO .State;
end;
This is the end of my monologue. I finally did exactly what i want :
Installing some files depending on which checboxes are checked
Downloading and installing ZIP files depending on which checboxes are checked
Advantage of this method, you don't need to download a big install file. The installer will download on your server the needed files.
[Setup]
#include "C:\Dev\Inno Download Plugin\idp.iss"
#include "C:\Dev\Inno Download Plugin\french.iss"
[Dirs]
Name: {app}\Pic
Name: {app}\Pic\FR
Name: {app}\Pic\MO
[Files]
Source: C:\Sources\Phi\Exe\Datas\FR_BIN20P2D.s3db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallFR;
Source: C:\Sources\Phi\Exe\Datas\FR_BIN20D.s3db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallFR;
Source: C:\Sources\Phi\Exe\Datas\MO_BIN20P2D.s3db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\MO_BIN20D.s3db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\AN_BIN20P2D.s3db; DestDir: {app}\Datas; Flags: ignoreversion; Check: InstallMO;
Source: C:\Sources\Phi\Exe\Datas\AN_BIN20D.s3db; DestDir: {app}\datas; Flags: onlyifdoesntexist; Check: InstallMO;
Source: C:\Dev\Phi\Install\7za.exe; DestDir: "{app}"; Flags: deleteafterinstall;
[Run]
Filename: {app}\7za.exe; Parameters: "x ""{tmp}CAV.zip"" -o""{app}\Pic\CAV"" * -aoa"; Flags: runascurrentuser; Check: InstallFR;
Filename: {app}\7za.exe; Parameters: "x ""{tmp}SIC.zip"" -o""{app}\Pic\SIC"" * -aoa"; Flags: runascurrentuser; Check: InstallMO;
[Code]
{ RedesignWizardFormBegin } // Don't remove this line!
// Don't modify this section. It is generated automatically.
var
Page : TWizardPage;
chkbInstallFR: TCheckBox;
chkbInstallMO: TCheckBox;
chkbInstallBELUX: TCheckBox;
chkbInstallSUI: TCheckBox;
chkbInstallITA: TCheckBox;
chkbInstallALL: TCheckBox;
chkbInstallEURONU: TCheckBox;
chkbInstallILE: TCheckBox;
chkbInstallAFR: TCheckBox;
chkbInstallBUR: TCheckBox;
procedure RPage;
begin
Page := CreateCustomPage(wpSelectComponents, 'Sélection des pays','');
chkbInstallFR := TCheckBox.Create(Page);
chkbInstallFR.Top := ScaleY(8);
chkbInstallFR.Left := ScaleX(0);
chkbInstallFR.Width := Page.SurfaceWidth;
chkbInstallFR.Height := ScaleY(17);
chkbInstallFR.Caption := 'France';
chkbInstallFR.Checked := True;
chkbInstallFR.Parent := Page.Surface;
chkbInstallMO := TCheckBox.Create(Page);
chkbInstallMO.Top := ScaleY(35);
chkbInstallMO.Left := ScaleX(0);
chkbInstallMO.Width := Page.SurfaceWidth;
chkbInstallMO.Height := ScaleY(17);
chkbInstallMO.Caption := 'Monaco, Andorre, TAAF, SPM';
chkbInstallMO.Checked := True;
chkbInstallMO.Parent := Page.Surface;
chkbInstallBELUX := TCheckBox.Create(Page);
chkbInstallBELUX.Top := ScaleY(62);
chkbInstallBELUX.Left := ScaleX(0);
chkbInstallBELUX.Width := Page.SurfaceWidth;
chkbInstallBELUX.Height := ScaleY(17);
chkbInstallBELUX.Caption := 'Belgique, Luxembourg';
chkbInstallBELUX.Checked := True;
chkbInstallBELUX.Parent := Page.Surface;
chkbInstallSUI := TCheckBox.Create(Page);
chkbInstallSUI.Top := ScaleY(89);
chkbInstallSUI.Left := ScaleX(0);
chkbInstallSUI.Width := Page.SurfaceWidth;
chkbInstallSUI.Height := ScaleY(17);
chkbInstallSUI.Caption := 'Suisse, Liechtenstein';
chkbInstallSUI.Checked := True;
chkbInstallSUI.Parent := Page.Surface;
chkbInstallITA := TCheckBox.Create(Page);
chkbInstallITA.Top := ScaleY(116);
chkbInstallITA.Left := ScaleX(0);
chkbInstallITA.Width := Page.SurfaceWidth;
chkbInstallITA.Height := ScaleY(17);
chkbInstallITA.Caption := 'Italie';
chkbInstallITA.Checked := True;
chkbInstallITA.Parent := Page.Surface;
chkbInstallALL := TCheckBox.Create(Page);
chkbInstallALL.Top := ScaleY(143);
chkbInstallALL.Left := ScaleX(0);
chkbInstallALL.Width := Page.SurfaceWidth;
chkbInstallALL.Height := ScaleY(17);
chkbInstallALL.Caption := 'Allemagne';
chkbInstallALL.Checked := True;
chkbInstallALL.Parent := Page.Surface;
chkbInstallEURONU := TCheckBox.Create(Page);
chkbInstallEURONU.Top := ScaleY(170);
chkbInstallEURONU.Left := ScaleX(0);
chkbInstallEURONU.Width := Page.SurfaceWidth;
chkbInstallEURONU.Height := ScaleY(17);
chkbInstallEURONU.Caption := 'Europa, Nations Unies, sepac';
chkbInstallEURONU.Checked := True;
chkbInstallEURONU.Parent := Page.Surface;
chkbInstallILE := TCheckBox.Create(Page);
chkbInstallILE.Top := ScaleY(197);
chkbInstallILE.Left := ScaleX(0);
chkbInstallILE.Width := Page.SurfaceWidth;
chkbInstallILE.Height := ScaleY(17);
chkbInstallILE.Caption := 'Iles des antilles, Pacifique et Océan indien';
chkbInstallILE.Checked := True;
chkbInstallILE.Parent := Page.Surface;
chkbInstallAFR := TCheckBox.Create(Page);
chkbInstallAFR.Top := ScaleY(8);
chkbInstallAFR.Left := ScaleX(210);
chkbInstallAFR.Width := Page.SurfaceWidth;
chkbInstallAFR.Height := ScaleY(17);
chkbInstallAFR.Caption := 'Anciennes colonies françaises en Afrique';
chkbInstallAFR.Checked := True;
chkbInstallAFR.Parent := Page.Surface;
chkbInstallBUR := TCheckBox.Create(Page);
chkbInstallBUR.Top := ScaleY(35);
chkbInstallBUR.Left := ScaleX(210);
chkbInstallBUR.Width := Page.SurfaceWidth;
chkbInstallBUR.Height := ScaleY(17);
chkbInstallBUR.Caption := 'Bureaux français à l''étranger';
chkbInstallBUR.Checked := True;
chkbInstallBUR.Parent := Page.Surface;
end;
procedure InitializeWizard;
begin
RPage;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then //essayer ssInstall au lieu de ssPostInstall
begin
if chkbInstallFR .State= cbchecked then
begin
FileCopy(ExpandConstant('{tmp}\CAV.zip'), ExpandConstant('{app}\CAV.zip'), false);
end;
if chkbInstallMO .State= cbchecked then
begin
FileCopy(ExpandConstant('{tmp}\SIC.zip'), ExpandConstant('{app}\SIC.zip'), false);
end;
end;
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
result := True;
case CurPageID of
100:
begin
if chkbInstallFR .State= cbchecked then
begin
idpAddFile('http://www.phi.com/PHI/CAV.zip', ExpandConstant('{tmp}CAV.zip'));
end
else
begin
msgbox('Not France!',mbError, MB_OK)
end;
if chkbInstallMO .State= cbchecked then
begin
idpAddFile('http://www.phi.com/PHI/SIC.zip', ExpandConstant('{tmp}SIC.zip'));
end
else
begin
msgbox('Not Monaco!',mbError, MB_OK)
end;
end;
wpSelectTasks:
begin
end;
wpReady:
begin
end;
end;
{ Download after "Ready" wizard page }
idpDownloadAfter(wpReady);
end;
function InstallFR: Boolean;
begin
if chkbInstallFR .State = cbchecked then
begin
Result := TRUE;
end
else
begin
Result := FALSE;
end;
end;
function InstallMO: Boolean;
begin
if chkbInstallMO .State = cbchecked then
begin
Result := TRUE;
end
else
begin
Result := FALSE;
end;
end;
this is my go function
func logInFirst(res http.ResponseWriter, req *http.Request) {
type Resp struct {
Result []map[string]interface{} `json:"Result,omitempty"`
Result1 []map[string]interface{} `json:"Result1,omitempty"`
Result2 []map[string]interface{} `json:"Result2,omitempty"`
Status string `json:"Status"`
}
type AxleUser struct {
ShopID string `json:"ShopID"`
VehicleType string `json:"VehicleType"`
}
var Response Resp
Response.Status = "failed"
Result := make(map[string]interface{})
Result1 := make(map[string]interface{})
Result2 := make(map[string]interface{})
//db, err := sql.Open("mysql", "root:chikkIbuddI57#tcp(127.0.0.1:3306)/b2b")
db, err := sql.Open("mysql", "awsgobumpr:gobumpr123#tcp(briaxpgbmpr.cx4twoxoumct.ap-southeast-1.rds.amazonaws.com)/b2b_optimization")
if err != nil {
panic(err.Error())
}
defer db.Close()
rnd := render.New()
b, err := ioutil.ReadAll(req.Body)
defer req.Body.Close()
if err != nil {
panic(err.Error())
}
// Unmarshal the request body
var msg AxleUser
err = json.Unmarshal(b, &msg)
if err != nil {
panic(err.Error())
}
//fmt.Println(msg)
// get shop id from emp table using mobile number and password
brandrows, branderr := db.Query("SELECT DISTINCT brand,model FROM admin_vehicle_table_new WHERE type=?", msg.VehicleType)
if branderr != nil {
panic(branderr.Error())
}
brandcolumns, branderr := brandrows.Columns()
if branderr != nil {
panic(branderr.Error())
}
brandcount := len(brandcolumns)
brandValues := make([]string, brandcount)
brandScanArgs := make([]interface{}, brandcount)
for i := range brandValues {
brandScanArgs[i] = &brandValues[i]
}
for brandrows.Next() {
branderr := brandrows.Scan(brandScanArgs...)
//fmt.Println(branderr)
if branderr != nil {
panic(branderr.Error())
}
for i, v := range brandValues {
Result[brandcolumns[i]] = v
}
Response.Result = append(Response.Result, Result)
}
servicerows, serviceerr := db.Query("SELECT DISTINCT b2b_service_type FROM b2b_service_type WHERE b2b_vehicle_type=? and b2b_flag=0 and b2b_shop_id=0 UNION SELECT b2b_service_type FROM b2b_service_type WHERE b2b_vehicle_type=? and b2b_flag=0 and b2b_shop_id=?", msg.VehicleType, msg.VehicleType, msg.ShopID)
if serviceerr != nil {
panic(serviceerr.Error())
}
servicecolumns, serviceerr := servicerows.Columns()
if serviceerr != nil {
panic(serviceerr.Error())
}
servicecount := len(servicecolumns)
serviceValues := make([]string, servicecount)
serviceScanArgs := make([]interface{}, servicecount)
for i := range serviceValues {
serviceScanArgs[i] = &serviceValues[i]
}
for servicerows.Next() {
serviceerr := servicerows.Scan(serviceScanArgs...)
if serviceerr != nil {
panic(serviceerr.Error())
}
for i, v := range serviceValues {
Result1[servicecolumns[i]] = v
}
Response.Result1 = append(Response.Result1, Result1)
}
repairrows, repairerr := db.Query("SELECT DISTINCT b2b_repair_decription FROM b2b_repair_decription WHERE b2b_vehicle_type=? and b2b_shop_id=0 UNION SELECT b2b_repair_decription FROM b2b_repair_decription WHERE b2b_vehicle_type=? and b2b_shop_id=?", msg.VehicleType, msg.VehicleType, msg.ShopID)
if repairerr != nil {
panic(repairerr.Error())
}
repaircolumns, repairerr := repairrows.Columns()
if repairerr != nil {
panic(repairerr.Error())
}
repaircount := len(repaircolumns)
repairValues := make([]string, repaircount)
repairScanArgs := make([]interface{}, repaircount)
for i := range repairValues {
repairScanArgs[i] = &repairValues[i]
}
for repairrows.Next() {
repairerr := repairrows.Scan(repairScanArgs...)
if repairerr != nil {
panic(repairerr.Error())
}
for i, v := range repairValues {
Result2[repaircolumns[i]] = v
}
Response.Result2 = append(Response.Result2, Result2)
}
Response.Status = "success"
res.Header().Set("Content-Type", "application/json")
rnd.JSON(res, http.StatusOK, Response)
}
My Desrired output is a json string like this
{
"Result": [
{
"brand": "Hero Honda",
"model": "Passion Pro"
},
{
"brand": "Yamaha",
"model": "120"
},...
]
"Result1":[
{
"service_type" : "repairs",
},
{
"service_type" : "general service",
},...
]
"Result2":[
{
"b2b_repair_decription": "Tire Replacement"
},
{
"b2b_repair_decription": "Electric work"
},...
]
}
but the output which i got contains the same row instead of all the rows like
this,
{
"Result": [
{
"brand": "Yamaha",
"model": "120"
},
{
"brand": "Yamaha",
"model": "120"
},...
]
"Result1":[
{
"service_type" : "general service",
},
{
"service_type" : "general service",
},...
]
"Result2":[
{
"b2b_repair_decription": "Electric work"
},
{
"b2b_repair_decription": "Electric work"
},...
]
}
i tried appending in the loop , but it dint work. i even tried defining the Result, Result1, Result2 as array of interfaces
can someone help me with this issue?
I am now coding with Martini and AppEngine/Go.
I want to use memcache to serve JSON data.
But the response is invalid JSON format.Why "null" is in the response?
null{"results":[{"Title":"Nikkei225","PriceTime":"2014-04-25 06:28:00 UTC","Price":"14,429.26","Diff":"+24.27(0.1%)"},{"Title":"USD/JPY","PriceTime":"2014-04-25 20:49:00 UTC","Price":"102.12-102.16","Diff":"-0.15(-0.1%)"},{"Title":"EURO/JPY","PriceTime":"2014-04-25 20:49:00 UTC","Price":"141.28-141.32","Diff":"-0.19(-0.1%)"},{"Title":"EURO/USD","PriceTime":"2014-04-25 20:48:00 UTC","Price":"1.3833-1.3836","Diff":"+0.0002(0.0%)"},{"Title":"USD/CNY","PriceTime":"2014-04-25 20:48:00 UTC","Price":"6.2536-6.2546","Diff":"+0.0063(0.1%)"},{"Title":"DJIA","PriceTime":"2014-04-25 07:29:00 UTC","Price":"16,361.46","Diff":"-140.19(-0.8%)"},{"Title":"Nasdaq","PriceTime":"2014-04-25 07:00:00 UTC","Price":"4,075.561","Diff":"-72.777(-1.7%)"},{"Title":"FTSE100","PriceTime":"2014-04-25 07:35:00 UTC","Price":"6,685.69","Diff":"-17.31(-0.2%)"}]}
And console says like below:
http: multiple response.WriteHeader calls
My code is like below.
Retrieve from cache:
c := appengine.NewContext(req)
memcacheKey := "markets"
results := []Result{}
cachedItem, getCacheErr := memcache.JSON.Get(c, memcacheKey,&map[string]interface{}{"results": results})
if getCacheErr != nil && getCacheErr != memcache.ErrCacheMiss {
c.Infof("get cache error")
}
if getCacheErr == nil {
c.Infof("cached data found")
c.Infof("cached data: %v",cachedItem.Value)
r.JSON(200, cachedItem.Object)
} else {
c.Infof("cached data not found")
}
Set to memcache:
client := urlfetch.Client(c)
resp, err := client.Get("http://www.nikkei.com/markets/kaigai/worldidx.aspx")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
indexes := Indexes()
doc, _ := goquery.NewDocumentFromResponse(resp)
doc.Find("div.mk-world_market div table tr").Each(func(_ int, s *goquery.Selection) {
title := s.Find("th").Text()
title = strings.Trim(strings.Replace(title,"※","",-1)," ")
if val,ok := indexes[title]; ok {
price := s.Find("th").Next().Text()
diff := s.Find("td:nth-child(3)").Text()
pricetime := s.Find("td:nth-child(4)").Text()
t := time.Now()
pricetime = StringToTime(pricetime,t)
result := Result{val,pricetime,price,diff}
results = append(results,result)
}
})
item := &memcache.Item{
Key:memcacheKey,
Object: &map[string]interface{}{"results": results},
}
setErr := memcache.JSON.Set(c, item)
if setErr != nil {
c.Infof("set error: %v",setErr)
}
What is wrong with my code?
self-resolution:
What I want to do is below.
m.Get("/api/Markets", func(w http.ResponseWriter,r render.Render,req *http.Request) {
c := appengine.NewContext(req)
memcache_key := "markets"
var item_list []Result
results := []Result{}
_, get_cache_err := memcache.JSON.Get(c,memcache_key,&item_list)
if get_cache_err != nil && get_cache_err != memcache.ErrCacheMiss {
c.Infof("get cache error")
}
if get_cache_err == nil {
c.Infof("cached data found")
c.Infof("cached data: %v",item_list)
results = item_list
} else {
c.Infof("cached data not found")
client := urlfetch.Client(c)
resp, err := client.Get("http://www.nikkei.com/markets/kaigai/worldidx.aspx")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
indexes := Indexes()
doc, _ := goquery.NewDocumentFromResponse(resp)
doc.Find("div.mk-world_market div table tr").Each(func(_ int, s *goquery.Selection) {
title := s.Find("th").Text()
title = strings.Trim(strings.Replace(title,"※","",-1)," ")
if val,ok := indexes[title]; ok {
price := s.Find("th").Next().Text()
diff := s.Find("td:nth-child(3)").Text()
pricetime := s.Find("td:nth-child(4)").Text()
t := time.Now()
pricetime = StringToTime(pricetime,t)
result := Result{val,pricetime,price,diff}
results = append(results,result)
}
})
item_list = results
item := &memcache.Item{
Key:memcache_key,
Object: &item_list,
}
setErr := memcache.JSON.Set(c, item)
if setErr != nil {
c.Infof("set error: %v",setErr)
}
}
r.JSON(200, map[string]interface{}{"results": item_list})
})