Latest Publications

DBObject rev .03

Alright, now I have a working .By

It actually simplifies things a lot, to the point I’m starting to double think making everything static.

As you can see, you can simply call something like:

    DBUser chris = (DBUser)DBObject.By("firstname", "chris", typeof(DBUser), Utility.connMy);
    DBUser bob = (DBUser)DBObject.By("id", "1327", typeof(DBUser), Utility.connMy);

And get back a valid user.

This isn’t prefect, for example, what if there are two people named Chris? this would only return an object for the first record returned. Which leads into my next step, returning a list of DBObjects.

    ///
    /// This is the baseclass for DB Object created by Chris Richards
    ///
    [Serializable]
    public class DBObject
    {
        //Holds all the properties in the object
        protected Hashtable _properties = new Hashtable();

        protected DBObject() { }

        ///
        /// Get the Object By a single property
        ///
        ///
The Property you want to get the Object By        ///
Value of the Property        ///
Type of the object to get (Must inherent from DBOBject)        ///
Connection String to use        ///
        static protected DBObject By(string property, object value, Type who_type, string connection)
        {
            DBObject obj = null;    //Either it will be set to a valid object, or it will remain null

            //Find the Column Name for the property requested
            string column_name = DBObject.GetColumn(property, who_type);

            if (column_name != string.Empty)
            {
                //Append the WHERE clause
                string query = DBObject.SelectQuery(who_type) + " WHERE " + column_name + "=?value";

                using (MySqlConnection conn = new MySqlConnection(connection))
                {
                    MySqlCommand cmd = new MySqlCommand(query, conn);
                    cmd.Parameters.AddWithValue("?value", value);

                    try
                    {
                        conn.Open();
                        MySqlDataReader reader = cmd.ExecuteReader();

                        if (reader.Read())
                        {
                            obj = (DBObject)DBObject.FromReader(reader, who_type);
                        }

                        conn.Close();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("nnERROR:n" + ex.Message);
                    }
                }

            }

            //Return what we have
            return obj;
        }

        ///
        /// Gets the Column name of a Property
        ///
        ///
Name of the Property        ///
Type of the object to get (Must inherent from DBOBject)        ///
        static protected string GetColumn(string property, Type who_type)
        {
            foreach (PropertyInfo who_properity in who_type.GetProperties())
            {
                //Find the matching property
                if (who_properity.Name.ToLower() == property.ToLower())
                {
                    foreach (object attribute in who_properity.GetCustomAttributes(false))
                    {
                        //Get the column
                        if (attribute is DBColumn)
                        {
                            return ((DBColumn)attribute).Column;
                        }
                    }
                }
            }

            //Couldn't find it
            return string.Empty;
        }

        ///
        /// Gets the SELECT ... FROM query for this object
        ///
        ///
Type of the object to get (Must inherent from DBOBject)        ///
        static protected string SelectQuery(Type who_type)
        {
            //Generate the Select Query
            string _select = "SELECT";

            //Now Set all the select columns
            foreach (PropertyInfo properity in who_type.GetProperties())
            {
                foreach (object attribute in properity.GetCustomAttributes(false))
                {
                    if (attribute is DBColumn)
                    {
                        _select += " " + ((DBColumn)attribute).Column + ",";
                    }
                }
            }

            //Remove the last Comma
            _select = _select.Substring(0, _select.Length - 1);

            //Get the Table Name for this Object
            foreach (object attr in who_type.GetCustomAttributes(false))
            {
                if (attr is DBTable)
                {
                    //Add the Table to our List
                    _select += " FROM " + ((DBTable)attr).Table;
                }
            }
            //Now Return it
            return _select;
        }

        ///
        /// This will populate the object from the reader.
        /// It will not advance the reader.
        ///
        ///
        ///
Type of the object to get (Must inherent from DBOBject)        ///
        static protected DBObject FromReader(MySqlDataReader reader, Type who_type)
        {
            DBObject who = (DBObject)Activator.CreateInstance(who_type, true);
            //Look for all the properities
            foreach (PropertyInfo properity in who_type.GetProperties())
            {
                if (properity.CanWrite)
                {
                    object[] attributes = properity.GetCustomAttributes(false);
                    foreach (object attribute in attributes)
                    {
                        if (attribute is DBColumn)
                        {
                            try
                            {
                                properity.SetValue(who, reader[((DBColumn)attribute).Column], null);
                            }
                            catch (IndexOutOfRangeException)
                            {
                                //Just Skip it
                            }
                            catch (Exception ex)
                            {
                                string junk = ex.Message;
                            }
                        }
                    }
                }
            }
            return who;
        }
    }

Here is my test object.

    [Serializable]
    [DB.MetaData.DBTable("users")]
    class DBUser : DBObject
    {
        [DBColumn("first_name")]
        public string FirstName
        {
            get
            {
                if (!_properties.ContainsKey("first_name"))
                {
                    _properties["first_name"] = string.Empty;
                }
                return (string)_properties["first_name"];
            }

            set
            {
                _properties["first_name"] = value;
            }
        }

        [DBColumn("last_name")]
        public string LastName
        {
            get
            {
                if (!_properties.ContainsKey("last_name"))
                {
                    _properties["last_name"] = string.Empty;
                }
                return (string)_properties["last_name"];
            }

            set
            {
                _properties["last_name"] = value;
            }
        }

        public string FullName
        {
            get { return this.FirstName + " " + this.LastName; }
        }

        [DBColumn("id", true)]
        public int ID
        {
            get
            {
                if (!_properties.ContainsKey("id"))
                {
                    _properties["id"] = -1;
                }
                return (int)_properties["id"];
            }

            set
            {
                _properties["id"] = value;
            }
        }

        protected DBUser() { }

        static public void DEBUG()
        {

            string suery = DBObject.SelectQuery(typeof(DBUser)) + " WHERE id=?id";

            Console.Write("Going to run: " + suery);

            using (MySqlConnection conn = new MySqlConnection(Utility.connMy))
            {
                MySqlCommand cmd = new MySqlCommand(suery, conn);
                cmd.Parameters.AddWithValue("?id", 1327);

                try
                {
                    conn.Open();
                    MySqlDataReader reader = cmd.ExecuteReader();

                    if (reader.Read())
                    {
                        DBUser user = (DBUser)DBObject.FromReader(reader, typeof(DBUser));
                        Console.WriteLine("nGot: " + user.FullName);
                    }

                    conn.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("nnERROR:n" + ex.Message);
                }
            }

            //Now try the properity
            Console.WriteLine("nnTrying the By Methiod (ID)");
            DBUser u2 = (DBUser)DBObject.By("id", "1327", typeof(DBUser), Utility.connMy);
            if (u2 != null)
            {
                Console.WriteLine("Got: " + u2.FullName);
            }
            else
            {
                Console.WriteLine("Oops, got a null back");
            }

            //Try another property
            Console.WriteLine("nnTrying the By Methiod (FirstName)");
            DBUser u3 = (DBUser)DBObject.By("firstname", "chris", typeof(DBUser), Utility.connMy);
            if (u3 != null)
            {
                Console.WriteLine("Got: " + u3.FullName);
            }
            else
            {
                Console.WriteLine("Oops, got a null back");
            }
        }
    }
Share

Next Steps

So far I think things are going good. I could even start to use this in the real world. But I’d like to complete a few more features first.

Having a .By(Property, Value) method. That way we could get an object by any defined property.

Having something like .Get(Property) and .Set(Property) that will return the value of any property. Right now the child class has to access the underlying _properties hash. I don’t necessarily like that idea, it gives the developer a chance to screw up more than just the property they are working with (since all properties are through the same hash.) Also methods like that would mean that the developer wouldn’t have to check if the property already exists and if they should return a default value. On the down side, how do you define what the default should be? probably in the attribute.

Share

DBObject rev .02

Ok, here is the code with the static modifications.
I like this better, but I don’t like the whole “(DBUser)DBObject.FromReader(reader, typeof(DBUser));” (or “(DBUser)DBUser.FromReader(reader, typeof(DBUser));”) thing. It just seems like I’m having to type to much. Then again, the child class could encapsulate some of this passing by type.

