If you use the Backup and Restore functionality (^DBACK and ^DBREST) all identity values will be preserved.
If you are importing the data in another way you need to look at the $SYSTEM.SQL SetIdentityInsert ClassMethod, this allows you to insert id values when importing data through SQL statements for example.
This is a side effect of how Caché finds the string, the code performs a read() on the stream to load a chunk into memory before searching for the string.
The read() is setting the AtEnd property, but if the string being searched for appears more than once in the chunk in memory, only the first occurrence will be found.
So in order to read all occurrences of the string, you should not sue the AtEnd to determine when to Stop.
The following code will count the number of times "Invalid password" appears in the file.
kill set stream=##class(%Stream.FileCharacter).%New() do stream.LinkToFile("d:\csp.log") set x="" set i=0 set j=0 write stream.Rewind() while(i'=-1){set i=stream.FindAt(-1,"Invalid password",.x) set j=j+1} write i write j
Obviously you can alter the code in the while loop to perform any other action when it finds the string.
Many thanks for following up on this, it is appreciated.
I've had time to do some further investigations on both the file itself and the FileCharacter object.
It's still not working as I would expect. I might raise a WRC ticket on this, I can then attach the file so people can work with the same data that I am working with.
The last 14 lines of the file are at the bottom of this message, you can see that Invalid Password appears twice.
The file is 2491024949 characters, counting back from the end, this puts the last Invalid Password at about character 2491024505
So if I run the following: k s stream=##class(%Stream.FileCharacter).%New() d stream.LinkToFile("d:\csp.log") w stream.Rewind() w stream.MoveTo(2491024500) set x="" w stream.FindAt(-1,"Invalid password",.x,1)
it returns 45 which is about correct? But it also sets stream.AtEnd to 1?
I can also do:
k s stream=##class(%Stream.FileCharacter).%New() d stream.LinkToFile("d:\csp.log") w stream.Rewind() w stream.MoveTo(2491024500) for i=1:1:5{w stream.ReadLine(),!} k
Which gives the following output, where you can clearly see the Invalid password string.
Well spotted on the "pass by reference", my mistake.
I updated my code and it looks a lot better, but is still not quite giving me what I expect.
The final output now shows:
USER>w stream.SizeGet() 2491024949 USER>while(stream.AtEnd=0){set i=stream.FindAt(-1,"Invalid password",.x)+i set j=j+1} USER>w stream.AtEnd 1 USER>w i 2442920326 USER>w j 3205553 USER>
So it's still not quite going to the end of the file (see SizeGet() and i output above) and it is missing the last 5 "Invalid password" entries (GLOGG is showing 3205558 instances).
Let me know if there is any further information that I can send on that might help.
Configure your 2017 instance with the same Namespaces/Database as the 2007 instance
On the 2007 instance - take a Full Backup
On the 2017 instance - Restore the Backup
If you need/want to configure the 2017 databases to different locations than the 2007 instance, that's fine, just specify the new locations when using ^DBREST to perform the Restore.
go to post
Ankur,
If you use the Backup and Restore functionality (^DBACK and ^DBREST) all identity values will be preserved.
If you are importing the data in another way you need to look at the $SYSTEM.SQL SetIdentityInsert ClassMethod, this allows you to insert id values when importing data through SQL statements for example.
Oliver.
go to post
This is a side effect of how Caché finds the string, the code performs a read() on the stream to load a chunk into memory before searching for the string.
The read() is setting the AtEnd property, but if the string being searched for appears more than once in the chunk in memory, only the first occurrence will be found.
So in order to read all occurrences of the string, you should not sue the AtEnd to determine when to Stop.
The following code will count the number of times "Invalid password" appears in the file.
kill
set stream=##class(%Stream.FileCharacter).%New()
do stream.LinkToFile("d:\csp.log")
set x=""
set i=0
set j=0
write stream.Rewind()
while(i'=-1){set i=stream.FindAt(-1,"Invalid password",.x) set j=j+1}
write i
write j
Obviously you can alter the code in the while loop to perform any other action when it finds the string.
go to post
See additional comment on your previous answer.
go to post
Robert,
Many thanks for following up on this, it is appreciated.
I've had time to do some further investigations on both the file itself and the FileCharacter object.
It's still not working as I would expect. I might raise a WRC ticket on this, I can then attach the file so people can work
with the same data that I am working with.
The last 14 lines of the file are at the bottom of this message, you can see that Invalid Password appears twice.
The file is 2491024949 characters, counting back from the end, this puts the last Invalid Password
at about character 2491024505
So if I run the following:
k
s stream=##class(%Stream.FileCharacter).%New()
d stream.LinkToFile("d:\csp.log")
w stream.Rewind()
w stream.MoveTo(2491024500)
set x=""
w stream.FindAt(-1,"Invalid password",.x,1)
it returns 45 which is about correct?
But it also sets stream.AtEnd to 1?
I can also do:
k
s stream=##class(%Stream.FileCharacter).%New()
d stream.LinkToFile("d:\csp.log")
w stream.Rewind()
w stream.MoveTo(2491024500)
for i=1:1:5{w stream.ReadLine(),!}
k
Which gives the following output, where you can clearly see the Invalid password string.
USER>k
USER>s stream=##class(%Stream.FileCharacter).%New()
USER>d stream.LinkToFile("d:\csp.log")
USER>w stream.Rewind()
1
USER>w stream.MoveTo(2491024500)
1
USER>for i=1:1:5{w stream.ReadLine(),!}
tent-type: text/html
Connection: closed
Invalid password
>>> Time: Tue Feb 13 11:41:34 2018; RT Build: 1501.1472 (win64/iis/mod:srv=8.5); Log-Level: 0; Gateway-PID: 26860; Gateway-TID: 19448; Connection-No: ; Request-ID: 2e5d; Session-ID: yynkyKY1Kr; Remote-Addr: 10.104.16.17; Page: POST /csp/ccms_stat/ws.DatabaseQuery.cls
USER>k
LAST 14 LINES OF FILE.
Invalid password
>>> Time: Tue Feb 13 11:41:34 2018; RT Build: 1501.1472 (win64/iis/mod:srv=8.5); Log-Level: 0; Gateway-PID: 26860; Gateway-TID: 24956; Connection-No: ; Request-ID: 2e5c; Session-ID: mVINyKM1KZ; Remote-Addr: 10.104.15.55; Page: POST /csp/ccms_stat/ws.DatabaseQuery.cls
Diagnostic
Failed to connect - Reason: 0 (Connection successfully made but server not responding) (No Retry)
>>> Time: Tue Feb 13 11:41:34 2018; RT Build: 1501.1472 (win64/iis/mod:srv=8.5); Log-Level: 0; Gateway-PID: 26860; Gateway-TID: 19448; Connection-No: 11; Server: CCDSInstance; Cache-PID: 0; Request-ID: 2e5d
cspTestConnection(mode=0, context=11, response_size=104): Response
CacheSP: chd=1;
HTTP/1.0 403 Forbidden
Content-type: text/html
Connection: closed
Invalid password
>>> Time: Tue Feb 13 11:41:34 2018; RT Build: 1501.1472 (win64/iis/mod:srv=8.5); Log-Level: 0; Gateway-PID: 26860; Gateway-TID: 19448; Connection-No: ; Request-ID: 2e5d; Session-ID: yynkyKY1Kr; Remote-Addr: 10.104.16.17; Page: POST /csp/ccms_stat/ws.DatabaseQuery.cls
Diagnostic
Failed to connect - Reason: 0 (Connection successfully made but server not responding) (No Retry)
go to post
Robert,
Well spotted on the "pass by reference", my mistake.
I updated my code and it looks a lot better, but is still not quite giving me what I expect.
The final output now shows:
USER>w stream.SizeGet()
2491024949
USER>while(stream.AtEnd=0){set i=stream.FindAt(-1,"Invalid password",.x)+i set j=j+1}
USER>w stream.AtEnd
1
USER>w i
2442920326
USER>w j
3205553
USER>
So it's still not quite going to the end of the file (see SizeGet() and i output above) and it is missing the last 5 "Invalid password" entries (GLOGG is showing 3205558 instances).
Let me know if there is any further information that I can send on that might help.
I'll keep investigating from my side as well.
Oliver.
go to post
If I was doing this I would do the following:
If you need/want to configure the 2017 databases to different locations than the 2007 instance, that's fine, just specify the new locations when using ^DBREST to perform the Restore.