I worked some more on this last night and made some good progress. Our models previously were manually extracting values from the TablularData for the CloudDB data row. This meant we hard coded which column index to read. It’s not flexible. I could write code to generate a proxy class derived from the model which would be marked a virtual. However, that would cause problems on medium trust, so I went with basic Reflection to find properties and a custom attribute to specify the CloudDb column name. Here’s what that looks like:
1: public class CloudDBColumnAttribute : Attribute
2: {
3: public string Name { get; set; }
4:
5: public CloudDBColumnAttribute(string name)
6: {
7: Name = name;
8: }
9: }
Use that to tag your properties:
1: [CloudDBColumn("id")]
2: public Guid Id { get; set; }
Just use GetType().GetProperties() to find the properties for the class, and then check if that property is tagged like this:
1: object[] columnAttributes = info.GetCustomAttributes(typeof(CloudDBColumnAttribute), true);
2: if (columnAttributes == null || columnAttributes.Length == 0 || !(columnAttributes[0] is CloudDBColumnAttribute)) continue;
You can then loop through each of the tagged properties and find the corresponding column in the TabularData to find the right column. Then take that index to get the right value from the Row fields. The end result is an easy way to set property values from CloudDB data.
1: public static T Open(TabularData data, Row row)
2: {
3: T item = new T();
4: item.Map(data, row);
5: return item;
6: }
I’ll post more later, and I’ll provide code on request.
Update
So I got the csinc site switched over to using v3 api instead of the v2 CloudDB strongly typed service. Generally, I like it because it allows greater flexibility. That could have been true for v2 api, but I haven’t tried it so I can’t say. The CloudDB hasn’t put together the docs for this yet, so I’ll show you some code to use it below.
Why use it
First, it keeps the website portable. It doesn’t matter where it’s hosted because the datastore doesn’t change. Second, We can tweak content and even some behavior/layout stuff easily by making the change using the clouddb website.
Implementation
I’m not entirely settled with our implementation so far. How we read columns and set object properties needs work. Also, I re-factored the base to pass in a context object basically just to pass around a pointer to the IWindsorContainer instance so it would work in the web app and in the test project. It’s one of those quick hacks which you’re not quite happy with but don’t really have another good idea at the time. I just wanted my tests to pass.
Getting started
First you have to get an invite, and then set up a clouddb account. Once done, add the clouddb api url as a webreference and begin coding. Start with the login code:
1: public static Token Login(string user, string password)
2: {
3: using (CloudDB cdb = new CloudDB())
4: {
5: return Login(cdb, user, password);
6: }
7: }
8:
9: public static Token Login(CloudDB cdb, string user, string password)
10: {
11: Token tok = cdb.LogIn(user, password).Result;
12: return tok;
13: }
Using an instance of CloudDB and the Token, you call whatever api method you need. Our site only uses reads so far. So here’s how we get a list of rows:
1: public static RowsResponseData GetRowData(CloudDB cdb, Token token, string appName, string entityName, Predicate[] predicates)
2: {
3: App app = cdb.GetApplicationByName(token, token.UserID, appName, false, false).Result;
4: Entity e = cdb.GetEntityByName(token, app, entityName, false).Result;
5: RowsResponseData rowData = cdb.SearchEntity(token, app, e, predicates, 0, 0, 0, 0).Results;
6: return rowData;
7: }
In the above code, the Predicate array is used to specify which rows to get back from clouddb. That’s how we get a single match if we want. Just query for the id or other unique criteria. Here’s how we handle that in our record base class:
1: public static T GetRecord(IAppContext context, string cacheKey, string entityName, Predicate[] predicates)
2: {
3: CachedItem ci = DataCache.GetItem(cacheKey);
4: if (ci != null) return (T)ci.Data;
5:
6: try
7: {
8: ICloudConnectionSettings connectionSettings = context.Container.Resolve<ICloudConnectionSettings>();
9: RowsResponseData rowData = CloudDBDataAccess.GetRowData(connectionSettings.CloudDBApplicationName, entityName, connectionSettings.CloudDBUser, connectionSettings.CloudDBPassword, predicates);
10: T item = new T();
11: item.Init(rowData.Data, 0);
12: DataCache.Add(cacheKey, item);
13: return item;
14: }
15: catch (Exception er)
16: {
17: T item = default(T);
18: DataCache.Add(cacheKey, item);
19: return item;
20: }
21: }
You’ll notice that caching is also handled at that layer so the specific model doesn’t have to know or think about it. (Yes, there are things I can do to improve this. Remember, time for our own site isn’t a high priority versus time for clients.)
..and a sample usage:
1: protected bool ShowDynamicContent()
2: {
3: return ShowDynamicContent(Request.FilePath.ToLower());
4: }
5:
6: protected bool ShowDynamicContent(string contentName)
7: {
8: var pageContent = PageContent.GetByPath(new AppContext(), contentName);
9: if (pageContent != null && pageContent.IsPublished)
10: {
11: PropertyBag["contentTitle"] = pageContent.Title;
12: PropertyBag["contentDescription"] = pageContent.Description;
13: PropertyBag["content"] = pageContent.Content;
14: RenderView("../shared/contentview");
15: return true;
16: }
17: return false;
18: }
1: public void Index()
2: {
3: //show dynamic content if available, defaults to view file content if not
4: ShowDynamicContent();
5: }
Good to know
Clouddb data is described with Entity objects representing the table, Column objects describing the columns for data, and Row objects containing the data. Think of it a little like a DataSet in .Net. You’ll need to know a little about the columns in the data, and then read the values from the Rows array. Also, you’'ll need to know the application name, which is the specific clouddb database in your account.
That’s a simple overview. Hopefully it helps. There is more to it, but that should get you started.


I’m continuing to play with CloudDB as the data store for the computerist solutions site. Currently the sidebar links are stored in clouddb, as well as optionally storing most page content in it. Currently, only the home page has its content in clouddb. It’s built so most pages check on first load if content is available in clouddb, otherwise render the normal view.
So all this makes me think.. why not add a users table and go full on CMS with it. I think it would work. So why not also build our own blog engine too. Again, it might just work but it becomes a question of size restrictions. I just don’t know what clouddb will allow/handle. I’ll have to ask the team about it.
Speaking of features, CloudDB is working on the next version. It may get released by the time this gets published. I’m waiting to see what changes there are. There will be JSON support I’m told, which will make be wonder whether to stick with the current webservice method of calling it or move to the JSON method.
Overall, I like clouddb. It’s perfect for the csinc site. It maintains the portability directive because we can host anywhere and still fetch data from clouddb. Plus we have some nice flexibility with the content. It really is an enticing solutions. It took some thinking to centralize the data access and caching, but worked out. Now I’m just waiting to see what clouddb v3 brings.
I’ll probably post again on CloudDB when the next version comes out. I’ll do some code samples at that time. Maybe a working sample project for people to try.
Other Goings On
In other news, I recently found myself considering buying a new vacuum. It was a good vacuum when we bought it but it had lost its power over the last year. Thanks to some random review, I rechecked the filter I thought I cleaned and found that it was actually just the housing for the actual filer. After cleaning it, the power is back! How many times have you felt you code base is old and worn out? Maybe you just need clean it out a bit instead of throwing it away. Add some tests, maybe use clouddb, or refactor some common code. Having made the clouddb changes to csinc, it feels refreshed and not so stale. I still want some more clean up and better testing but I like where its going. ..just a little life lesson applied to work.
CloudDb is a web based data store, and it’s pretty cool. I got an invite a while ago from my friend Scott Cate (mykb), but didn’t really dig too much into it. Now if you follow this blog, you’d now we’ve been looking at different data storage options for various things such as content for this site. Most embedded db’s aren’t an option because it’s currently hosted in a Medium Trust environment which doesn’t allow native calls (all the embedded db’s I know require this). That pretty much killed it. We have the option of using mysql or 1 sql server database but we’d like to keep this as portable as possible. Also, there are other plans for that.
But Hey! Why not use a cloud or web based service? We want to be able to manage some content without re-deploying, and a cloud service would allow that. Yes, most of the current content are just stored in view files, but what’s the fun in that?
I’ll probably post more info when I get something together. In the meantime, click the link and watch the videos.