Tuesday, June 1, 2010

JavaScript: functions as objects vs. functions as functions


I ran into this interesting behavior today. I was passing a function to a list of functions to execute later, and I kept getting an error in firebug that said when it came to execute it that it "is not a function", but proceeded to completely successfully execute it as one anyway, doing exactly what I wanted it to. I wanted to get rid of the error message, since it was behaving properly.


Come to find out, it was listed as an object instead of a function. In short, the difference is that if you declare a function like this: function() { ... }, it will be returned as a function. If you declare it like this: new function() { ... }, it will be returned as an object. I just needed to take out the word "new" I had used.


I created the following simple HTML page to demonstrate this behavior. Feel free to try it out for yourself and tinker around with it:

<html>
<head>
<script type="text/javascript">
//setup
var tests = new Array();
tests[0] = new function() { return 'A is the best!'; };
tests[1] = function() { return 'B is better!'; };

var message = 'tests:';
for (var i = 0; i < tests.length; i++)
{
message += '\ntest[' + i + ']: ' + tests[i];
}
alert(message +'\n\nNext, we\'ll try to execute these as functions...');
</script>
</head>
<body>
<div id="divResults"></div>
<br />
<div id="divStatus">Testing...</div>
</body>
<script type="text/javascript">
//run the tests
var resultsDiv = document.getElementById('divResults');
for (var i = 0; i < tests.length; i++)
{
resultsDiv.innerHTML += 'test[' + i + ']\'s result: ';
try { resultsDiv.innerHTML += tests[i](); }
catch(ex) {resultsDiv.innerHTML += '<span style="color:red;">Test failed: ' + ex.message + '</span>'; }
resultsDiv.innerHTML += '<br />';
}

//we're done
document.getElementById('divStatus').innerHTML = 'The test is done. Reload this page to run the test again.';
</script>
</html>


I have confirmed this behavior in Firefox 3.6.3, IE 7.0, Chrome 5.0, Safari 4.0.5, and Opera 10.53.

Monday, February 8, 2010

Resolved: "uninitialized constant DBI::DBD::ODBC" in Ruby for Windows

Running:
  • Windows 2003 Server SP2
  • Ruby 1.8.6 patchlevel 383, i386-mingw32 (from RubyInstaller)
  • dbd-odbc 0.2.4
  • dbi 0.4.3
Problem:
I created a Ruby class that can run arbitrary SQL queries on remote databases of various kinds. It was working fine for a while, but then something changed so that whenever I would try to use it to execute some SQL, I'd get the following error:

