A while back I decided it was about time for me to get some real database management software. I do a lot with SQLite databases, and we also use Oracle at work. I wanted a database administration software that could do everything for me. I find it really annoying to have one program for Oracle, and one for SQLite.
After some research I happened upon an extremely comprehensive comparison of different database applications. Unfortunately this research happened over a year before writing this post so I don’t have the URL anymore. But after looking at things I eventually decided to try out Navicat Premium Essentials. It does everything I need in a database software at only $20. It handles SQL Server, PostgreSQL, MySQL, Oracle, MariaDB and SQLite, so I never have to switch around between applications to get to my different databases.
Unfortunately though, I made the mistake of assuming that buying from the Mac App Store was the best route. The Mac App Store does some wonderful things like updating my applications and giving me free updates to applications. If a developer wants to charge for an update to an application, they actually have to publish it to the Mac App Store as a new application, not just a new version. This sometimes helps out when companies have weird upgrade costs.
When you use Navicat for your Oracle database and you have a TNSNames.ora driving your connections then you have to make sure Navicat knows where your TNSNames is. This is really easy to do in the non-app store version. In the version of Navicat you download from Navicat.com, you simply have to open up the preferences of the app and go the the “Environment Variables” tab and setup your TNS_ADMIN variable.
They had to pull this tab out to make it into the App Store, so they provide a little wiki article to help out us fellows who made the mistake of purchasing from the App Store. For those who want the watered down version, they basically tell you that you have to open the terminal, export the environment variables and then launch Navicat.
Fortunately, I have since discovered a better solution.
Here’s a few ways to setup environment variables in OS X:
Inside your bashrc (bash_profile)
Since OS X is Unix based then we can just set up everything inside of our bashrc. Well, sort of – OS X doesn’t really have a bashrc it has a bash_profile. For those who are unfamiliar with bashrc, it’s a bash file that runs every time you login to a bash shell. Whenever you launch terminal.app, it will log you into the bash shell. I don’t know the reason Apple decided to do this, but in OS X, the file is names bash_profile instead of bashrc, but as far as I have seen, they function identically.
Someone may have noticed a key part to the bash_profile, it executes every time you log into a bash shell. Because of this, it does NOT apply to GUI applications.
Your bash_profile is where you should stick anything that you need in console applications, but not GUI’s.
To edit your bash_profile just open up a terminal and execute the following
1 2 |
touch ~/.bash_profile open ~/.bash_profile |
The first line will create the file if it doesn’t exist, the second will open it in your OS X text editor.
Inside the file you can just use straight bash. Here’s a little snippet from my bash_profile
1 2 3 |
export GRADLE_HOME=~/sd/android-sdk/gradle export ANDROID_HOME=~/sd/android-sdk export PATH=$GRADLE_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH |
Inside your environments.plist
This one popped up in OS X Lion, Mountain Lion and then just as quickly disappeared in Mavericks. This is rather unfortunate as it was pretty clever.
If your still in Lion/Mountain Lion, the file is ~/.MacOSX/environment.plist it’s just a plist, if you don’t know how to edit it yourself, use Xcode.
This method applies the environment variables to all GUI applications. This should apply to the Terminal application too, but I can’t be positive as I haven’t done the research.
Inside your launchd.conf
This one is a little odd because it applies the environment variables to all GUI and bash instances. It also applies regardless of the logged in user. Usually fine for the work computer but it makes you think twice before using it on your family computer. Global variables can always be a little scary.
When you make changes to your launchd, you’ll have to either reboot your machine or use the launchctl command in the terminal.
1 2 |
sudo touch /etc/launchd.conf sudo vim /etc/launchd.conf |
And then you can add variables with launchctl syntax:
1 2 |
setenv TNS_ADMIN /Applications/instantclient_11_2/network/admin setenv DYLD_LIBRARY_PATH /Applications/instantclient_11_2 |
This is the option I took for Navicat. I had some issues with the built in Oracle driver not working so I set my DYLD_LIBRARY_PATH variable to my own Oracle instant client, and TNS_ADMIN is the folder with my TNSNames.ora.
Update: As of Yosemite, launchd.conf doesn’t work anymore. You can still use launchctl commands in the prompt, but that’s kind of annoying to do every time you reboot. It also only affects the user that is logged in instead of all users. Thanks to a bunch of people that have already solved this problem, here are the two ways I’ve found to be most practical.
AppleScript
Write an apple script that has a bunch of lines like this
1 |
do shell script "launchctl setenv <variable name> <value>" |
for example
1 2 |
do shell script "launchctl setenv TNS_ADMIN /Applications/instantclient_11_2/network/admin" do shell script "launchctl setenv DYLD_LIBRARY_PATH /Applications/instantclient_11_2" |
Put the apple script somewhere and add it to your login items.
As a pro, this method is simple, easy to understand, and it works. As a con, this method only works for the user that is logged in, and depending on the order your login items run in, it may not affect other login items.
For the most part, I think the cons are minor annoyances at worst. I really like the idea of having a single script that is in an easy to remember/easy to find location. Every time i need to set up launchd.conf stuff, I always have to look at this blog post.
launchd.limit.plist
Note: This method did not work for me.
The basis of this method is essentially to just turn launchd back on. By creating a LaunchDaemon that runs early enough, you can re-enable launchd. The daemon basically just runs launchctl limit core unlimited. Keep in mind that all LaunchDaemons run as root no matter what.
To create the LaunchDaemon create the following file (as root) at /Library/LaunchDaemons/com.apple.launchd.limit.plist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>eicar</string> <key>ProgramArguments</key> <array> <string>/bin/launchctl</string> <string>limit</string> <string>core</string> <string>unlimited</string> </array> <key>RunAtLoad</key> <true/> <key>ServiceIPC</key> <false/> </dict> </plist> |
And then reboot. This should make launchd.conf work again.
The pro for this method is that it theoretically makes the variable affect ever user, and once you set it up everything works the way it used to. The con is that it’s confusing.
Either way, pick your poison and drink up.
You can get more information on environment variables from here, but in my experience this is enough knowledge to get by.
For anyone wondering, I have been very pleased with Navicat. Even with issues getting started, I don’t regret the purchase. I do however recommend buying from their website.