Repoint legacy app to new oracle home hierarchy - oracle

I am working on 2 virtual machines to test legacy application functionality on new platforms, with an OS & DB upgrade. The application that is being tested on the new client (Win7Prox64) was written in VB6. (It's pretty old!) When the application launches, it opens a form that allows users to login.
The old DB it connected to was 11G on Server2003SP2 32bit box and the app ran on a 32bit XP client. (The new VM for the new server for test is 2008R2x64).
The legacy app has the the following declared: ("frmLogin.frm")
(The app checks the registry for the location of tnsnames by assigning the correct directory paths to these Const's)
Private Const MODULE_NAME = "frmLogin"
Private Const REG_APP_KEY = "Software\ORACLE\HOME"
Private Const REG_APP_PATH = "Oracle_Home"
Private Const REG_ALL_HOMES = "Software\Oracle\ALL_HOMES"
Private Const REG_LAST_HOME = "LAST_HOME"
Private Const REG_MYAPP_KEY = "Software\company\myapp"
Private Const MYAPP_APP_KEY = "Database Host Name"
I assume I have to change these constants to the new hierarchy found with 11GR2 to make it work correctly, how do I check and update these? I'm not sure it's as easy as just changing the directories above, but I could be wrong.
Any tips welcome.
EDIT: I notice 11GR2 on Win7 64 registry entries are alot different to XP 32bit with 11G. Both in layout and content. LAST_HOME for example doesn't seem to exist on Win7, any advice?
I hard coded a reference to the location of tnsnames.ora into the app, and I know that it runs (and seems to run well) on the new 64bit client, but I cannot hardcode it for each and every client machine it will reside on, so need to re-point the directories correctly.

You have to go through every registry key in HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_***, since there are possibly multiple installations on one system.
Go to HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE in the registry, then check every sub key if it starts with KEY_. (pick the first if you don't care, if you do, go through every one)
In those keys you will find:
The TNS_ADMIN, the deviating location where the tnsnames.ora will be saved;
The ORACLE_HOME where you need to append network\admin where the tnsnames.ora will generally be found.

Related

Can I replace %USERPROFILE% and still get KNOWNFOLDERIDs from the registry?

We're developing an open source Python library that runs on Linux, MacOS, and Windows, but we don't have much experience or exposure to Windows in the developer team. The way we setup and run our test suite works fine under Linux and Mac, but is suboptimal on Windows.
Our tests set up a new directory in a temporary location, place a fake .gitconfig with relevant configurations inside it, and have the relevant HOME environment variables point to this location as the home directory in order to pick up the configurations during testing.
The code is shortened and can't be run, but hopefully illustrates the gist of what we do:
with make_tempfile(mkdir=True) as new_home:
pass
for v, val in get_home_envvars(new_home).items():
set_envvar(v, val)
if not os.path.exists(new_home):
os.makedirs(new_home)
with open(os.path.join(new_home, '.gitconfig'), 'w') as f:
f.write("""\
[user]
name = Tester
email = test#example.com
[more configs for testing]
exc = 1
""")
where get_home_envvars() makes sure that the $HOME env variable points to the new, temporary test home. On Windows since Python 3.8, os.path no longer queried the $HOME variable to determine a user's home, but USERPROFILE[1 ][2], so we've just overwritten this variable with the temporary test home:
def get_home_envvars(new_home):
environ = os.environ
out = {'HOME': new_home}
if on_windows:
# requires special handling, since it has a number of relevant variables
# and also Python changed its behavior and started to respect USERPROFILE only
# since python 3.8: https://bugs.python.org/issue36264
out['USERPROFILE'] = new_home
out['HOMEDRIVE'], out['HOMEPATH'] = splitdrive(new_home)
return {v: val for v, val in out.items() if v in os.environ}
However, we have now discovered that this breaks our test setup on Windows, with tests "bleeding" their caches, cookie data bases etc. into the places where we perform our unit tests, and with this creating files and directories that break our test assumptions.
I have a very limited understanding on what happens exactly, but my current hypothesis is this: Our library determines the appropriate locations for caches, logs, cookies, etc upon start by using appdirs [3], which does so by querying the "special folder" IDs/ CSIDLs that Windows has [4]. This information is determined in the Windows registry - which is found based on the USERPROFILE. To quote one specific reply in the Python bug tracker to this change:
This is unfortunate. Modifying USERPROFILE is highly unusual. USERPROFILE is the location of the user's "NTUSER.DAT" registry hive and local application data ("AppData\Local"), including "UsrClass.dat" (the "Software\Classes" registry hive). It's also the default location for a user's known shell folders and home directory. Modifying USERPROFILE shouldn't cause problems with any of this, but I'm not completely at ease with it.
After our testsuite setup is done, we start new processes that run our tests. The new processes only get to see the new USERPROFILE, and appdirs returns the paths it finds by sending them through normpath, which unfortunately interprets the empty string returned by _get_win_folder for a CSIDL that now can't be found anymore as a relative path (.):
# snippet from appdirs source code
path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA"))
And based on this, we end up configuring the current working directory of each test as the place for user data, user caches, etc.
My question is: How could I fix this? Based on my probably incomplete understanding, I currently think it ultimately boils down to the question how to treat or mock the USERPROFILE. I need to have it pointed to a registry in order to derive the "special folder" IDs (be it with appdirs or more modern replacements of it) - but I also need it to point to the fake home with test-specific Git configurations. I believe the latter requires overwriting USERPROFILE in Python3.8 and newer. I'm wondering if there is a way to copy or mock the registry and place it under the new home? Set relevant CSIDLs/KNOWNFOLDERIDs in some other way? Hardcode other temporary locations to use as cache directories etc? Or maybe there is a more clever way to run a test suite under Windows that does not require a fake home?
I would be very grateful to learn from more experienced Windows developers what to do, or also what not to do. Many thanks in advance.
[1] https://docs.python.org/3.11/library/os.path.html#os.path.expanduser
[2] https://bugs.python.org/issue36264
[3] https://github.com/ActiveState/appdirs
[4] https://learn.microsoft.com/en-us/windows/win32/shell/csidl

Where can I find the database Room.DataBaseBuilder(...).build() creates?

I'm quite new to android and I am currently working on a app which should utilize a Room database. Following the documentation a room database can be created through the following lines:
myDatabase = Room.databaseBuilder(appContext, MyDatabase.class, "MyDB")
.build();
Now where did room create the database file?
It can't be found in my project folder.
The documentation doesn't mention anything about it and -generally speaking- barely gives any information about how this thing works.
Where is the database?
Does DatabaseBuilder.build() manage, to open the existing database created from previous app launches?
The list of questions is long.
Any information about the .build() thing aswell as further information about Room (misconceptions etc.) are very appreciated, for the documentation doesn't really make things clear for me.
Thank you!
Now where did room create the database file?
The database (a file) will be placed at the default location on the actual device which is data/data/<the_package_name>/database/MyDB.
In your case, as you have coded :-
myDatabase = Room.databaseBuilder(appContext, MyDatabase.class, "MyDB")
.build();
Then the database files will be: -
data/data/<your_package_name>/databases/MyDB
data/data/<your_package_name>/databases/MyDB-wal
data/data/<your_package_name>/databases/MyDB-shm
It can't be found in my project folder.
The database file is not part of the project, it is a file that is created and maintained on the actual device on which the App has been installed.
However, you can use Database Inspector (now App Inspection) on Android Studio to view the database e.g. :-
You can also view the files, if whatever device you test on allows access, by using Device File Explorer. e.g.
Does DatabaseBuilder.build() manage, to open the existing database created from previous app launches?
Yes, if the file exists then it is opened otherwise the file is created. If you uninstall the App this effectively delete's the file. The whole idea of a database is that it persists.
The build() undertakes various tasks, primarily seeing if the underlying file exists and then opening the file. In doing so it
extracts the version number that is stored in the file and compares the number against the number coded within the App (via the #Database).
If the version number from the App is greater then an attempt is tried to find a Migration (recently AutoMigration's have been added to Room).
compares the expected schema (according to the entities defined as part of the #Database), against what is found in the file.
A mismatch will result in the app crashing, so fixes would have to be made.
Note references to file is a simplification, by default Room uses a loggin mode called WAL (Write-Ahead Logging). In WAL mode there will be an additional 2 files that the SQLite routines maintain (you don't need to do anything):-
the database file name suffixed with -wal is the primary wal file into which changes are written (they are applied to the main database automatically).
the database file name suffixed with -shm (this is a WAL file for the WAL file).

What is the easiest way to migrate file permissions (SMB/AD)

I botched a DC's AD / DNS pretty bad over the course of several years (of learning experiences) to the point where I could no longer join or leave the domain with clients. I have a NAS that used to plug into AD via SMB and that is how all the users (my family) used to access their files.
I have recreated my infrastructure configuration from scratch using Windows 2016 using best practices this time around. Is there any way to easily migrate those permissions to users in a new domain/forest (that are equivalent in value to the old one)?
Could I possibly recreate the SIDs / GUIDs of the new users to match the old? I'm assuming no because they have a Windows installation-unique generated string in there.
Could I possibly do this from the NAS side without having to go through each individual's files to change ownership?
Thank you.
One tool you can use to translate permissions from original SIDs to new SIDs is Microsoft's SubInACL
SubInACL will need from you information which old SID corresponds to which new SID or username and execute translation for all data on NAS server. For example like this
subinacl /subdirectories "Z:\*.*" /replace=S-1-5-1-2-3-4-5=NEWDOMAIN\newuser
How long it will take for translation to complete depends on number of files and folders, if it's tens of thousands expect hours.
There are also other tools like SetACL or PowerShell cmdlets Get-Acl/Set-Acl
You cannot recreate objects with original SIDs and GUIDs unless you're doing restore of the AD infrastructure or cloning/migrating original identities into new ones with original SID in sidHistory attribute.
So if you're already running domain controller with NAS in newly created forest and old one suffered from issues you wanted fixed that option would be probably much more painful and it's easier to go for SID translation.

Server name dissapears from rdoConnection.Connect string

I'm working with an old Visual Basic 6 application that connects to an Oracle11g server using Remote Data Objects (RDO) 2. Here is my code:
Dim rdoCon As New rdoConnection
rdoCon.Connect = "DRIVER={Microsoft ODBC for Oracle};SERVER=os11atst.world;"
Debug.Print rdoCon.Connect '1
'Prompt the user to enter credentials and connect to the server:
rdoCon.EstablishConnection rdDriverComplete, False
Debug.Print rdoCon.Connect '2
The first Debug.Print gives me this (as expected):
DRIVER={Microsoft ODBC for Oracle};SERVER=os11atst.world;
However, the second one gives me this:
DRIVER={Microsoft ODBC for Oracle};UID=username;PWD=password;
The SERVER parameter is missing, even though the connection works fine. This is a problem for me, because I need to know what server the connection is to. I can not simply use the information from the first string, because the user is (and should be) able to change the server in the prompt that asks for username and password.
This problem arose from nowhere, possibly in connection to an upgrade from Windows XP to 7. Previously the program did not exhibit this behaviour, or so I am told by older colleagues. Not 100% sure that is correct, though.
How can I prevent the dissaperance of the server name? Can I get the name of the server in any other way than looking at the connection string?
I am not interested in solutions that include upgrading to something newer than RDO. For external reasons I am stuck with it.
rdoCon.EstablishConnection will override whatever you had previously set.
It sounds like the problem is in the DSN that is installed on this new machine. Compare it to the DSN that was installed on the previous machine. It had a configuration that you are missing on this new machine.
I have developed a not so pretty workaround to solve this. I have a table called SETTINGS containing columns NAME and VALUE. For every database I have simply added the setting servername together with the appropriate value. All I need to do to find out what server I am connected to is then to query the DB:
SELECT value FROM settings WHERE name = 'servername'
This is of course quite an ugly hack, so any better solutions would be welcome.

what is the GROOVY connection string to an JDBC database with SSPI = True? I am running this from SoapUI Free version

I'm trying to do this:
import groovy.sql.Sql
def sql = Sql.newInstance(
url:'jdbc:sqlserver://localhost\\myDB',
user:'server\user', //this I don't think I need because of SSPI
password:'password',
driver:'com.microsoft.sqlserver.jdbc.SQLServerDriver',
SSPI: 'true'
)
The problem I'm having is that this connection is just timing out. I can ping the machine. I can also connect to the database with Managment Studio logged into my SSPI user (or whatever you call it, I start the Management Studio with a different user)
So I've tried that with my SoapUI as well, started the program as a different user, but I still time out when I initiate the connection. So something is very wrong with my connection string and any help would be appreciated.
P.S. Yes, I don't know what's up with the \ backslashes after the URL to the server, I guess it indicates that it's at the root. If I don't use them I get a message that I'm on the incorrect version.
And then we found the answer..... First of all I had the wrong JDBC driver installed. You need to head over to microsoft to get the real deal:
https://www.microsoft.com/en-us/download/details.aspx?id=11774
Then you need to unpack this one, place the 4 or 4.1 version in your bin directory of SoapUI. (You are apparently supposed to use Lib/Ext, but that doesn't work for me)
Then, since we are trying to use SSPI or Windows Authentication, to connect to the SQL server, you need to place the sqljdbc_auth.dll from the driver/enu/auth folder. This is used in one of your path's or in SoapUI Lib folder. Remember to use the 32 bit dll for 32 bit SoapUI!!! I did not since my system is 64.....
After this, I used this string, but now you have the setup correct, so it should work fine as long as you remember to start SoapUI up using the correct windows user. (Shif-right click - start as different user - use the same user you have started the SQL server with)
Again, I wasn't completely aware of this from the start (yes, total newbie here) and it failed.
Finally, when you have done all this, this is the string that works - and probably a lot of derivatives since the failing part here were the driver and dll.
def sql =Sql.newInstance("jdbc:sqlserver://localhost;Database=myDB;integratedSecurity=true","com.microsoft.sqlserver.jdbc.SQLServerDriver")

Resources