DBI::InterfaceError (Unable to load driver 'ODBC' (underlying error: uninitialized constant DBI::DBD::ODBC)):
dbi (0.4.3) lib/dbi.rb:300:in `load_driver'
C:/Ruby/lib/ruby/1.8/monitor.rb:242:in `synchronize'
dbi (0.4.3) lib/dbi.rb:242:in `load_driver'
dbi (0.4.3) lib/dbi.rb:160:in `_get_full_driver'
dbi (0.4.3) lib/dbi.rb:145:in `connect'
...

Resolution:
Make sure you have the dbd-odbc and dbi gems installed correctly.
For me, a couple of associated files were missing from C:\Ruby\lib\ruby\1.8\i386-mingw32: odbc.so and odbc_utr8.so. I had these files in my working Dev installation, so I just copied them from Dev to Prod, and it fixed the problem.

Commentary:
This comes from DBI trying to do a require dbd/odbc and not finding that file. When I googled around about the error, mostly people said to make sure you had the dbd-odbc gem installed, which I already did. I tried reinstalling the gem, as well as the dbi gem. This had no effect. The problem was happening on Prod, but I had the same thing set up on Dev, which was working. So, I checked to see what paths require uses like so:

C:\...>irb
irb(main):001:0> $LOAD_PATH
=> ["C:/Ruby/lib/ruby/site_ruby/1.8", "C:/Ruby/lib/ruby/site_ruby/1.8/i386-msvcr
t", "C:/Ruby/lib/ruby/site_ruby", "C:/Ruby/lib/ruby/1.8", "C:/Ruby/lib/ruby/1.8/
i386-mingw32", "."]

I checked through those directories to see what .rb files looked like ODBC-related things that were in Dev but not in Prod. That's how I found those two files. After I copied them to Prod, I tested it in IRB like so:

irb(main):004:0> require 'odbc'
=> true

After that, everything worked fine again. I hope this anecdote can help you! Good luck!

Friday, January 22, 2010

Thursday, January 14, 2010

How to restore an Oracle database from its original files

Background:
I recently had to bring an Oracle database online from its original files an old laptop hard drive. It had some data on it that I needed to get off, and as usual, Oracle is anything but straightforward. This post describes how I ended up doing it.
To start with, I had to connect the old hard drive to the machine. I did this with a USB-SATA2.5" external adapter. You can find hard drive multi-adapters like these on newegg or any other online hardware store for around $20 - $30.

Running:
- Windows XP SP3
- Oracle 10g

Solution Steps:
1) Locate your current Oracle database files. The default location for this is C:\oracle\product\10.2.0\oradata. Each folder in that directory contains the data files for the database by the same name.

2) I'll call the database you're trying to restore "OldDatabase". If the path for OldDatabase folder was different from your current Oracle data folders, this might not work (but of course the drive letter will be different if you're using an old disk drive via USB). If it doesn't work, see if you can install Oracle into a directory on the new machine that has the same path as the old one had.

3) Make sure you don't have any databases in your current Oracle installation that have the same name as OldDatabase. If they match and you continue anyways, things will get very screwed up. If you do have a match, see if you can migrate the matching new one to another new database with a different name. You might want to back up that db's files first.

4) Now, go ahead and create a new database with all the default settings and the same name as OldDatabase. You can do this via the Database Configuration Assistant that should have been included with your Oracle installation. I found mine under Start > All Programs > Oracle - OraDb10g_home1 > Configuration and Migration Tools.

5) Go into your Administration Assistant for Windows (in the same start menu folder as the Database Config Assist.) and find your newly created database, right click it, and choose Stop Service.

6) The data files for the new database you just created are now in your current oradata folder. Copy the contents of your old OldDatabase folder into the new one by the same name, replacing all files (you might want to back up your new folder first).

7) Back in the Admin. Assist., right-click your new database and choose Start Service. With any luck, you'll be able to connect to it in a few moments, and it will look just like your old database!

Hope this helps!

Wednesday, December 30, 2009

Resolved: "failed to build gem native extension" on Windows

Running:
- Windows XP SP3
- Ruby 1.8.6 (patchlevel 383, i386-minw32)

Problem:
When trying to do "gem install" on certain gems, I got a message "failed to build gem native extension" and the installation would fail. Some common gems that this happens to include ruby-debug, ruby-debug-ide, hpricot, sqlite3-ruby, and ruby-oci8.

Resolution:
Install the Ruby Development Kit from RubyForge. It's currently only available as a .7z file, so you'll need 7Zip to open it. Follow the instructions in the included INSTALL.txt file, but make sure when you copy the bin folder to your Ruby installation that you copy just the files inside it. Don't overwrite your Ruby installation's bin folder. That would be very bad.

Notes:
So what is a native extension and why is trying to install this?
Your Ruby interpreter (the ruby.exe program) is written C (or Java if it's jruby). Certain gems need to actually add C libraries to your Ruby installation in order to function properly, not just ruby-language files. They're usually downloaded as source (not binaries) and compiled on your machine to match your system's architecture. The problem is when, for instance, your machine doesn't have a C compiler available or not the same one as the gem is expecting (you may see something about "MSC version unmatch" if the version is different). The Ruby Dev Kit comes with a C compiler (gcc) that runs on Windows and is (probably) compatible with the gems. This resolved my issue.

The fact that you have to download the Dev Kit for building native extensions is apparently a recent change (Nov. '09), and it probably only applies to Windows Ruby installations. This change is currently not well documented, which is why I'm posting my findings.

This can also manifest itself in NetBeans IDE if you opt to install the FastDebugger and get similar error messages about native extensions failing to build.

Related Links:

Monday, November 30, 2009

Resolved: SQL Server Agent job notifications fail with "failed to notify '(operator name)'"

Running:
- Windows Server 2003 (5.2, build 3790)
- SQL Server 2005 (9.00.4053.00)

Symptoms:
- A job in SQL Server Agent is set to have an email notification sent to an operator when it fails, but the notifications don't send.
- Running Management > Database Mail > Send Test E-Mail does work, however.
- In the job history, each failed attempt is followed by "NOTE: Failed to notify '(operator name)' via email.".
- In the SQL Agent error log, there is a message saying, "Unable to start mail session... profile name is not valid..."

Solution:
- Go to SQL Server Agent > Properties > Alert System.
- If "Enable mail profile" is unchecked, check it and restart the SQL Server Agent.
- If is checked and still doesn't work, UNcheck it, restart the SQL Server Agent, then go back in and check it again, and then restart SSA again (this fixed my issue).

Commentary:
I found a lot of posts about this issue. Most revolved around the fact that by default the SQL Server Agent comes with the mail profile disabled. But it took me a few hours to resolve this, so it sounded like a good one to post here for others.

There is also a
Microsoft HotFix for certain related problems, but if you've been keeping your system up-to-date, you probably already have installed it in a cumulative update.

You may also want to check out this:
http://msdn.microsoft.com/en-us/library/ms175984.aspx

Thursday, November 5, 2009

SQL dyanmic queries run in separate connections

In SQL Server 2005, it appears that all dynamic queries run in separate connections from that of the query which generated them. This makes a big difference if you are using connection-specific temp tables (e.g., #MyTempTable).

Here's a few examples in SQL Management Studio to demonstrate what's going on.

Query:

--in a dynamic query, create a local temp table and select from it
PRINT 'Example A:'
EXEC('CREATE TABLE #ConnectionTempTable ( [Foo] INT, [Bar] BIT, [Junk] NVARCHAR(100) ) SELECT * FROM #ConnectionTempTable')
PRINT '------'

--in a dynamic query, create a global temp table; then in the static query, drop it
PRINT 'Example B:'
EXEC('CREATE TABLE ##GlobalTempTable ( [Foo] INT, [Bar] BIT, [Junk] NVARCHAR(100) )')
DROP TABLE ##GlobalTempTable
PRINT '------'

--in a dynamic query, drop the local temp table from Example A (FAILS!)
PRINT 'Example C:'
EXEC('DROP TABLE #ConnectionTempTable')
PRINT '------'

--in a dynamic query, recreate the temp table from Example A (FAILS!)
PRINT 'Example D:'
EXEC('CREATE TABLE #ConnectionTempTable ( [Foo] INT, [Bar] BIT, [Junk] NVARCHAR(100) )')
SELECT * FROM #ConnectionTempTable


Results:

Example A:

(0 row(s) affected)
------
Example B:
------
Example C:
Msg 3701, Level 11, State 5, Line 1
Cannot drop the table '#ConnectionTempTable', because it does not exist or you do not have permission.
------
Example D:
Msg 208, Level 16, State 0, Line 20
Invalid object name '#ConnectionTempTable'.

Thursday, October 8, 2009

Resolved: iPhone OS 3.1 download error 3259: "network timed out"

I haven't seen any help about this online so far, but I resolved the issue, so I'm posting my findings.

I have:
- iPod Touch 16GB
- iTunes 9.0.1.8
- Windows XP SP3
- ESET Antivirus 3.0.672.0

Problem:
After paying the $5 to upgrade from iPhone OS 2.1.1 to 3.1.1, the software download in iTunes stopped after completing and eventually displayed an error message that the "network timed out". On the downloads page, it showed error code 3259.

Resolution:
My antivirus software (ESET) was stealing the file from iTunes after the download completed, scanning it, and not returning it in a timely manner, since the file was rather large. I temporarily disabled the antivirus software, restarted the download, and then everything worked fine. (Don't forget to reenable your antivirus when you're done!)

I hope this can help save you a headache!

Thursday, September 10, 2009

Beware of Courier font in Firefox

I noticed today that in Firefox (3.5.2), the Courier font does not size well at all. The smallest it gets is about 12px.

If you want a nice fixed-width font that does work well in Firefox, use Courier New instead.

Tuesday, September 8, 2009

NoMethodError, undefined method `call' for MyController:Class

If you're getting this error:
NoMethodError in MyController#my_action
undefined method `call' for ClientScriptsController:Class

...then you might have forgotten to make your controller inherit (extend) the ApplicationController class, like I did. The big clue is that the undefined method is in the class, not the instance.

Controllers should be set up like this:

class MyController < ApplicationController
def my_action
#do something...
end
end