DBObject

   ///
   /// This is the baseclass for DB Object created by Chris Richards   /// 

   [Serializable]   public class DBObject   {       //Holds all the properties in the object       protected Hashtable _properties = new Hashtable();

       protected DBObject() { }

       ///
       /// This will populate all of the properties from the table by the column 'id'       /// 

       ///       ///        public object ByID(int id)       {           return new DBObject();       }

       ///
       /// Gets the SELECT ... FROM query for this object       /// 

       static protected string SelectQuery(Type who)       {           //Generate the Select Query           string _select = "SELECT";

           //Now Set all the select columns           foreach (PropertyInfo properity in who.GetProperties())           {               foreach (object attribute in properity.GetCustomAttributes(false))               {                   if (attribute is DBColumn)                   {                       _select += " " + ((DBColumn)attribute).Column + ",";                   }               }           }

           //Remove the last Comma           _select = _select.Substring(0, _select.Length - 1);

           //Get the Table Name for this Object           foreach (object attr in who.GetCustomAttributes(false))           {               if (attr is DBTable)               {                   //Add the Table to our List                   _select += " FROM " + ((DBTable)attr).Table;               }           }           //Now Return it           return _select;       }

       ///
       /// This will populate the object from the reader.       /// It will not advance the reader.       /// 

       ///       ///        static protected DBObject FromReader(MySqlDataReader reader, Type who_type)       {           DBObject who = (DBObject)Activator.CreateInstance(who_type, true);           //Look for all the properities           foreach (PropertyInfo properity in who_type.GetProperties())           {               if (properity.CanWrite)               {                   object[] attributes = properity.GetCustomAttributes(false);                   foreach (object attribute in attributes)                   {                       if (attribute is DBColumn)                       {                           try                           {                               properity.SetValue(who, reader[((DBColumn)attribute).Column], null);                           }                           catch (IndexOutOfRangeException)                           {                               //Just Skip it                           }                           catch (Exception ex)                           {                               //ErrorLog.Log(-1, this.GetType().Name + " reader Error", ex.Message);                               string junk = ex.Message;                           }                       }                   }               }               else               {                   ErrorLog.Log(-1, "Can't Write " + who.GetType().Name + "'s Properity", "Properity: " + properity.Name);               }           }           return who;       }   }

Test Code

And here is the test example

            string suery = DBObject.SelectQuery(typeof(DBUser)) + " WHERE id=?id";

            Console.Write("Going to run: " + suery);

            using (MySqlConnection conn = new MySqlConnection(Utility.connMy))            {                MySqlCommand cmd = new MySqlCommand(suery, conn);                cmd.Parameters.AddWithValue("?id", 1327);

                try                {                    conn.Open();                    MySqlDataReader reader = cmd.ExecuteReader();

                    if (reader.Read())                    {                        DBUser user = (DBUser)DBObject.FromReader(reader, typeof(DBUser));                        Console.WriteLine("nGot: " + user.FirstName);                    }

                    conn.Close();                }                catch (Exception ex)                {                    Console.WriteLine("nnERROR:n" + ex.Message);                }            }
Share

Static again

I haven’t been able to work on this for a while because of school and work. I was rereading my last post and I noticed that I have to create a new DBUser in order to get the SelectQuery for it. I don’t like this, it violates my ‘new’ rule. One of the reasons it’s not a static method is because it caches the query string. But it doesn’t really matter if it caches the query if you call a new object each time, it eliminates the point of the cache.

So this is where I’m going to pick things back up, I’m going to make those two static and post the code.

The only problem is, how so I make these static? The base needs to know the child’s type to work. When they wheren’t static I could just use the this keyword. But as a static methiod I no longer have access to that keyword. The only alternative I can think of off the top of my head is requireing a type passed to both methods. I don’t know that I quite like that idea.

Share

Ideas

For years I’ve been toying with different ideas for thinking or evolving software. The concept where you give the program a goal, some starting information, and some rules; and the program figures out the best way to reach the goal.

My favorite so far is the evolving method. The program created thousands to millions of little randomized programs and makes them survive or die. Maybe I’m just fascinated by the idea that something intelligent can derive from randomness. One of my favorite demonstrations is where clocks evolve out if random parts (YouTube clock evolution).

If I could harness this idea, then there would be no limit to the problems it could solve. With enough time and possessing power, it could solve anything.

So I was thinking today of how to build said program. My first instinct was to build it in C# because that’s where I’m strongest. Then I thought I should build it in python because the language is a lot more flexible and would lend it’s self easer to this kind of project.

Both have good points and both could be argued for my zen method. But which one is the right one? Spending too much time on that question is very anti-zen. It’s better to just pick one, even the wrong one, than to spend to much time debating the choices.

Back to how the system would work. I was thinking something like a table structure. The first column would be the input. The second would be the rule or function. The third would be the result.

The input could come from any of the sensory inputs, any random number(s)/letter(s), or the result from any row above it. This table would then be the programs DNA so to speak. It would be evaluated in order and the last row would contain the final result.

The rules would have to defined to the specific problem being solved. Over time universal rules that apply to almost any (if not all) problems could be defined. I think the more general the rules are, the longer it will take to find the best solution.

With enough random creatures, a very small percent will have some sort of solution. Then the winners go on to round two and new random children are created. Some of the new children will get random sections of the winners DNA. This process is repeated until the best solution is found.

A Question.
How do we know who was close to the correct solution? It would be easy if some of the found the solution, but I fear that that would take an impossible number if starting creatures.

Share

Decisions

So as I’m thinking about the DBOBject I just created. I ask myself, “Why make a protected method FromReader() vs just using a constructor? Why a protected method and not just a static method?”

The way I see it, using the “new” keyword to create a database object should create a table in the database. So using the datareader in the constructor isn’t an option because we are retrieving the object from the database, not adding one to it.

The static question is a bit tricker. I’m not 100% sure that it shouldn’t be a a static method. It would eliminate a step. right now you have to do something like:

    DBUser user = new DBUser();

    string suery = user.SelectQuery + " WHERE id=?id";

    Console.Write("Going to run: " + suery);

    using (MySqlConnection conn = new MySqlConnection(Utility.connMy))    {        MySqlCommand cmd = new MySqlCommand(suery, conn);        cmd.Parameters.AddWithValue("?id", 1327);

        try        {            conn.Open();            MySqlDataReader reader = cmd.ExecuteReader();

            if (reader.Read())            {                user.FromReader(reader);            }

            conn.Close();        }        catch (Exception ex)        {            Console.WriteLine("nnERROR:n" + ex.Message);        }    }

Which means we are still calling new on the object (even though it’s internally, it still violates the whole ‘new should be to add a record’ idea. If I changed .FromReader to be a static method, then we could simply do this:

            DBUser user = null;

            string suery = user.SelectQuery + " WHERE id=?id";

            Console.Write("Going to run: " + suery);

            using (MySqlConnection conn = new MySqlConnection(Utility.connMy))            {                MySqlCommand cmd = new MySqlCommand(suery, conn);                cmd.Parameters.AddWithValue("?id", 1327);

                try                {                    conn.Open();                    MySqlDataReader reader = cmd.ExecuteReader();

                    if (reader.Read())                    {                         user = DBUser.FromReader(reader);                    }

                    conn.Close();                }                catch (Exception ex)                {                    Console.WriteLine("nnERROR:n" + ex.Message);                }            }

It still takes the same number of lines of code, but it doesn’t violate the “new keyword” rule.

I think I like the method being static. Mostly because it stays constant.

Share

DBObject

I made some changes so I could display code on the site. Thanks to This guy

below is a basic working starting point for the DBObject. It does one very important thing. It can fill it’s self out from a DataReader.

  ///
  /// This is the baseclass for DB Object created by Chris Richards
  ///
  [Serializable]
  public class DBObject
  {
      //Holds all the properties in the object
      protected Hashtable _properties = new Hashtable();

      private string _select_query;
      private PropertyInfo[] _obj_proterties;

      ///
      /// An Array of all the properities for this object
      ///
      private PropertyInfo[] _propteries_
      {
          get
          {
              if (_obj_proterties == null)
              {
                  _obj_proterties = this.GetType().GetProperties();
              }
              return _obj_proterties;
          }
      }

      ///
      /// Gets the SELECT ... FROM query for this object
      ///
      protected string SelectQuery
      {
          get
          {
              if (_select_query == string.Empty || _select_query == null)
              {
                  //Generate the Select Query
                  _select_query = "SELECT";
                  //Get Information about the object
                  object[] obj_attributes = this.GetType().GetCustomAttributes(false);

                  //Now Set all the select columns
                  foreach (PropertyInfo properity in this._propteries_)
                  {
                      object[] attributes = properity.GetCustomAttributes(false);
                      foreach (object attribute in attributes)
                      {
                          if (attribute is DBColumn)
                          {
                              _select_query += " " + ((DBColumn)attribute).Column + ",";
                          }
                      }
                  }

                  //Remove the last Comma
                  _select_query = _select_query.Substring(0, _select_query.Length - 1);

                  //Get the Table Name for this Object
                  foreach (object attr in obj_attributes)
                  {
                      if (attr is DBTable)
                      {
                          //Add the Table to our List
                          _select_query += " FROM " + ((DBTable)attr).Table;
                      }
                  }
              }

              return _select_query;
          }
      }

      protected DBObject() { }

      ///
      /// This will populate the object from the reader.
      /// It will not advance the reader.
      ///
      protected void FromReader(MySqlDataReader reader)
      {
          //Look for all the properities
          foreach (PropertyInfo properity in this._propteries_)
          {
              if (properity.CanWrite)
              {
                  object[] attributes = properity.GetCustomAttributes(false);
                  foreach (object attribute in attributes)
                  {
                      if (attribute is DBColumn)
                      {
                          try
                          {
                              properity.SetValue(this, reader[((DBColumn)attribute).Column], null);
                          }
                          catch (IndexOutOfRangeException)
                          {
                              //Just Skip it
                          }
                          catch (Exception ex)
                          {
                              //ErrorLog.Log(-1, this.GetType().Name + " reader Error", ex.Message);
                              string junk = ex.Message;
                          }
                      }
                  }
              }
              else
              {
                  ErrorLog.Log(-1, "Can't Write " + this.GetType().Name + "'s Properity", "Properity: " + properity.Name);
              }
          }
      }
  }
Share

Knit Project

I’ve been working on the Knit Project application because I need to have it done by xmas. I ran in to a problem once I started to run it as an Adobe AIR application. (It’s stupid to call it ‘Adobe AIR’ because AIR stands for Adobe Integrated Runtime. So I’m really saying Adobe Adobe Integrated Runtime. That’s just stupid, but google won’t return anything usefull if you just call it AIR. So you have to specify Adobe AIR. Thus, I am going to continue to call it Adobe Adobe Integrated Runtime.)

Adobe AIR uses Webkit to render HTML. Apparently, Webkit doesn’t like “for each()” in javascript. So I had to change all of my “for each()” to just “for()”.

I also notice that the placement of the controls, which looked OK in firefox, looked like ass in Adobe AIR. My inital thought was to break the controls into their own windows like Photoshop/Illistrator/etc. I’ve never used windows or popups in my webdesign before. Opening the window was easy, trying to get the windows to comunicate proved difficault.

So I was thinking about how to solve this problem, and I asked myself. Do I need the controls in a seprate window? Does it add anything significate to the program? The answer was a restounding “No.” So I threw out the idea and asked, “What would be the fastest/easyest way to group these controls?” Tabs of course! Within a few minuetes I had the controls broken up into tabs at the top of the application. Not only did this look nicer, it make easer to work with the grid. Which is the entire point of the application.

Loading and saving to a file proved to be dead easy. I was able to copy some code from Adobe’s API refrence and adapt it to my program. It took less than 10 minenutes.

I did run into another bug with Webkit. I have a table of all the knitting symbols the user can click on. When you click on one of these symbols, it updates the Marker cell. This worked fine under firefox. But for whatever reason, Webkit will only show the image properly if I double click on the symbol. I set the ‘src’ to the image, which works fine, but when I resize the image. Webkit stops showing the image the first time. Once I’ve seen it in the marker once, it’ll always work properly on the first click. I spent a half and hour or so trying to fix this bug. I couldn’t get it working so I just remved the code that resized the image. I can always go back and fix it later if I need to.

I’m thinking I might have to rewrite the zoom function again. If you zoom all the way in, and then zoom out, the knit symbols are tiny. I want to fix it, but I’m not sure about the best way.
I thought about making all of the image one specific size. (right now they are all diffrent sizes). Another way would be to store the orginal size somewhere (probably in the symbol JSON) so I could refrence it. If I do that, I need to keep better track of the “zoom level” so I know how to adjust the image size.

Another bug: In the grid it’s self, if there is an image, the user can click on the image and not the table cell, which won’t cause the cell to change to the current marker.

Share

Welcome!

Welcome to Zen Software.
*note: I know that some may dissigree with the way I am using the word “Zen” I am using it in the meaning of simple and without excess.

My goal is to develop simple applications that focus on getting the job done. I want to move away from all of the features and bloat. Every decision in designing the software should first ask, “Does this contribute to mission of the application?”

I have two projects right now. One is a knit pattern application that I am making for my girl friend. The other is a flash card program. Both of these applications use Adobe AIR.

Why Adobe AIR?
After playing around with Adobe AIR, I found that it does what I need without making me do anything I don’t want to. I can create a page in HTML/CSS/Javascript and it will just work with Adobe AIR. If I don’t want anything else, I don’t have to use anything else. If I want some extras, like the ability to load and save to a file; it’s there. If I want to use jQuery, I can. It just works and stays out of my way. That is why I am using Adobe AIR for these projects.

Does using Adobe AIR contribue to the projects?
Both projects require some way to save and load data. The knit project needs the ablity to save and load patterns. Otherwise it doesn’t achive its purpose of allowing my girlfriend to easally view/edit/print knitting patterns. The same deal with the flash card program.

There are many options I could take to solve this problem. The solution that comes to mind first is to use a database. Save the knit patterns in the database, then she could access them anywhere and we open up the possiblity to having people share patterns.

The downside to useing a database is that I would need some kind of server side scripting. And a database. There may be ways to talk to a database without serverside (I didn’t look.) But that still doesn’t elminate the need for a database. And the need to maintain that database. I’m not saying that these are terribaly difficault tasks, but they don’t really fit the zen concept. That’s more work that I’d have to do that doesn’t really focus on the purpose of the application. There is no real need that anyone other than my girlfriend use the program. There is no real need to allow people to share patterns over the internet. There are other ways to provide those same features (like email) without me building something specific.

This is why I choose Adobe AIR. I can easly save and load the patterns to files on the hard drive. No server side script is required. The only requirement is that the computer has Adobe AIR, or at lest Flash. Everyone has flash (except my iphone) so that’s not an issue. (More specifically, my girl friends old laptop has flash.)

Share

School is almost over!

I haven’t worked on this project since school started. It’s finals week so I thought I should start this project again.

I think I may have bitten off more than I can chew with this project. It’s become larger and more complicated than I initially imagined. So the first step is to review the goal of the project.

Goal:
To make developing Database Objects easier by having many of the details taken care by the object it’s self. A developer with little skill should be able to create an object that inherits from the DBObject and start using it.

Step 1:
I find the most repetitive part of developing database objects has been filling out the object. I have to make a loop to read the DataReader, and convert the columns to their proper types before assigning them to the object.

I could have a lot of time and error prone code, if the object would preform this task it’s self.

So this is where I’m going to restart. If I remember correctly, I either almost had this functionality already, or was very close to having it. Once I’ve verified it, then I can think about step 2.

Share