免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1862 | 回复: 0
打印 上一主题 下一主题

Using Amazon SimpleDB as an Object Persistence Dat [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-06 15:54 |只看该作者 |倒序浏览

I hate relational databases!  In a high traffic scenario they become painful to scale.  Data segmentation, replication, asynchronous updates….you can only go so far.  Schema changes alone require site outages and careful planning.  That is why I was excited when Amazon announced their
SimpleDB
service.  
Features:  

  • High Availability
  • Scales with you
  • No need to worry about schema
  • Has a free tier for low traffic uses

I am working on two social networking sites (
tool-assisted
,
beerpassport
) that I plan to use SDB for.  The basic idea is to have several cheap web servers talking to a pool of memcached instances that act as a caching mechanism for my object graph which is stored in SDB.  The first step towards implementing this solution is to come up with a way to persist objects into the SDB.
Object to be persisted  

First lets look at the object I want to save to the database.  I want as little actual db code in this object as possible.
[code:c#]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ToolAssistedCom.Models;
using Amazon.SimpleDB.ORM;
namespace ToolAssistedCom.Models
{
    public class Platform
    {
        public string Description { get; set; }
        public List Manufacturers { get; set; }
        public string Name { get; set; }
        public List OnlineServices { get; set; }
        public string Predecessor { get; set; }
        public string Successor { get; set; }
        [SDB(IsKey = true)] public string UID { get; set; }
        ///
        /// Default constructor
        ///
        public Platform()
        {
            Description = "";
            UID = "";
            Name = "";
            Manufacturers = new Liststring>();
            Predecessor = "";
            Successor = "";
            OnlineServices = new Liststring>();
        }
    }
}[/code]
Base Class
Now I am going to define my base class.  I want this class to be generic enough to load any object from the database.  I have defined two methods called LoadOne and LoadMany which will be used to do this.  I have not implemented a save mechanism yet.
[code:c#]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon.SimpleDB;
using Amazon.SimpleDB.Model;
using System.Reflection;
using Attribute = Amazon.SimpleDB.Model.Attribute;
namespace Amazon.SimpleDB.ORM
{
    public abstract class SimpleDBObject
    {
        protected string _domainName = "";
        protected string _columns = "*";
        protected string _sort = "";
        protected string _accessKeyId = "YOURKEY";
        protected string _secretAccessKey = "SECRETKEY";
        protected AmazonSimpleDB _service = null;
        protected SelectRequest _request = null;
        protected object _prototype = null;
        protected void SetupClient()
        {
            _service = new AmazonSimpleDBClient(_accessKeyId, _secretAccessKey);
        }
        protected void CreateNewSelectRequest()
        {
            _service = new AmazonSimpleDBClient(_accessKeyId, _secretAccessKey);
            _request = new SelectRequest();
        }
        protected void SetValueFromResponse(ref object myobj, string name, string value)
        {
            // Include the type of the object
            System.Type type = myobj.GetType();
            
            // Walk the properties on this object
            System.Reflection.PropertyInfo[] pi = type.GetProperties();
            if (pi.Length > 0)
            {
                foreach (PropertyInfo p in pi)
                {
                    
                    if (p.CanRead && p.CanWrite && p.Name.ToLower() == name.ToLower())
                    {
                        if (p.PropertyType == typeof(List))
                        {
                            ((Liststring>)p.GetValue(myobj, null)).Add(value);
                        }
                        else if (p.PropertyType == typeof(string))
                        {
                            p.SetValue(myobj, value, null);
                        }
                        else if (p.PropertyType == typeof(int))
                        {
                            p.SetValue(myobj, int.Parse(value), null);
                        }
                    }
                }
            }
        }//send SetValueFromResponse
        protected void LoadOneFromDB(string id)
        {
            SetupClient();
            CreateNewSelectRequest();
            _request.SelectExpression = "select " + _columns + " from " + _domainName + " where UID = '" + id + "'";
            if (!string.IsNullOrEmpty(_sort))
            {
                _request.SelectExpression += " order by " + _sort;
            }
            SelectResponse response = _service.Select(_request);
            
            if (response.IsSetSelectResult())
            {
                SelectResult result = response.SelectResult;
                List itemList = result.Item;
                foreach (Item item in itemList)
                {
                    if (item.IsSetName())
                    {
                    }
                    List attributeList = item.Attribute;
                    foreach (Attribute attribute in attributeList)
                    {
                        if (attribute.IsSetName() && attribute.IsSetValue())
                        {
                            SetValueFromResponse(ref _prototype, attribute.Name, attribute.Value);
                        }
                    }//end foreach attribute
                }//end for each item
            }//if issetseltresult
            else
            {
                throw new Exception("WTF M8");
            }
        }
        protected List LoadManyFromDB()
        {
            Listobject> myList = new Listobject>();
            SetupClient();
            CreateNewSelectRequest();
            _request.SelectExpression = "select " + _columns + " from " + _domainName;
            if (!string.IsNullOrEmpty(_sort))
            {
                _request.SelectExpression += " order by " + _sort;
            }
            SelectResponse response = _service.Select(_request);
            if (response.IsSetSelectResult())
            {
                SelectResult result = response.SelectResult;
                List itemList = result.Item;
                foreach (Item item in itemList)
                {
                    if (item.IsSetName())
                    {
                    }
                    object myobj = System.Activator.CreateInstance(_prototype.GetType());
                    List attributeList = item.Attribute;
                    foreach (Attribute attribute in attributeList)
                    {
                        if (attribute.IsSetName() && attribute.IsSetValue())
                        {
                            SetValueFromResponse(ref myobj, attribute.Name, attribute.Value);   
                        }
                    }//end foreach attribute
                    myList.Add(myobj);
                }//end for each item
            }//if issetseltresult
            else
            {
                throw new Exception("WTF M8");
            }
            return myList;
        }
    }
}[/code]
Glue Code

Finally here is the code that glues it together.
[code:c#]
class="MsoNormal"> using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon.SimpleDB.ORM;
using System.Reflection;
namespace ToolAssistedCom.Models
{
    public class SDBPlatform : SimpleDBObject, IPlatformRepository
    {
        public SDBPlatform()
        {
            _domainName = "Platform";
            _prototype = new Platform();
        }
        public Platform GetByUID(string id){
            LoadOneFromDB(id);
            return ((Platform)_prototype);
        }
        public void Add(Platform entity)
        {
            throw new NotImplementedException();
        }
        public void Remove(Platform entity)
        {
            throw new NotImplementedException();
        }
        public List GetPlatforms()
        {
            List temp = new List();
            foreach (Platform item in LoadManyFromDB())
            {
                temp.Add(item);
            }
            return temp;
        }
        public void Save(Platform entity)
        {
            throw new NotImplementedException();
        }
    }
}
class="MsoNormal"> [/code]
I will release more details as I finish writing the code. Once the code is in a pretty good state I will throw it up on codeplex incase anyone else wants to use it (or improve it).
[/url]



本文来自ChinaUnix博客,如果查看原文请点:[url]http://blog.chinaunix.net/u/78/showart_1891282.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP