Why does this operation break when turned into a function (AutoHotKey/AHK) - function

The following operation works correcting inside AHK. It replaces the word ted with the word tom inside an open word document.
Working Code
; Word Constants
vbTrue := -1
wdReplaceNone := 0
wdFindContinue := 1
return
#IfWinActive, ahk_exe WINWORD.EXE
^7::
try
oWord := ComObjActive("Word.Application")
catch
return
FindText := "ted"
ReplaceWith := "tom"
oFind := oWord.Selection.Find
oHyperlinks := oWord.ActiveDocument.Hyperlinks
oFind.ClearFormatting
oFind.Replacement.ClearFormatting
while oFind.Execute(FindText, vbTrue, false,,,,, wdFindContinue,,, wdReplaceNone)
oHyperlinks.Add(oWord.Selection.Range, "http://www.autohotkey.com",,, ReplaceWith)
return
However, when I turn this exact same code into a function it does not work. It does not work when written this way, and it also does not work even if the parameters are removed and the variables are put back into the script.
Broken Code (with parameters)
ReplaceAndLink(FindText, ReplaceWith)
{
; Word Constants
vbTrue := -1
wdReplaceNone := 0
wdFindContinue := 1
return
try
oWord := ComObjActive("Word.Application")
catch
return
oFind := oWord.Selection.Find
oHyperlinks := oWord.ActiveDocument.Hyperlinks
oFind.ClearFormatting
oFind.Replacement.ClearFormatting
while oFind.Execute(FindText, vbTrue, false,,,,, wdFindContinue,,, wdReplaceNone)
oHyperlinks.Add(oWord.Selection.Range, "http://www.autohotkey.com",,, ReplaceWith)
return
}
#IfWinActive, ahk_exe WINWORD.EXE
^7::
ReplaceAndLink("ted", "tom")
Broken Code (without parameters)
ReplaceAndLink(FindText, ReplaceWith)
{
; Word Constants
vbTrue := -1
wdReplaceNone := 0
wdFindContinue := 1
return
try
oWord := ComObjActive("Word.Application")
catch
return
FindText := "ted"
ReplaceWith := "tom"
oFind := oWord.Selection.Find
oHyperlinks := oWord.ActiveDocument.Hyperlinks
oFind.ClearFormatting
oFind.Replacement.ClearFormatting
while oFind.Execute(FindText, vbTrue, false,,,,, wdFindContinue,,, wdReplaceNone)
oHyperlinks.Add(oWord.Selection.Range, "http://www.autohotkey.com",,, ReplaceWith)
return
}
#IfWinActive, ahk_exe WINWORD.EXE
^7::
ReplaceAndLink()
Troubleshooting Notes:
Word is open during both operations
I am using the newest version of AHK
I have tried running the broken one on a clean restart
No special libraries or other AHK scripts are running
Also... I know that similar COM based AHK scripts can be placed into functions... see for example:
LinkCreator(FindText, ReplaceWith)
{
oWord := ComObjActive("Word.Application")
oWord.Selection.Find.ClearFormatting
oWord.Selection.Find.Replacement.ClearFormatting
oWord.Selection.Find.Execute(FindText, 0, 0, 0, 0, 0, 1, 1, 0, ReplaceWith, 2)
}
F2::
LinkCreator("store", "town")

You're calling return before the function can finish. This causes the script to stop processing that function and return to the caller.
ReplaceAndLink(FindText, ReplaceWith)
{
; Word Constants
vbTrue := -1
wdReplaceNone := 0
wdFindContinue := 1
return <---------- HERE
try
oWord := ComObjActive("Word.Application")
catch
return
Try removing that and it should execute as expected.
A simple troubleshooting tip for when something isn't executing is to place a Soundbeep or MsgBox somewhere in the code to see if you have some unreachable code and work backwards from there.

Related

How to test mysql insert method

I'm setting up testing in Go. I use go-sqlmock to test mysql connection. Now I try to test mysql insert logic. But the error occurs.
I want to know how to resolve this error.
server side: golang
db: mysql
web framework: gin
dao.go
func PostDao(db *sql.DB, article util.Article, uu string) {
ins, err := db.Prepare("INSERT INTO articles(uuid, title,content) VALUES(?,?,?)")
if err != nil {
log.Fatal(err)
}
ins.Exec(uu, article.TITLE, article.CONTENT)
}
dao_test.go
func TestPostArticleDao(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
mock.ExpectExec("^INSERT INTO articles*").
WithArgs("bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c", "test", "test").
WillReturnResult(sqlmock.NewResult(1, 1))
article := util.Article{
ID: 1,
TITLE: "test",
CONTENT: "test",
}
PostDao(db, article, "bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c")
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expections: %s", err)
}
}
I expect go test -v runs without error.
But the actual is not.
Here is the error.
=== RUN TestPostArticleDao
2019/08/31 00:08:11 call to Prepare statement with query 'INSERT INTO articles(uuid, title,content) VALUES(?,?,?)', was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
- matches sql: 'INSERT INTO articles(uuid, title,content) VALUES(?,?,?)'
- is with arguments:
0 - bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c
1 - test
2 - test
- should return Result having:
LastInsertId: 1
RowsAffected: 1
exit status 1
FAIL article/api/dao 0.022s
As #Flimzy suggested, it needs to set ExpectPrepare first.
So I changed dao_test.go in this way:
prep := mock.ExpectPrepare("^INSERT INTO articles*")
prep.ExpectExec().
WithArgs("bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c", "test", "test").
WillReturnResult(sqlmock.NewResult(1, 1))
In my case it worked without asterix:
mock.ExpectExec("INSERT INTO `mytable`").WithArgs(mockdbutils.AnyTime{}, mockdbutils.AnyTime{}, nil, 4455,false).WillReturnResult(sqlmock.NewResult(int64(4455), 1))
mock.ExpectCommit()

PLSQL parse json list: JSON Scanner exception

I'm parsing a json feed but when I loop the json_list I get the following error:
ORA-20100: JSON Scanner exception # line: 1 column: 33086 - string ending not found
Looking at the feed I'm unable to find anything out of the ordinary. It started to make me wonder if there's a character limitation.
my code is pretty simple..here are the relevant parts:
DECLARE
a_list json_list;
v_list clob;
obj_ json;
.....
BEGIN
....
req := utl_http.begin_request (v_url,'GET');
res := utl_http.get_response (req);
utl_http.read_text(res, v_list);
a_list := json_list(v_list);
for i in 1 .. a_list.count loop
obj_ := json(a_list.get(i));
val_source := obj_.get('source');
val_date := obj_.get('date');
el_source := val_source.get_string;
el_date := val_date.get_string;
end loop;
...
END;
Is there anything that I'm doing wrong? Or any hints out there?
I figured it out....
I read the data into a buffer string and basically worked on the data by chunks and then appended it to a clob.
dbms_lob.createtemporary(p_res_clob, false);
req := utl_http.begin_request (v_url,'GET');
res := utl_http.get_response (req);
begin
-- process the request and get the response:
loop
utl_http.read_text(res,l_buffer,32000);
dbms_lob.writeappend(p_res_clob,length(l_buffer), l_buffer);
end loop;
end;
a_list := json_list(v_list);
for i in 1 .. a_list.count loop
obj_ := json(a_list.get(i));
val_source := obj_.get('source');
val_date := obj_.get('date');
el_source := val_source.get_string;
el_date := val_date.get_string;
end loop;
...
END;
Hope this helps someone who gets stumped :)

JSON returned by TIdHTTP cannot be decoded

I have the following code:
var
MemoryStream1: TMemoryStream;
IdHTTP1: TIdHTTP;
Bytes1: TBytes;
s1: string;
begin
IdHTTP1 := TIdHTTP.Create(nil);
MemoryStream1 := TMemoryStream.Create;
IdHTTP1.Get('https://restcountries.eu/rest/v2/all', MemoryStream1);
MemoryStream1.Position := 0;
MemoryStream1.SaveToFile('C:\Temp\MemoryStream1.txt');
MemoryStream1.Position := 0;
SetLength(Bytes1, MemoryStream1.Size);
MemoryStream1.Read(Bytes1[0], MemoryStream1.Size);
s1 := TEncoding.UTF8.GetString(Bytes1);
It fails at the last line with the message "no mapping for the unicode character in the target multi-byte code page exists"
However, I can see the returned JSON clearly in HttpAnalyzer.
The file 'C:\Temp\MemoryStream1.txt' starts with the hex '1F8B0800000000000003DC9BED6F1BB7' when I am expecting something corresponding to { - a left brace - as the first character
when I try
s1 := TEncoding.Unicode.GetString(Bytes1);
String s1 contains "Chinese" characters.
I worked it out. Apparently, the gzip is not decompressed. One must do it oneself. Here goes:
var
IdHTTP1: TIdHTTP;
a1: AnsiString;
s1: string;
MemoryStream1, MemoryStream2: TMemoryStream;
begin
Screen.Cursor := crHourGlass;
IdHTTP1 := TIdHTTP.Create(nil);
MemoryStream1 := TMemoryStream.Create;
MemoryStream2 := TMemoryStream.Create;
IdHTTP1.Get('https://restcountries.eu/rest/v2/all', MemoryStream1);
MemoryStream1.Position := 0;
IdCompressorZLib1.DecompressGZipStream(MemoryStream1, MemoryStream2);
FreeAndNil(MemoryStream1);
MemoryStream2.Position := 0;
SetLength(a1, MemoryStream2.Size);
MemoryStream2.Read(a1[1], MemoryStream2.Size);
// AnsiString a1 now contains the decompressed data

Getting MySQL process output

I want to play with MySQL process and get what ever it write to console so I write this code in FreePascal:
I want to control MySQl and read & write whatever.
Process := TProcess.Create(nil);
with Process do
begin
Executable := 'C:\Program Files (x86)\MySQL\MySQL Server 5.5\bin\mysql.exe';
with Parameters do
begin
Options := [poUsePipes];
Add('-u');
Add('root');
Add('-p');
end;
Execute;
sleep(1000);
WriteLn(Process.Output.NumBytesAvailable); // will be 0 but it write "Enter password"
WriteLn(Process.Stderr.NumBytesAvailable); // will be 0 but it write "Enter password"
end;
TProcess is a component that control executing other programs,I even test Delphi codes but all result are the same.
But the problem is that this will freeze because there is no output but console window write :
Enter password:
How can I get this in my application and all others?
As I said I want to work with MySQL executable and read from and write in it, So I dont want to use its library or any other DB component.
EDIT:
Here is a Delphi version of my test from here with the same result :
function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of AnsiChar;
BytesRead: Cardinal;
WorkDir: string;
Handle: Boolean;
begin
Result := '';
with SA do begin
nLength := SizeOf(SA);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, #SA, 0);
try
with SI do
begin
FillChar(SI, SizeOf(SI), 0);
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
WorkDir := Work;
Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
nil, nil, True, 0, nil,
PChar(WorkDir), SI, PI);
CloseHandle(StdOutPipeWrite);
if Handle then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
Result := Result + Buffer;
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(PI.hProcess, INFINITE);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
CloseHandle(StdOutPipeRead);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
memo1.text:=GetDosOutput('"C:\Program Files (x86)\MySQL\MySQL Server 5.5\bin\mysql.exe" -u root -p');
end;
It will freeze in WasOK line .
Also I tested many other codes for this subject and neither worked.

Delphi JSON superobject saving multiple objects to file in alphabetical order

I'm using the JSON superobject library to save objects to a file. When my code worked, they were written with proper formatting.
procedure TDCell.Save(fileName: string);
var i,j : integer;
JsonObjCol1, JsonObjCol2, JsonObjCol3, JsonObjCol4: ISuperObject;
begin
JsonArray := SO();
JsonObjCol1 := SO();
JsonObjCol2 := SO();
JsonObjCol3 := SO();
JsonObjCol4 := SO();
for i := 0 to Table.ColCount - 1 do
begin
for j := 0 to Table.RowCount - 1 do
begin
if Table.Objects[i, j] is TEdit then
with Table.Objects[i, j] as TEdit do
case i of
0:JsonArray[Name] := SO(Table.Cells[i, j]);
1:JsonObjCol1[Name] := SO(Table.Cells[i, j]);
2:JsonObjCol2[Name] := SO(Table.Cells[i, j]);
3:JsonObjCol3[Name] := SO(Table.Cells[i, j]);
4:JsonObjCol4[Name] := SO(Table.Cells[i, j]);
end
else
if Table.Objects[i, j] is TLabel then
with Table.Objects[i, j] as TLabel do
case i of
0:JsonArray[Name] := SO(Caption);
1:JsonObjCol1[Name] := SO(Caption);
2:JsonObjCol2[Name] := SO(Caption);
3:JsonObjCol3[Name] := SO(Caption);
4:JsonObjCol4[Name] := SO(Caption);
end
end;
case i of
0:JsonObject['Col' + IntToStr(Table.ColCount - 1 - i)] := JsonArray;
1:JsonObject['Col' + IntToStr(Table.ColCount - 1 - i)] := JsonObjCol1;
2:JsonObject['Col' + IntToStr(Table.ColCount - 1 - i)] := JsonObjCol2;
3:JsonObject['Col' + IntToStr(Table.ColCount - 1 - i)] := JsonObjCol3;
4:JsonObject['Col' + IntToStr(Table.ColCount - 1 - i)] := JsonObjCol4;
end;
end;
JsonObject.SaveTo(fileName, true);
end;
JsonArray also has type ISuperObject
But it seems that there is some opposite order sorting feature running in this library. Not only objects but also key-value pairs in them are written in opposite alphabetical order.
{
"Col4": {
"Label03": "Hello03",
"Label01": "Hello01",
"Edit04": "Hello04",
"Edit02": "Hello02",
"Edit00": "Hello00"
},
"Col3": {
"Label13": "Hello13",
"Label11": "Hello11",
"Edit14": "Hello14",
"Edit12": "Hello12",
"Edit10": "Hello10"
},
"Col2": {
"Label23": "Hello23",
"Label21": "Hello21",
"Edit24": "Hello24",
"Edit22": "Hello22",
"Edit20": "Hello20"
},
"Col1": {
"Label33": "Hello33",
"Label31": "Hello31",
"Edit34": "Hello34",
"Edit32": "Hello32",
"Edit30": "Hello30"
},
"Col0": {
"Label43": "Hello43",
"Label41": "Hello41",
"Edit44": "Hello44",
"Edit42": "Hello42",
"Edit40": "Hello40"
}
}
What should I do to make superobject write the file in the proper order? I've tested that objects are added in the proper order in cycles. The file must look like this.
{
"Col0": {
"Edit00": "Hello00",
"Label01": "Hello01",
"Edit02": "Hello02",
"Label03": "Hello03",
"Edit04": "Hello04"
},
"Col1": {
"Edit10": "Hello10",
"Label11": "Hello11",
"Edit12": "Hello12",
"Label13": "Hello13",
"Edit14": "Hello14"
},
and so on
There is no proper order. The elements of a JSON object can be presented in any order, and the JSON standard makes it clear that the meaning of the file cannot depend on the order of the elements of a JSON object:
An object is an unordered set of name/value pairs.
If you require ordered data then you need to use a JSON array:
An array is an ordered collection of values.