Tuesday, December 8, 2009

Quickbase C# API Wrapper

Maybe I can save someone the tedium of wrapping the quickbase API in C#?  Fun, fun, fun, fun,...


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Collections.Specialized;
using System.Data;

namespace ICanHasCode
{
    public static class Apis{
        public const string Authenticate = "API_Authenticate";
        public const string DoQuery = "API_DoQuery";
        public const string GetDbInfo = "API_GetDBInfo";

    }

    public struct QuickbaseDbInfo
    {
        public string dbname;
        public DateTime lastRecModTime;
        public DateTime lastModifiedTime;
        public DateTime createdTime;
        public long numRecords;
        public string mgrID;
        public string mgrName;
        public string version;

    }

    public static class QuickbaseApiWrapper
    {
        const string dbId = "YourQuickbaseDatabaseId";
        const string queryId = "YourQuickbaseQueryId";

      
        private static string CreateRootDoc(string apiName, StringDictionary parameters)
        {
            XmlDocument doc = new XmlDocument();
            XmlElement root = doc.CreateElement("qdbapi");

            if(parameters!=null)
                foreach(string field in parameters.Keys){

                    XmlElement child = doc.CreateElement(field);
                    child.InnerText = parameters[field];
                    root.AppendChild(child);           
                }

            doc.AppendChild(root);
            StringWriter sw = new StringWriter();
            XmlTextWriter xw = new XmlTextWriter(sw);
            doc.WriteTo(xw);
        
            return sw.ToString();
        }

        private static System.Data.DataSet GetQueryResults(string dbIdParam, string action, StringDictionary parameters)
        {
            string url = "https://www.quickbase.com/";
            if(dbIdParam!=null)
                url+="db/"+dbIdParam;
            url+="?act=" + action;
            foreach (string s in parameters.Keys)
            {
                url += "&" + s + "=" + parameters[s];
            }

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);

            webRequest.Method = "POST";
            webRequest.ContentType = "application/xml";
            webRequest.Headers.Add("QUICKBASE-ACTION", action);
            string input = CreateRootDoc(action, parameters);
            byte[] postBytes = Encoding.ASCII.GetBytes(input);
            webRequest.ContentLength = postBytes.Length;
            Stream postStream = webRequest.GetRequestStream();
            postStream.Write(postBytes, 0, postBytes.Length);
            postStream.Close();
            WebResponse response = webRequest.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream());
         
            XmlTextReader xmlReader = new XmlTextReader(reader);
            StringDictionary toGo = new StringDictionary();
            System.Data.DataSet ds = new System.Data.DataSet();
            ds.ReadXml(xmlReader, System.Data.XmlReadMode.Auto);

            return ds;
            //return response.ToString();

        }

        public static string Authenticate(string username, string password)
        {
            StringDictionary parameters = new StringDictionary();
            parameters.Add("username", username);
            parameters.Add("password", password);
            DataSet ds = GetQueryResults(null, Apis.Authenticate, parameters);

            string errorMessage = ds.Tables[0].Rows[0]["errtext"].ToString();
            string errorCode = ds.Tables[0].Rows[0]["errcode"].ToString();
            if (errorCode != "0")
                throw new Exception("Quickbase login failed: " + errorMessage + ", code:" + errorCode);
            else
                return ds.Tables[0].Rows[0]["ticket"].ToString();
        }

        public static QuickbaseDbInfo GetDbInfo(string ticket)
        {
            StringDictionary parameters = new StringDictionary();
            parameters.Add("dbid", dbId);
            parameters.Add("ticket", ticket);

            DataSet ds = GetQueryResults(dbId, Apis.GetDbInfo, parameters);

            QuickbaseDbInfo toGo = new QuickbaseDbInfo();
            DateTime kookyBaseDate = new DateTime(1970, 1, 1);
            toGo.dbname = ds.Tables[0].Rows[0]["dbname"].ToString();
            toGo.createdTime = kookyBaseDate.AddMilliseconds(double.Parse(ds.Tables[0].Rows[0]["createdTime"].ToString()));
            toGo.lastModifiedTime = kookyBaseDate.AddMilliseconds(double.Parse(ds.Tables[0].Rows[0]["lastModifiedTime"].ToString()));
            toGo.lastRecModTime = kookyBaseDate.AddMilliseconds(double.Parse(ds.Tables[0].Rows[0]["lastRecModTime"].ToString()));
            toGo.numRecords = long.Parse(ds.Tables[0].Rows[0]["numRecords"].ToString());
            toGo.mgrID = ds.Tables[0].Rows[0]["mgrID"].ToString();
            toGo.mgrName = ds.Tables[0].Rows[0]["mgrName"].ToString();
            toGo.version = ds.Tables[0].Rows[0]["version"].ToString();

            return toGo;
        }

        public static DataTable DoQuery(string ticket)
        {
            StringDictionary parameters = new StringDictionary();
            parameters.Add("dbid", dbId);
            parameters.Add("ticket", ticket);
            parameters.Add("qid", queryId);
            DataSet ds = GetQueryResults(dbId, Apis.DoQuery, parameters);
            return ds.Tables[2];
        }

       
    }
}


4 comments: