Friday, March 15, 2013

SqlDependency Copy & Paste Tutorial

Into

While building out push notifications for Twit-A-Dex I wanted to build out a server application that took users twitter information and pushed notifications to their phones. At first I was considering polling the SQL database at a regular interval, however after reading all this stuff about push notifications in both Twitter and GCM I wanted to see if i could use a similar solution locally to set up my services for a new user when a new user account was committed to the database.

Problem

After a quick search I found SqlDependency was probably my solution however I could not find a good way of using it without getting a single notifications, or a million instant notifications etc..

Tutorial

So this tutorial is meant to be a cut and paste. 1. Create a new database called ‘NotificationDependency’ and create this table:

  
CREATE TABLE [dbo].[Note](
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Name] [nchar](10) NOT NULL,
 CONSTRAINT [PK_Note] PRIMARY KEY CLUSTERED 
(
 [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

2. Create a sql user the application will be able to connect with and give it Read/Write/Create Stored Procs/Execute Stores Procs

3. Run this statement to enable the service broker:
  
ALTER DATABASE NotificationDependency SET ENABLE_BROKER with rollback immediate;
4. Create a new Console Application and create an app config with the connection string NotificationDependency 5. Create the following class:
  
    public class DatabaseChangeListener
    {
        private readonly string connectionString;
        private readonly SqlConnection connection;

        public delegate void NewMessage();
        public event NewMessage OnChange;

        public DatabaseChangeListener(string connectionString)
        {
            this.connectionString = connectionString;
            SqlDependency.Stop(connectionString);
            SqlDependency.Start(connectionString);
            connection = new SqlConnection(connectionString);
        }

        public DataTable Start(string changeQuery)
        {
            
            var cmd = new SqlCommand(changeQuery, connection) { Notification = null };
            var dependency = new SqlDependency(cmd);
            dependency.OnChange += NotifyOnChange;
            if (connection.State == ConnectionState.Closed)
                connection.Open();
            var dt = new DataTable();
            dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection));

            return dt;
        }

        void NotifyOnChange(object sender, SqlNotificationEventArgs e)
        {
            var dependency = sender as SqlDependency;
            if (dependency != null) dependency.OnChange -= NotifyOnChange;
            if (OnChange != null) { OnChange(); }
        }

        ~DatabaseChangeListener()
        {
            SqlDependency.Stop(connectionString);
        }
    }

7. Create a new EF model or have some way to query the database.

8. In the Main Add the following Code:
  
            var db = new NotificationDependencyEntities();
            var maxId = db.Notes.Max(x => x.Id);

            var con = System.Configuration.ConfigurationManager.ConnectionStrings["NotificationDependency"];
            var changeListener = new DatabaseChangeListener(con.ConnectionString);
            changeListener.OnChange += () =>
                                           {
                                               Console.WriteLine("There was a change");
                                               maxId = db.Notes.Max(x => x.Id);
                                               changeListener.Start(@"SELECT [Id] ,[Name] FROM [dbo].[Note] WHERE [Id] > " + maxId);
                                           };
            changeListener.Start(@"SELECT [Id] ,[Name] FROM [dbo].[Note] WHERE [Id] > " + maxId);

            Console.ReadLine();

9. Finally you can run the application, then run the following insert in some other application like SSMS to see the result
  
INSERT INTO [dbo].[Note]
           ([Name])
     VALUES
           ('hello')


Conclusion

Sql Dependency is not so bad, and in this example I used a query that allows me to prevent the whole table from being downloaded each time an event happens.
The OnChange event only gets called once each time so you will need to make sure the Start method is called again.

Monday, February 11, 2013

Artificial Intelligence Exploratory Tester

Chris Lucian speaking at Agile Open Northwest 2013 on a Machine Learning Artificial Intelligence Exploratory Tester

Aversions to Learning

Chris Lucian Speaking at Agile Open Northwest on Aversions to Learning

Tuesday, January 8, 2013

Unity3d Beginner On Screen Diagnostic Script

Small Script to display diagnostic information on screen

This script is really useful when developing a plugin for Unity that must be deployed onto a device without the editor. For Example and Android or iOS device.

Script:


using UnityEngine;

public class DiagText : MonoBehaviour
{
    public static string DisplayText = "";

    void Start()
    {
    }

    void Update()
    {
    }

    void OnGUI()
    {
        GUI.Label(new Rect(0, 0, 500, 500), DisplayText);
    }
}

How to Use:

Just enter any string value that will show you the information from any script because display text is declared as static. Also there must be a GameObject added to the scene with the script attached. 
 DiagText.DisplayText = "Some Text";

IntelliJ Unity3d Plugin Not Finding Classes

Unity3d Plugin Cannot Find UnityPlayerActivity with IntelliJ


End of the world sale

After JetBrains had their end of the world sale at 75% off I ended up with 3 much needed tools for my game and app development. First I bought ReSharper my favorite re-factoring tool. Then I bought AppCode for iPhone development, and Finally I bought IntelliJ IDEA to replace Eclipse.

I never used IntelliJ and my only hope was that it would have better re-factoring than Eclipse. I am happy with its re-factoring capabilities however when I built the project I found that everything that worked in Eclipse failed to work in Unity3d 3.5. 

When making a plugin I got the following error:

01-08 19:13:35.678: E/AndroidRuntime(9029): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.game/com.example.unityplugin.ExampleUnityActivity}: java.lang.ClassNotFoundException: com.example.unityplugin.ExampleUnityActivity in loader dalvik.system.PathClassLoader[/mnt/asec/com.example.game-1/pkg.apk]

Amazingly my searches returned little to know information...

Search Terms

"Unity3d IntelliJ"
"Unity3d IntelliJ Problem"
"Unity3d IntelliJ ClassNotFound"
etc..

eventually I searched: "Unity cannot find my java class"

Which tipped me off to the last of many answers.

Solution

The reason the classes were not showing up in the Jar Artifact was the JDK I was using. I Installed IntelliJ with JDK 1.7, however eclipse uses its own compiler, which must ad-hear more to what ever 1.6 does. So I was able to fix the problem by going to File/ProjectSettings in IntelliJ (Ctrl+Alt+Shift+S) and set your SDK to 1.6. This should make the classes show up!