Skip to main content

Posts

Showing posts from 2005

AppTrain: A Rails Form Generator

If you've been thinking about trying out Ruby On Rails , you just have to check out the AppTrain project on Ruby Forge. There is a step-by-step guide to form generation as well. AppTrain is currently an alpha release, but it still looks quite handy. If you want to install it, use the quick-start . The AppTrain Project seems very committed to making it easy to build rails apps. First, they created a Table Generator , and now they are working on a form generator. That's all some simpler administrative apps need!

SQLServer2000: Capture output of EXEC statements

About 2 years ago, I discovered that I could capture the results of an EXEC (@string_variable) statement. We had a server process that logged in as System Admin (SA), so it could perform a directory scan, bulk insert any files it found, and move those files to a "processed" subdirectory. This process can be used to run any DOS command, and inserts each line of text as a record into a table. We still use this trick to log program responses to a journal table. When reading the sample code, notice that we are using two single-quote characters back-to-back to cause a single quoted argument to be sent to the xp_cmdshell extended command (really a registered DLL accessible only to SA). Here's an example: DECLARE @s varchar(255); CREATE TABLE #cmdOutput(Line varchar(200)) ; SET @s='INSERT INTO #cmdOutput EXEC master.dbo.xp_cmdshell ''dir c:\temp\*.txt /b'''; EXEC (@s) ; SELECT * FROM #cmdOutput WHERE Line IS NOT NULL; DROP TABLE #cmdOutput; A word of c...

Use and Abuse of XML

This may be considered a rant by some, but here goes. XML is a data structure which is easily parsed by 3rd party applications. This does not mean that the data can be easily interpreted as information, that is the responsibility of the XML data designer. Depending on your audience, you may have to spell out units (pounds, kilograms, minutes, seconds, etc.). Also, XML IS NOT FAST. Do not use XML between internal components in your application if at all possible. Thank you for your attention.

How to flag spam on BlogSpot

I like Blogger.com, but it has a fair amount of blog-spam. I was searching on the keyword "blacksmith" today, and ran across a number of spammer pages, with javascript that removed the "Flag Content as Objectionable" button. If you are a programmer, you can easily flag these pages anyway, by viewing the HTML source, and searching for "flag". Look for var ID = 1234567; and surf to http://www.blogger.com/flag-blog.g?nav=1&toFlag= ID_GOES_HERE to help Blogger find these nasties. Once you've done it a few times, it doesn't take long at all.

How does Rails scaffolding select HTML input tags?

Recently, a reader saw my fix for SQL Server booleans, and asked me a followup question: why does Rails display a yes/no selection instead of a checkbox? The short answer is look in {RUBY_HOME} /lib/ruby/gems/1.8 /gems/actionpack-1.10.2 /lib/action_view/helpers, but your path may vary depending on whether you are using gem, "edge rails", etc. Anyway, look in the file "active_record_helper.rb" for a method called "all_input_tags", and notice that it calls "default_input_block" if you don't supply an input_block. Now notice that "default_input_block" creates a label and calls "input(record, column.name)" which in turn calls "InstanceTag#to_tag" which finally looks at the datatype and maps boolean to a select tag. Perhaps a wiser Rails explorer can provide us with the rationale for this, but I guess we could add a MixIn for InstanceTag that redefines the to_tag() method, or just do a dirty and unmaintainable hack l...

Data warehousing - finally!

I finally helped some friends set up a data cube. It mostly involved creating a specialized view that had one numeric field (in our case - a count), a date field, and a number of categorical "dimension" fields. We used Seagate Info , now from Business Objects to actually work with the data. So no, I didn't write my own data cube explorer. The client couldn't afford that, and I didn't really want to do it. What did I do? I took a conglomerated (non-normalized) survey table and built a set of relational tables for surveys, questions, answers, results (the actual answers), etc. Then I wrote an "importer" to smartly read the "scanned surveys" table and populate my relational data set with any "new" surveys, based on an "IsProcessed" flag, and whether that ScannedSurvey_ID existed in the relational table collection. This allows their OCR process to add records at any time, and a daily process runs under SQL Agent to import new s...

Planning for failure - embedded systems

Here's a short story about total system design, and planning for failure. Last friday night, I was filling up my truck with gas, and I did the "pay at the pump" thing, using my credit card. After I filled my tank, the pump's display helpfully asked "Do you want a receipt? Yes / No". I usually say no, but I wanted to remember the price per gallon, so I said "Yes." Within 2 seconds, it said "Printer Not Available." Why did they offer to print a receipt if the printer is not working? A more helpful system would have simply stated "See attendant if you want a receipt," knowing that the printer was down. To make this system more effective, they would have to: a) know when the attendant had replaced the paper roll b) remember that last time they tried to print, it didn't work. c) reset the printer state when the attendant did a test print, or closed the access panel. Perhaps cost was the prohibitive factor.

SSPI connection for Rails SQLServer connection adapter

Recently, I added support for SSPI (a connection that uses your local user account to authenticate you on the database server without supplying another password). To use an SSPI connection, do not supply a username or a password. sqlserver_adapter.rb: username = config[:username] ? config[:username].to_s : '' ... # Use integrated security if config[:integrated] or (username == '' and password == '') conn = DBI.connect("DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};Integrated Security=SSPI;") else conn = DBI.connect("DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};") end

Rails connection_adapter SqlServer fix for boolean fields

I tried to use Ruby on Rails with Microsoft SQLServer recently, and I kept having problems with my "bit" fields. Looking on the web, the Rails repository claims to have fixed this, so I downloaded the new adapter from svn. It didn't work for me, so I started hacking. I really need to send this as a diff to the ActiveRecord maintainers, with test code to prove that it works. By the way, I am using ADO mode ... maybe their original code works for ODBC mode. I suspect that tests should be run for both modes. Anyway, enough chatter, here is the fix! In file sqlserver_adapter.rb, add the #cast_to_bit and modify #quote as following: def cast_to_bit(value) case value when nil then nil when '1' then 1 when '0' then 0 when 1 then 1 when 0 then 0 when 'true' then 1 when 'false' then 0 else # puts "Invalid Boolean #{value}" 0 end end def qu...

.Net Strings - LastIndexOf in c#

Today, I tried to use string methods IndexOf and LastIndexOf to parse a directory entry string that I received across an SSH channel. I guess I should have read the method description closer, but I expected LastIndexOf to find the last space character in a string. The signature I wanted to use is: public int LastIndexOf(char, int, int); Reports the index position of the last occurrence of a specified String within this instance. The search starts at a specified character position and examines a specified number of character positions. It turns out that LastIndex will decrement it's starting index for "count" characters. Here was my incorrect code: private void method () { string dirEntry = "-rwxr-xr-x 1 abcde fghij 44458 Feb 22 1987 prt01.txt"; int m, n; // I thought this would scan from 32 to 44 and find the last space char m = dirEntry.LastIndexOf(' ', 32, 12); // it returned 32 // code that does what I w...

Upgrading Ubuntu from Hoary to Breezy

For those of you still running Ubuntu Hoary, I have upgraded 2 computers to Breezy now, and I like the improvements just fine. There is a more up-to-date software selection, including PHP5, Ruby, Rails, Mono 1.8.x and MonoDevelop. If you want to pull from Packages.DotDeb.Org , you can even try out MySQL 5.x. I haven't done that yet, but I have found some instructions on the Ubuntu Forums that I plan to use as a guideline. When you upgrade, you may have to stop your email server . I had to on both computers. If you want an easier installation, there are Breezy Colony CDs that you can download with BitTorrent. I haven't done that yet, but if I install on another PC before Breezy goes live, I will try it. Best of luck to my fellow ubuntu-ites.

Ruby On Rails (Resources)

Here are some links that I consider essential to working with Ruby on Rails. Ruby On Rails RubyForge.org Ruby Code Snippets What is Ruby on Rails I have Rails running on Win32 and Ubuntu Linux (Breezy) so far, with MS SqlServer and MySQL as back-end databases. I just wish Ruby and Debian developers could come to a conclusion about package management between apt-get and gem . The debian team wants to package up each gem so they can control the location of C interface libraries. Of course, we sacrifice timely access to updated gems, but that is no different than any other package. Personally, I have un-installed the apt-get managed versions of all ruby packages including rails and rake, and installed them through gem install . Someday I need to If you want to try out the bleeding edge of Ruby on Rails, download and install the Subversion source control system, then pull down the rails source into your application's vendor directory. Speaking of Edge Rails , I noticed that it s...

Using a spreadsheet to simplify data entry

I've used a spreadsheet for data entry on a number of occasions. It is quite handy! All it requires is a string concatenate function, and a bit of cleverness. This is great for "quick-n-dirty" data entry, or for searches. The comma separated list is usually used for "SELECT * FROM TBL WHERE X IN ( ## excel text goes here ## )". # to build a comma separated list =CONCATENATE("'", A2, "',") # insert new records =CONCATENATE("INSERT INTO #t (Nbr, Code, Descr) VALUES ('", A4, "', '", B4, "', '", C4,"');")

SQLServer 2000: Concatenate fields in a table

Here's a handy way to create a comma-separated list from a small lookup table. I put the most interesting statement in bold. -- BEGIN CODE -- silence the "rows affected" message SET NOCOUNT ON ; -- create a temp table CREATE TABLE #temp(id int identity(1,1) not null, state varchar(50) not null); -- insert a few states for our example INSERT INTO #temp(state) values('AK'); INSERT INTO #temp(state) values('CA'); INSERT INTO #temp(state) values('HI'); INSERT INTO #temp(state) values('OK'); INSERT INTO #temp(state) values('TX'); -- declare a variable large enough to hold the needed results DECLARE @strg varchar(1000) ; -- collect fields (ordered any way you want) -- you can also do "top 10" SELECT @strg = COALESCE(@strg + ',', '') + State FROM #temp t ORDER BY State DESC PRINT 'My States: ' + @strg ; DROP TABLE #temp ; -- END CODE

Capture output from SqlServer 2000

Here is a method of capturing the output of a command executed by the system shell. It is typically called from the SA account, and used to automate maintenance tasks. I do not recommend that you allow other users to send statements to a command shell. --- BEGIN CODE DECLARE @s varchar(255); -- our command SET @s = 'DIR C:\TEMP\*.EXE' ; -- the temporary table CREATE TABLE #tCmdOutput( output varchar(1024) NULL ) ; -- capturing output from the command INSERT INTO #tCmdOutput( output ) EXEC Master..XP_CmdShell @s ; -- delete blank lines DELETE FROM #tCmdOutput WHERE output is null ; -- show output as a result set SELECT * FROM #tCmdOutput ; -- clean up our session DROP TABLE #tCmdOutput ; --- END CODE

Introduction

Hi! I am a computer programmer, working for the last few years with C# and Vb on .Net 1.x and Windows. At prior jobs, I have written Java, FoxPro for Windows, MFC, C, Visual Basic and Fortran. I have more experience with SQLServer 7 and 2000 than with any other database, writing huge stored procedures for invoicing, etc. Recently, I have started looking at Ruby and Rails, and I intend to comment on my experiences as they occur. I am starting a blog so I can "give some back" to the various communities that I am learning from. I will mostly write about Ruby, Ruby on Rails, MySQL 4x and 5.x, Ubuntu Linux, Mono.net, and more, but I am always studying on some new topic, so who knows!. Since this is my first post, it will probably change over time. I am always studying on a new hobby or a new programming topic! Update I've decided to split my blog posts, keeping this one for programming topics only. Check out Bees In Oklahoma or Forging Fun (my blacksmithing blog) if you...