Kevin Sheffield

Dummy for Programming

Ruby + Windows + Sql Server

| Comments

I love it when I spend a few hours getting something working only to not write down the steps I did to solve the magic riddle that Ruby on Windows seems to be. Fast forward a few months, a wiped computer and enough beers to make sure I can barely remember last night’s dinner and what we have here is a failure to communicate… with myself.

This post is a reminder to myself on how to set up a fresh windows install to be able to query Sql Server via Ruby.

The way this is going to be done is via 2 gems… dbi and dbd-odbc.

*replace C:\Ruby187 below with whatever the install path selected during the installation

  1. Install Ruby via the 1-click installer. I have only used 1.8.7 for this.
  2. Update rubygems (gem update –system).
  3. Install dbi gem (gem install dbi).
  4. Install dbd-odbc gem (gem install dbd-odbc).
  5. Copy C:\Ruby187\lib\ruby\gems\1.8\gems\dbd-odbc-0.2.5\lib\dbd to C:\Ruby187\lib\ruby\gems\1.8\gems\dbi-0.4.5\lib. (this will result in the following file path being valid… C:\Ruby187\lib\ruby\gems\1.8\gems\dbi-0.4.5\lib\dbd\odbc.rb).
  6. Go to http://www.ch-werner.de/rubyodbc/ and download i386-msvcrt-ruby-odbc.zip.
    Put the 2 .so files in the …/ruby/1.8/i386-mingw32 directory.

That is it.

Now the following code will work like magic….

1
2
3
4
5
6
7
8
 require 'rubygems'
require 'dbi'
oConn = DBI.connect('DBI:ODBC:sqldsn')
sth = oConn.execute(commandstring)
rows = sth.fetch_all
col_names = sth.column_names
sth.finish
DBI::Utils::TableFormatter.ascii(col_names, rows) 

Monotouch : Sectioned UITableViews

| Comments

I was playing around some more with UITableViews and wanted to get them working the way they do in Contacts with the vertical bar on the right side of the screen providing navigation to a certain section in the list (in the case of Contacts and this example, first letter of the word).

It is amazingly simple.  Basically you only have to override and implement a few more functions of UITableDataSource… mainly SectionIndexTitles, NumberOfSections, TitleForHeader (and TitleForFooter if you wanted a footer), SectionFor, and RowsInSection.  So maybe that wasn’t just a few but they are really simple to implement.

SectionIndexTitles : This is just a string[] with all the titles you want to show on the right side scrollbar area.

NumberOfSections : Simply just a count of the number of sections.

TitleForHeader : This will set the header title for each section.  There is an int parameter and for me just returns the string at the specified index.

RowsInSection : This returns a count of the items in the current section. Using .FindAll() in my code.

SectionFor : Not exactly sure what this is for as of yet.  Seeing it used in some Obj-c code it just returned the atIndex param.  Will look into this more or would love a commentor to explain it.

To spice this demo up I even hooked up a UISearchBar and filter the list on each keystroke.  You can notice both the items and sections being filtered out.

Here is what it looks like when it first loads up first load

And this it the program after searching for something searched

Here is the code. All of the delegates are in the Main.cs file.

Here is the MainWindow.designer.cs

namespace SectionedUITableViewSample {
// Base type probably should be MonoTouch.Foundation.NSObject or subclass
[MonoTouch.Foundation.Register("AppDelegate")]
public partial class AppDelegate {
[MonoTouch.Foundation.Connect("window")]
private MonoTouch.UIKit.UIWindow window {
get {
return ((MonoTouch.UIKit.UIWindow)(this.GetNativeField("window")));
}
set {
this.SetNativeField("window", value);
}
}

[MonoTouch.Foundation.Connect("tvc")]
private MonoTouch.UIKit.UITableViewController tvc {
get {
return ((MonoTouch.UIKit.UITableViewController)(this.GetNativeField("tvc")));
}
set {
this.SetNativeField("tvc", value);
}
}

[MonoTouch.Foundation.Connect("tv")]
private MonoTouch.UIKit.UITableView tv {
get {
return ((MonoTouch.UIKit.UITableView)(this.GetNativeField("tv")));
}
set {
this.SetNativeField("tv", value);
}
}

[MonoTouch.Foundation.Connect("searchBar")]
private MonoTouch.UIKit.UISearchBar searchBar {
get {
return ((MonoTouch.UIKit.UISearchBar)(this.GetNativeField("searchBar")));
}
set {
this.SetNativeField("searchBar", value);
}
}
}
}

And here is the Main.cs


namespace SectionedUITableViewSample
{
    public class Application
    {
        static void Main (string[] args)
        {
            UIApplication.Main (args);
        }
    }

    // The name AppDelegate is referenced in the MainWindow.xib file.
    public partial class AppDelegate : UIApplicationDelegate
    {
        // This method is invoked when the application has loaded its UI and its ready to run
        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        {
            // If you have defined a view, add it here:
            // window.AddSubview (navigationController.View);
            
            TableViewDataSource tvdc = new TableViewDataSource();
            this.tvc.TableView.DataSource = tvdc;
            
            this.searchBar.Delegate = new SearchDelegate(tvc, tvdc);
            
            window.AddSubview(this.tvc.View);
            
            window.MakeKeyAndVisible ();

            return true;
        }

        // This method is required in iPhoneOS 3.0
        public override void OnActivated (UIApplication application)
        {
        }
    }
    public class SearchDelegate : UISearchBarDelegate
    {
        public UITableViewController tvc;
        public TableViewDataSource tvdc;
        public SearchDelegate(UITableViewController tvc, TableViewDataSource tvdc) : base ()
        {
            this.tvc = tvc;
            this.tvdc = tvdc;
        }
        
        public override void TextChanged (UISearchBar searchBar, string searchText)
        {
            tvdc.Search(searchText);
            tvc.TableView.DataSource = tvdc;
            tvc.TableView.ReloadData();
        }
    }
    
    public class TableViewDataSource : UITableViewDataSource
    {   
        private List sectionList;
        private List filteredSectionList = new List();
        private List dictionaryItems = new List();
        public List filteredDictionaryItems = new List();
        public TableViewDataSource ()
        {
            Initialize();
        }
        
        public void Initialize()
        {
            sectionList = new List {"A","B","C","D","E","F","G","H","J","I","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z" };
            filteredSectionList = new List {"A","B","C","D","E","F","G","H","J","I","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z" };
        
            var random = new System.Random();
            
            for(int i = 0; i < 2000; i++)
            {
                dictionaryItems.Add(sectionList[random.Next(26)] + sectionList[random.Next(26)] + sectionList[random.Next(26)] + sectionList[random.Next(26)]);
            }
            dictionaryItems.Sort();
            foreach(var item in dictionaryItems)
            {
                filteredDictionaryItems.Add(item);  
            }
        }
        
        public void Search(string searchText)
        {
            filteredDictionaryItems.Clear();
            filteredSectionList.Clear();
            foreach(string item in dictionaryItems)
            {
                if(item.ToLower().Contains(searchText.ToLower()))
                {
                    filteredDictionaryItems.Add(item);
                    if(filteredSectionList.Find(x => x == item[0].ToString()) == null)
                    {
                        filteredSectionList.Add(item[0].ToString());    
                    }
                }
            }
            filteredSectionList.Sort();
        }
        
        public override string[] SectionIndexTitles (UITableView tableView)
        {
            return filteredSectionList.ToArray();
        }
        
        public override int NumberOfSections (UITableView tableView)
        {
            return filteredSectionList.Count;
        }
        
        public override string TitleForHeader (UITableView tableView, int section)
        {
            return filteredSectionList[section];
        }
        
        public override int RowsInSection (MonoTouch.UIKit.UITableView tableview, int section)
        {
            return filteredDictionaryItems.FindAll(x => x.StartsWith(filteredSectionList[section])).Count;
        }
        
        public override UITableViewCell GetCell (MonoTouch.UIKit.UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
        {
            var termsinsection = filteredDictionaryItems.FindAll(x => x.StartsWith(filteredSectionList[indexPath.Section]));
            
            string dictionaryItem = termsinsection[indexPath.Row];
            string cellID = "CellID";
    
            UITableViewCell cell = tableView.DequeueReusableCell(cellID);
            if(cell == null)
            {
                cell = new UITableViewCell(UITableViewCellStyle.Default, cellID);
                cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
            }
            cell.TextLabel.Text = dictionaryItem;
            return cell;
        }

        public override int SectionFor (UITableView tableView, string title, int atIndex)
        {
            return atIndex;
        }
    }
}

The code is up on Github

Monotouch Beta 3 Is Out

| Comments

I am stoked about downloading it when I get back from dinner. Going to play with the drawing API tonight!

CS193P via Monotouch Launching

| Comments

I just finished recording a walkthrough of assignment 1 and it is uploading to a few sites so I can compare them.  I have never really done any screencasts aside from a few simple “how to use this page I just made” videos for work using camtasia (and those sucked I am sure), so as I post these, let me know how I can improve not only the code but also my presentation skills.

Before I post any of the videos I did want to put down a disclaimer:

I am not associated with the CS193p course or Monotouch.  All code you see in the screencasts may not be best practice and as Monotouch is in beta, functionality may be different at the time of your viewing of this video.

I will try and update videos as I get feedback and as the project advances if need be.

Please provide any feedback you wish, but constructive feedback is what is going to most help shape these videos into something truly useful.

I hope you enjoy messing with Monotouch as much as I am.

Viddler vs YouTube vs Vimeo

| Comments

I am going to be recording Assignments 1 and 2 of CS193p only using Monotouch tomorrow. After I record assignment 1, I am going to see what service suits me best and run with it. If anyone has a suggestion for what works best with the idea that I will be mainly concerned with displaying screencasts, let me know here or via twitter

Kicking Ass With Monotouch

| Comments

A few days ago I was lucky to become a part of the Monotouch beta program and I must say that I cannot believe how cool it is so far.  I have seen a few screencasts from people making hello world (or really button press counter) apps and thought, “Hell, I was going through the Stanford Iphone class, why not do all the assignments using Monotouch?”  Last night I ran through Assignment 2B and I am going to attempt a screencast with my very best Ron Burgundy voice in the next few days.  I will tag any posts related to this endeavor with ‘monotouch’ so feel free to follow along.

If anyone has some suggestions for good screen recording software on OSX feel free to comment, I am new to the mac world and have only ever used Camtasia on windows.

Also expect a post soon giving a run down of my experience and what I hope any posts I make gains in terms of feedback. I will say though that I am by no means an expert and anything I code might not be best practice.  If you have a better/different way of doing anything please give me some feedback as my first motive in this is improving myself and any help I can give anyone else through this is just gravy on the potatoes.