<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programmer&#039;s Notes &#187; DB</title>
	<atom:link href="http://programmersnotes.info/tag/db/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmersnotes.info</link>
	<description>Notes on the web-development and artificial intelligence.</description>
	<lastBuildDate>Mon, 18 Jul 2011 13:20:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Requirements and Use Cases. SMS Notification System.</title>
		<link>http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/</link>
		<comments>http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 06:00:56 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[OOP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[experiece]]></category>
		<category><![CDATA[modelling]]></category>
		<category><![CDATA[sms-notify]]></category>
		<category><![CDATA[UML]]></category>

		<guid isPermaLink="false">http://programmersnotes.info/?p=342</guid>
		<description><![CDATA[Background I&#8217;ve graduated in March 2010 and I don&#8217;t need to visit university any more. However, I enjoyed studying there and I know what challenges my fellow students-programmers have. That&#8217;s why I continue the job started this autumn – computer club, we call it “Geeks&#8217; Club”. Sure, we&#8217;re not true geeks there, but we tend [...]


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h2><a name="background">Background</a></h2>
<p>I&#8217;ve graduated in March 2010 and I don&#8217;t need to visit university any more. However, I enjoyed studying there and I know what challenges my fellow students-programmers have. That&#8217;s why I continue the job started this autumn – computer club, we call it “Geeks&#8217; Club”. Sure, we&#8217;re not true geeks there, but we tend to be <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  So I&#8217;m helping students who&#8217;re interested in web-technologies and in object-oriented programming. I explain them things that are not covered in the standard university course. Things, that are more practical and they can be paid money for.</p>
<p><span id="more-342"></span></p>
<p>Here I&#8217;ll be covering both OOP and web-dev, but we&#8217;ll start from design hence OOP. The story began when some time passed after we started learning OOP at the club meetings and I decided that there is enough theory and separate examples, it&#8217;s time to build something practical that will be challenging for me too.<br />
I thought of different systems, but finally decided to pick up the SMS notification one. It requires both user interface, database, API (my friends want to communicate to it from standalone Java and C++ applications) and overall application design. In addition, I&#8217;d like such system to be deployed at our university and it is interesting for me to create one.</p>
<h2><a name="intro">Introduction</a></h2>
<p>This is going to be a series of articles, I&#8217;ll describe the progress and challenges we come across as we proceed with development. I think this kind of posts will be interesting for those who study OOP and want to apply what they&#8217;ve learned to some practical things. I&#8217;ll try to guide my students through the process using the iterative development methodology.</p>
<p>We have meetings once a week (on Saturdays), so I&#8217;ll post once or twice a week, depending on amount of work done on weekends and my free time during the week.</p>
<p>I think, this series will contain around 10 posts. We&#8217;re going to share the work done as an open-source project. There is nothing to share at the moment, so I&#8217;ll give the link when we code something <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2><a name="overview">System overview</a></h2>
<h3><a name="vision">Vision</a></h3>
<p>Obviously, the main purpose of the system is to send SMS notifications to students or tutors. These notifications may be quite different – from the timetable changes to some announcements or even warnings (e.g. “Due to the weather conditions, today is a day-off for all. Stay at home and have a good time”).</p>
<p>Actually the system isn&#8217;t that complex. Basically all it needs to do is to enable administrator pick a group of users, enter the message and send it through the SMS gateway. The tricky things start from “pick a group of users”. We want this to be as flexible as possible so we could use this system not only for university, but any other organization.</p>
<h3><a name="vision">University structure</a></h3>
<p>This is obvious to anyone who studied at the university in Ukraine, Russia and former USSR, but I&#8217;m not sure the structure is the same abroad. So we have the university. There are faculties (e.g. Computer Science, Philology etc). These faculties have specialties. For example, Computer Science faculty has 2 specialties – “Intellectual Systems of Decision-Making” (mine) and “Computer Engineering”. (For those interested about the difference, first one deals more with AI technologies while the latter – with system programming, networks etc).</p>
<p>Next level is “course”. We call it so, but actually that is the year of study. I know, there are special words for the 1st year students, for the 2nd etc. Here we just say “I&#8217;m on the first course”. That means “I&#8217;m studying the first year”.</p>
<p>All students that study the same specialty and are on the same course are called “Stream”. This is literal translation and I&#8217;m sure there is some more correct term. I&#8217;d be thankful if someone posts it in comments.</p>
<p>There are 2-4 groups in the “stream”. In our university they are names as follows: 101, 102, 103 etc. First number is course. In this case it is the first one. Second number is the faculty code. 0 is for computer science. And the third number is the group number. Thus 102 is the second group of first-year  students studying Computer Science. I realize that not all universities name groups like this, so we don&#8217;t want to stick to such naming in our product.</p>
<p>Now let&#8217;s go through the tutors and staff. There is a rector of a university. There are deans for every faculty. And all tutors are grouped by departments. Usually, departments relate to the faculty, but that&#8217;s not a rule. For example, on our faculty we have Department of Higher Mathematics, Department of Intellectual systems ans some others. One tutor usually belongs to one department.</p>
<p>In addition, there are different clubs for students like our “Geeks&#8217; Club”, translators&#8217; “Pickwick Club” etc. Some of these clubs (like ours) have departments (Web-development, OOP, Java, C++, Delphi, Administration etc). </p>
<p>We want to be able to filter users using all the above groups plus some more user-specific filters like age or gender.<br />
Let&#8217;s go through the planned features now.</p>
<h3><a name="userperspective">User perspective</a></h3>
<p>First of all, user can log in. User should enter his phone number and password. We&#8217;ll possibly add additional security for administrators. If administrator logs in, he enters his phone and password, but then a dynamic password is sent to his phone. And he completes login procedure only after he enters this dynamic password. We&#8217;re not sure if we&#8217;ll implement this. Your comments are welcome!</p>
<p>Next, user can edit his profile. He&#8217;ll have the following fields there:</p>
<ul>
<li>Phone</li>
<li>Email</li>
<li>Password (and confirmation)</li>
<li>Name, surname, patronymic</li>
<li>Gender</li>
<li>Birthday</li>
<li>ICQ</li>
<li>Faculty</li>
<li>Course (1st year, 2nd year etc)</li>
<li>Group</li>
<li>Clubs user is member of</li>
<li>Any tags user assigns to himself (e.g. “musician”)</li>
</ul>
<p>Plus user should check the option “receive SMS”.</p>
<p>However, user can&#8217;t edit phone directly because we&#8217;ll have to confirm it. So instead of giving him the field in the profile editing form, we&#8217;d rather give him a button or a link which will bring him a from where he puts new phone number and password. After that a dynamic password is sent to his phone via SMS and he enters this dynamic password and phone is updated.</p>
<p>Finally, user may register. When registering, he enters nearly the same data as when editing profile, but there is a dynamic password sent to him in order to confirm the phone number.<br />
All these screens are shown below.</p>
<div id="attachment_346" class="wp-caption aligncenter" style="width: 563px"><a href="http://programmersnotes.info/wp-content/uploads/2010/03/UserArea.png"><img src="http://programmersnotes.info/wp-content/uploads/2010/03/UserArea.png" alt="User area screens" title="UserArea" width="553" height="702" class="size-full wp-image-346" /></a><p class="wp-caption-text">User area screens</p></div>
<h3><a name="groupadmin">Group Administrator perspective</a></h3>
<p>Group administrator role may be assigned to the club&#8217;s leader, to the group monitor (or it&#8217;s better to say headman? What sound more “English”), to the tutor or headmaster. Basically everyone who needs to send notifications will have this role.</p>
<p>So, this type of users can do the same as the simple user plus searching users, sending email notifications and viewing statistics.<br />
Each group administrator will be limited to the groups he may view/notify. For example, headmaster can notify anyone. Tutor may notify all groups of students he tutors in. Group monitor may notify all students within his/her group.</p>
<p>Listing users and searching through them is done in the same screen. In the main part of the screen there is a list of users that are in the groups available to the group administrator. In the left side there is a “narrow search” panel which lists all filters that can be applied to the current set of users. Clicking the filter option (e.g. “Geeks&#8217; Club”) lists all users that fall into the current filter conditions. And it also refreshes the filtering options. For example, if there is no girls in the “Geeks&#8217; Club” then there is no point to show these option in the filter. This is harder to code, but it will bring excellent user experience.</p>
<p>In the right hand side there will be the “saved searches” panel. When you applied some searching criteria, you may save it with some label so you can quickly access this search in the future. Were going to create standard searches in addition to filtering to simplify the system&#8217;s usage.</p>
<p>This works as following. For example, you can view all Computer Faculty. But you need only girls from the Geeks&#8217; Club. So you filter by gender and then by club. And save this search as “Girls-geeks” <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  This immediately appears in the right “saved searches” panel.</p>
<p>These saved searched may be group-specific and user-specific. This basically means that when group admin saves search, he may select if he wants it to be private or he wants to share this search with other group administrators, who have access to the same groups as he does. We think, this will help users creating the searches that they really need. Sure, saved searched may be easily removed.</p>
<p>In the right side there will be also a “Send notification” panel. It will contain only textarea field and a “send” button. When you have your group ready, you type the message an click “send”. It asks for confirmation, displaying how much it would cost and sends it over.</p>
<p>Another page in the Group administrator&#8217;s  perspective is statistics. Here he&#8217;ll see how much messages he sent during the last day/week/month/overall and how much did it cost.</p>
<p>As we progress with development, we may add some settings, that will be the third page then. Here&#8217;s the filtering screen:</p>
<div id="attachment_344" class="wp-caption aligncenter" style="width: 568px"><a href="http://programmersnotes.info/wp-content/uploads/2010/03/FilterUsers.png"><img src="http://programmersnotes.info/wp-content/uploads/2010/03/FilterUsers.png" alt="Filter users screen" title="FilterUsers" width="558" height="370" class="size-full wp-image-344" /></a><p class="wp-caption-text">Filter users screen</p></div>
<p>Statistics screen is pretty straightforward, so we&#8217;ll omit it here.</p>
<h3><a name="administrator">Administrator&#8217;s perspective</a></h3>
<p>Administrator is almost god here <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  He can manage users, assign rights to the group administrators, set limits of SMS count, view logs and overall statistics.<br />
Users management screen will be nearly the same as filtering, with the only difference that when clicking the row with user&#8217;s you&#8217;ll see the profile screen with additional options:</p>
<ul>
<li>ban/unban</li>
<li>delete</li>
<li>phone editing does not require confirmation</li>
<li>administrator of (group selection)</li>
<li>notifications limit</li>
</ul>
<p>Logs and statistics screens are quite simple too.</p>
<h2><a name="usecase">Use cases</a></h2>
<p>After analyzing the above overview, we come up with the following use case diagram. It is pretty self-explanatory and written after the description above, so it is useful only as a summary.</p>
<div id="attachment_345" class="wp-caption aligncenter" style="width: 451px"><a href="http://programmersnotes.info/wp-content/uploads/2010/03/UseCaseModel.png"><img src="http://programmersnotes.info/wp-content/uploads/2010/03/UseCaseModel.png" alt="SMS Notification Use Cases" title="UseCaseModel" width="441" height="697" class="size-full wp-image-345" /></a><p class="wp-caption-text">SMS Notification Use Cases</p></div>
<p>Following the iterative development methodology, we should describe all usecases now, but I find this quite useless. After describing all usecases briefly, we should select 10% critical usecases and describe them in full. Full description includes the sequence of actions taken in the main success scenario and all alternative scenarios that may happen (e.g. DB error, connection failure, no users found etc). This is useful sometimes, but I think that for such simple application as this one, we ma skip this step either.</p>
<p>What is really useful about the iterative development at this stage is that it recommends picking 10% of the most critical usecases and start implementing them in full. By “critical” I usually mean those which may result in essential DB structure or application design changes. In our case there are 14 usecases.10% is 1.4 usecase. Let&#8217;s pick only one. The most critical usecase, that affects all the application design and DB structure is the user filtering. The success of an application depend on the stability and usability of this feature. So we should code it efficiently and then move to the other usecases.</p>
<p>I like this approach cause it is much more practical than designing the system from the interface. Changing interfaces and adopting them to core is much more simple and has less risk than doing vice versa.</p>
<p>So we decided to start with user filtering. The first thing we should create is the database structure. This will be covered in the tomorrow&#8217;s post.</p>
<p>I&#8217;d like to learn your opinion on all that. Maybe you can propose some better interface, or some nice filtering approach or just some idea for this. We&#8217;re open to all suggestions and comments! Thank you for reading my blog and following this project <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Subscribe to RSS and stay tuned!</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d342').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d342" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;T=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;title=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Requirements+and+Use+Cases.+SMS+Notification+System.+@+http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2010%2F03%2F18%2Frequirements-use-cases-sms-notification%2F&amp;t=Requirements+and+Use+Cases.+SMS+Notification+System." rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d342').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d342').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2010/03/18/requirements-use-cases-sms-notification/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building high-loaded portal &#8211; InnoDB vs MyISAM</title>
		<link>http://programmersnotes.info/2009/05/20/building-high-loaded-portal-innodb-vs-myisam/</link>
		<comments>http://programmersnotes.info/2009/05/20/building-high-loaded-portal-innodb-vs-myisam/#comments</comments>
		<pubDate>Wed, 20 May 2009 07:00:55 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[DB Design]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[production]]></category>

		<guid isPermaLink="false">http://konstantin.takeforce.net/?p=5</guid>
		<description><![CDATA[Post shares practical experience of developing MySQL DB for the high-loaded website.


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h2><a name="intro">Preface</a></h2>
<p>In November 2008 I&#8217;ve got a nice project, that resulted in a complex search engine, that specializes in clothing. I can&#8217;t give the link now, but will do when site officially launches. Key features of such service are:</p>
<ul>
<li>Large number of users, which search with various parameters, rate items, leave comments, create articles etc.</li>
<li>Large database, that is updated frequently</li>
</ul>
<p>Sure, the site is running on a dedicated server, sure I use caching, but optimal DB is a key to success.</p>
<p><span id="more-5"></span></p>
<h2><a name="myisam-innodb">MyISAM or InnoDB?</a></h2>
<p>Since we need reliability, I created different tests, search the internet etc. My main question was &#8211; what to use MyISAM or InnoDB? I found the <a href="http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/">post on the MySQL Perfomance Blog</a> (also <a href="http://www.mysqlperformanceblog.com/2007/10/12/myisam-scalability-and-innodb-falcon-benchmarks/">this</a> and <a href="http://www.mysqlperformanceblog.com/2007/01/03/innodb-benchmarks/">this</a>) and came to the conclusion, that when SELECT&#8217;ing, InnoDB is definitely faster (or, at least, is not slower). In addition, it provides constraints mechanism and allows transactions. The only thing it doesn&#8217;t have is FULLTEXT search. One more disadvantage is slower inserts. However, 80% of DB usage in this project are SELECT queries without FULLTEXT. For the fulltext search I created MyISAM table with fields I need and it works fine. The project is finished, but there will be phase 2 and I&#8217;m thinking of introducing <a href="http://www.sphinxsearch.com/">Sphinx</a> there. Anybody has experience with it?<br />
So I came up with InnoDB storage engine.</p>
<h2><a name="structure">Optimizing structure</a></h2>
<p>Next important step is DB structure. I&#8217;ll give some background info about the project so you could better understand what I&#8217;m talking about. The site collects info from different UK shops. Then users can rate them, add some tags, create articles (called &#8220;looks&#8221;) and link that articles to the products they&#8217;re writing about. And the same (tags, comments, rating) applies to the looks. Here we come across with an interesting question. We can create structure of different types for this:</p>
<ul>
<li>Create 2 separate cross-tables for linking Rating to Look or Product</li>
<li>Create one cross-table and add additional field &#8220;type&#8221; there to differentiate between Product and Look entities</li>
</ul>
<p>See both variants in the following images:<br />
<div id="attachment_251" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/05/norm1.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/05/norm-300x174.png" alt="Normalized variant" title="Normalized variant" width="300" height="174" class="size-medium wp-image-251" /></a><p class="wp-caption-text">Normalized variant</p></div><br />
<div id="attachment_252" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/05/denorm1.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/05/denorm-300x157.png" alt="Denormalized version" title="Denormalized version" width="300" height="157" class="size-medium wp-image-252" /></a><p class="wp-caption-text">Denormalized version</p></div><br />
Initially I thought that the second variant would perform better, but after creating and running tests, I saw, that:</p>
<ul>
<li>If there are 0-2 ratings linked to entity, then normalized variant is better</li>
<li>If there are 3-5 ratings linked to entity, then denormalized variant is slightly (less than 1%) better</li>
<li>If there are 6-8 ratings linked to the entity, the normalized variant wins again</li>
</ul>
<p>I did these tests for different situations similar to this one, in each test I generated random records and randomly linked them with each other. Number of record in Product, Look tables was 10000, in Rating &#8211; 20000. Number of records in cross tables varies because the linkings are random.<br />
So I came up with normalizing everything like it should be done according to the DB theory.</p>
<p>The only exclusion of this rule is the following situation. In this project you can add different alternatives to the product. Each alternative is &#8220;better&#8221; or &#8220;cheaper&#8221; or &#8220;different&#8221; etc. And since the only case when these alternatives are pulled from DB is when user views the product, they are pulled altogether, so it is better to keep them in the same table.</p>
<h2><a name="conclusion">Conclusion</a></h2>
<ul>
<li>InnoDB turns out to behave better under the high load, it supports transactions and maintains constraints. All that helps to develop better and never leave orphan records.</li>
<li>Using normalization techniques you usually get better performance</li>
<li>Create tests and test everything if you are going to do something great <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<h4>Further reading</h4>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Database_normalization">Database Normalization</a></li>
<li><a href="http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/">MySQL Performance Blog</a></li>
</ul>
<p>P.S. I&#8217;m looking forward to see your comments on implementation techniques in the high-loaded websites, your thoughts about the InnoDB vs MyISAM question and anything else you can think of <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d5').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d5" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F&amp;title=Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F&amp;title=Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F&amp;title=Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F&amp;T=Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F&amp;title=Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM" rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F&amp;title=Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM+@+http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F05%2F20%2Fbuilding-high-loaded-portal-innodb-vs-myisam%2F&amp;t=Building+high-loaded+portal+%26%238211%3B+InnoDB+vs+MyISAM" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d5').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d5').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2009/05/20/building-high-loaded-portal-innodb-vs-myisam/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Speeding up Yii or why should you use DB sessions</title>
		<link>http://programmersnotes.info/2009/03/05/speeding-up-yii-or-why-should-you-use-db-sessions/</link>
		<comments>http://programmersnotes.info/2009/03/05/speeding-up-yii-or-why-should-you-use-db-sessions/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 04:02:35 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[production]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[trick]]></category>

		<guid isPermaLink="false">http://programmersnotes.info/?p=135</guid>
		<description><![CDATA[Quick, effective and simple way how to speed up the Yii web application using the DB session storage.


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Yesterday I&#8217;ve read a post on <a target="_blank" href="http://www.thedeveloperday.com/anti-asynchronous-ajax-calls-and-php-sessions/">The Developer&#8217;s Day blog</a>. Then tested this thing in Yii. There is a jQuery in my application, so I created test controller and test action, that only outputted &#8220;Hello, world&#8221; and called it from the firebug console <span id="more-135"></span>like this (I have url rewrite set up):</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">$.<span class="me1">ajax</span><span class="br0">&#40;</span><span class="br0">&#123;</span>url:<span class="st0">&#8216;/test/test.html&#8217;</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">$.<span class="me1">ajax</span><span class="br0">&#40;</span><span class="br0">&#123;</span>url:<span class="st0">&#8216;/test/test.html&#8217;</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">$.<span class="me1">ajax</span><span class="br0">&#40;</span><span class="br0">&#123;</span>url:<span class="st0">&#8216;/test/test.html&#8217;</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">$.<span class="me1">ajax</span><span class="br0">&#40;</span><span class="br0">&#123;</span>url:<span class="st0">&#8216;/test/test.html&#8217;</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">$.<span class="me1">ajax</span><span class="br0">&#40;</span><span class="br0">&#123;</span>url:<span class="st0">&#8216;/test/test.html&#8217;</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">$.<span class="me1">ajax</span><span class="br0">&#40;</span><span class="br0">&#123;</span>url:<span class="st0">&#8216;/test/test.html&#8217;</span><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Yes, really it matters. Each call starts after the previous one ends and it takes long to finish them all. But each web application handles the concurrent requests by nature. So I started a <a target="_blank" href="http://www.yiiframework.com/forum/index.php/topic,1001.0.html">forum thread</a> to clarify this. And <a target="_blank" href="http://www.yiiframework.com/forum/index.php?action=profile;u=54">sebas</a> recommended me to use CDbHttpSession instead of standard one. Yes, I knew, that storing sessions in DB speeds up the application, but I thought that is because of more effective search. And it turns out, that besides more effective search it gives one more DB benefit &#8211; concurrent access to the session storage. That&#8217;s actually the reason #1 why we usually use databases instead of files <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
So here is a quick trick, that solves the problem:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// application components</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;components&#8217;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&#8230;&#8230;&#8230;.</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;session&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;class&#8217;</span> =&gt; <span class="st0">&#8216;system.web.CDbHttpSession&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;connectionID&#8217;</span> =&gt; <span class="st0">&#8216;db&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>It creates a new table YiiSession and uses it for session data. This time the JS test above runs much faster. Try it yourself!</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d135').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d135" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F&amp;title=Speeding+up+Yii+or+why+should+you+use+DB+sessions" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F&amp;title=Speeding+up+Yii+or+why+should+you+use+DB+sessions" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F&amp;title=Speeding+up+Yii+or+why+should+you+use+DB+sessions" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F&amp;T=Speeding+up+Yii+or+why+should+you+use+DB+sessions" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F&amp;title=Speeding+up+Yii+or+why+should+you+use+DB+sessions" rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F&amp;title=Speeding+up+Yii+or+why+should+you+use+DB+sessions" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Speeding+up+Yii+or+why+should+you+use+DB+sessions+@+http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F05%2Fspeeding-up-yii-or-why-should-you-use-db-sessions%2F&amp;t=Speeding+up+Yii+or+why+should+you+use+DB+sessions" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d135').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d135').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2009/03/05/speeding-up-yii-or-why-should-you-use-db-sessions/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Handling Application Parameters in Yii &#8211; Using the Database</title>
		<link>http://programmersnotes.info/2009/03/04/handling-application-parameters-in-yii-using-the-database/</link>
		<comments>http://programmersnotes.info/2009/03/04/handling-application-parameters-in-yii-using-the-database/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 09:48:22 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[tip]]></category>
		<category><![CDATA[trick]]></category>

		<guid isPermaLink="false">http://programmersnotes.info/?p=129</guid>
		<description><![CDATA[Overview of the standard Yii solution for storing application parameters and proposing custom way to do it using DB


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h2><a name="problem">The problem</a></h2>
<p>Nearly every large application has some configuration parameters &#8211; site admin email, cache time for different blocks, number of latest news, number of items per search or catalogue page etc. </p>
<p><span id="more-129"></span></p>
<h2><a name="standard-way">Standard Way</a></h2>
<p>Yii comes with the built-in mechanism for this. You can create a file with an associative array of all your variables, like this:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">&lt;?php</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">return</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;brandNew&#8217;</span> =&gt; <span class="nu0">7</span>, <span class="co1">// number of days to consider new</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;onSale&#8217;</span> =&gt; <span class="nu0">7</span>, <span class="co1">// number of days to consider on sale</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;favourites&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;max&#8217;</span> =&gt; <span class="nu0">9</span><span class="co1">//max number of last favourites to show</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;search&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;itemsPerPage&#8217;</span> =&gt; <span class="nu0">20</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;tagsInFilter&#8217;</span> =&gt; <span class="nu0">30</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;product&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;maxAlts&#8217;</span> =&gt; <span class="nu0">5</span>, <span class="co1">//max alternatives</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;cacheTime&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;assets&#8217;</span> =&gt; <span class="nu0">1800</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">?&gt;</span></div>
</li>
</ol>
</div>
<p>Then put it somewhere, for example in /protected/config/params.php and configure your application to use it:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">return</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// application components</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;components&#8217;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//components go here</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// application-level parameters that can be accessed</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// using Yii::app()-&gt;params['paramName']</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;params&#8217;</span>=&gt;include<span class="br0">&#40;</span><a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span>.<span class="st0">&#8216;/params.php&#8217;</span><span class="br0">&#41;</span>,<span class="co1">//&lt;&#8211; here is our file</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Usage is simple, just refer to it as to array:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">params</span><span class="br0">&#91;</span><span class="st0">&#8216;siteAdmin&#8217;</span><span class="br0">&#93;</span>;</div>
</li>
</ol>
</div>
<p>This is quite convenient when you just want to save some constants. End-user will not be able to change this from admin in any way. Sure, you can create the interface for editing this config and update the file, but much more flexible way is to store the configuration in DB.</p>
<h2><a name="db-way">The Database Way</a></h2>
<p>To make the life easier, I&#8217;ve created an extension, that can be used as an application component. Extension can be downloaded from the <a target="_blank" href="http://www.yiiframework.com/extension/dbparam/">Yii extension page</a>. Here I&#8217;ll give an overview of it&#8217;s work.</p>
<p>First thing to note, it implements IApplicationComponent, so it should implement init() method where initialization is performed. In this method we check if there are any parameters to load. If so &#8211; we try to load them. If there is an exception, it means, that no table is present, so we create it and initialize the parameters that should be preloaded with null values</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Initializes component, creates table if it doesn&#8217;t exist and populates preloaded attributes</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @throws CException Throws exception if table does not exist and auto creation is set to false</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw2">public</span> <span class="kw2">function</span> init<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;_init = <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDbConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">preload</span> = <span class="re0">$this</span>-&gt;<span class="me1">preprocessParams</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">preload</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<a href="http://www.php.net/empty"><span class="kw3">empty</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">preload</span><span class="br0">&#41;</span> || <span class="re0">$this</span>-&gt;<span class="me1">autoLoad</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> = <span class="st0">&#8216;SELECT name, value FROM &#8216;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">preload</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> .= <span class="st0">&#8216; WHERE name IN (<span class="es0">\&#8217;</span>&#8216;</span>.<a href="http://www.php.net/implode"><span class="kw3">implode</span></a><span class="br0">&#40;</span><span class="st0">&#8216;<span class="es0">\&#8217;</span>,<span class="es0">\&#8217;</span>&#8216;</span>, <span class="re0">$this</span>-&gt;<span class="me1">preload</span><span class="br0">&#41;</span>.<span class="st0">&#8216;<span class="es0">\&#8217;</span>)&#8217;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span> = <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$reader</span> = <span class="re0">$cmd</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$reader</span> <span class="kw1">as</span> <span class="re0">$row</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$row</span><span class="br0">&#91;</span><span class="st0">&#8216;name&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$row</span><span class="br0">&#91;</span><span class="st0">&#8216;value&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch <span class="br0">&#40;</span>CException <span class="re0">$e</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//table is not present</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$createTable</span> = <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//if there is no table, then attributes are empty.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span> = <span class="nu0">0</span>, <span class="re0">$s</span> = <a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">preload</span><span class="br0">&#41;</span>; <span class="re0">$i</span> &lt; <span class="re0">$s</span>; <span class="re0">$i</span>++<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">preload</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span>, <span class="kw2">null</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//check if table exist</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="st0">&#8216;SHOW TABLES LIKE <span class="es0">\&#8217;</span>&#8216;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216;<span class="es0">\&#8217;</span>&#8216;</span><span class="br0">&#41;</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">rowCount</span> &lt;= <span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$createTable</span> = <span class="kw2">true</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$createTable</span> === <span class="kw2">true</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">autoCreateParamsTable</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">createParamsTable</span><span class="br0">&#40;</span><span class="re0">$db</span>,<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> CException<span class="br0">&#40;</span>Yii::<span class="me2">t</span><span class="br0">&#40;</span><span class="st0">&#8216;xparam&#8217;</span>,<span class="st0">&#8216;Params table &quot;{tableName}&quot; does not exist.&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;{tableName}&#8217;</span>=&gt;<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>If parameter is requested, in the __get() method we reuse the parent&#8217;s (CAttributesCollection) <strong>contains()</strong> method, which checks if we have this parameter in the collection already. If so &#8211; we simply return it. If not &#8211; we call the <strong>loadParam()</strong> method, it loads if from DB and adds to the component collection. If there is no attribute, it throws an exception. We catch it in the <strong>__get()</strong> and call the <strong>parent::__get()</strong>. Here is the code:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Returns a property value or an event handler list by property or event name.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* This method overrides the parent implementation by returning</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* a parameter value if the it exist in the collection or loading it from DB</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* if not.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @param string the property name or the event name</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @return mixed the property value or the event handler list</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @throws CException if the property/event is not defined.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> __get<span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">contains</span><span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">itemAt</span><span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$this</span>-&gt;<span class="me1">loadParam</span><span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch <span class="br0">&#40;</span>CException <span class="re0">$e</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> parent::__get<span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Returns parameter from DB or cache if it was requested earlier</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @param string $name</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1">protected <span class="kw2">function</span> loadParam<span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">caseSensitive</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$name</span> = <a href="http://www.php.net/strtolower"><span class="kw3">strtolower</span></a><span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDbConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$res</span> = <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="st0">&#8216;SELECT value FROM &#8216;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216; WHERE name=<span class="es0">\&#8217;</span>&#8216;</span>.<span class="re0">$name</span>.<span class="st0">&#8216;<span class="es0">\&#8217;</span>&#8216;</span><span class="br0">&#41;</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$res</span>-&gt;<span class="me1">rowCount</span> == <span class="nu0">1</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$row</span> = <span class="re0">$res</span>-&gt;<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$name</span>,<span class="re0">$row</span><span class="br0">&#91;</span><span class="st0">&#8216;value&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$row</span><span class="br0">&#91;</span><span class="st0">&#8216;value&#8217;</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> CException<span class="br0">&#40;</span>Yii::<span class="me2">t</span><span class="br0">&#40;</span><span class="st0">&#8216;xparam&#8217;</span>,<span class="st0">&#8216;XDbParam-&gt;{name} does not exist!&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;{name}&#8217;</span>=&gt;<span class="re0">$name</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Setter method simply updates the collection. We check if the parameter is already present in DB. If so &#8211; we update it. If not &#8211; we create it. And, if everything was OK, we add the parameter to the internal collection (<strong>$this->add($name,$value)</strong>):</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Sets value of a component property.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* This method overrides the parent implementation by adding a new param</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* value to the collection and updating the DB.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* @param string the property name or event name</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @param mixed the property value or event handler</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @throws CException If the property is not defined or read-only.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> __set<span class="br0">&#40;</span><span class="re0">$name</span>,<span class="re0">$value</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">caseSensitive</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$name</span> = <a href="http://www.php.net/strtolower"><span class="kw3">strtolower</span></a><span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDbConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="st0">&#8216;SELECT name FROM &#8216;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216; WHERE name=<span class="es0">\&#8217;</span>&#8216;</span>.<span class="re0">$name</span>.<span class="st0">&#8216;<span class="es0">\&#8217;</span>&#8216;</span><span class="br0">&#41;</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">rowCount</span> &gt;= <span class="nu0">1</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> = <span class="st0">&#8216;UPDATE `&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216;` SET `value`=:value WHERE `name`=:name&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span> = <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:value&#8217;</span>, <span class="re0">$value</span>, PDO::<span class="me2">PARAM_LOB</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:name&#8217;</span>, <span class="re0">$name</span>, PDO::<span class="me2">PARAM_STR</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> = <span class="st0">&#8216;INSERT INTO `&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216;`(name, value) VALUES(:name, :value)&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span> = <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:name&#8217;</span>, <span class="re0">$name</span>, PDO::<span class="me2">PARAM_STR</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:value&#8217;</span>, <span class="re0">$value</span>, PDO::<span class="me2">PARAM_LOB</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$name</span>,<span class="re0">$value</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>When configuring the extension or using load() or purge() method, we can specify parameters either as array or as comma-separated string. This is achieved by the preprocessing method, which also converts parameter names to lowercase and they are case insensitive (if this is required by the caseSensitive property, it must be set to true). Here is it:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Sets value of a component property.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* This method overrides the parent implementation by adding a new param</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* value to the collection and updating the DB.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* @param string the property name or event name</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @param mixed the property value or event handler</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @throws CException If the property is not defined or read-only.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> __set<span class="br0">&#40;</span><span class="re0">$name</span>,<span class="re0">$value</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span>-&gt;<span class="me1">caseSensitive</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$name</span> = <a href="http://www.php.net/strtolower"><span class="kw3">strtolower</span></a><span class="br0">&#40;</span><span class="re0">$name</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDbConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="st0">&#8216;SELECT name FROM &#8216;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216; WHERE name=<span class="es0">\&#8217;</span>&#8216;</span>.<span class="re0">$name</span>.<span class="st0">&#8216;<span class="es0">\&#8217;</span>&#8216;</span><span class="br0">&#41;</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">rowCount</span> &gt;= <span class="nu0">1</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> = <span class="st0">&#8216;UPDATE `&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216;` SET `value`=:value WHERE `name`=:name&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span> = <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:value&#8217;</span>, <span class="re0">$value</span>, PDO::<span class="me2">PARAM_LOB</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:name&#8217;</span>, <span class="re0">$name</span>, PDO::<span class="me2">PARAM_STR</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> = <span class="st0">&#8216;INSERT INTO `&#8217;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>.<span class="st0">&#8216;`(name, value) VALUES(:name, :value)&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span> = <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:name&#8217;</span>, <span class="re0">$name</span>, PDO::<span class="me2">PARAM_STR</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">bindValue</span><span class="br0">&#40;</span><span class="st0">&#8216;:value&#8217;</span>, <span class="re0">$value</span>, PDO::<span class="me2">PARAM_LOB</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span>-&gt;<span class="me1">execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$name</span>,<span class="re0">$value</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>And, finally, load and purge methods:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Loads several params from DB at once. If nothing specified, all parameters</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* are loaded. This saves queries if you plan to use all that params in the</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* next lines.</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @param array|string $params</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* @throws CException</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw2">public</span> <span class="kw2">function</span> load<span class="br0">&#40;</span><span class="re0">$params</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$params</span> = <span class="re0">$this</span>-&gt;<span class="me1">preprocessParams</span><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDbConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> = <span class="st0">&#8216;SELECT name, value FROM &#8216;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> .= <span class="st0">&#8216;WHERE name IN (<span class="es0">\&#8217;</span>&#8216;</span>.<a href="http://www.php.net/implode"><span class="kw3">implode</span></a><span class="br0">&#40;</span><span class="st0">&#8216;<span class="es0">\&#8217;</span>,<span class="es0">\&#8217;</span>&#8216;</span>, <span class="re0">$params</span><span class="br0">&#41;</span>.<span class="st0">&#8216;<span class="es0">\&#8217;</span>)&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$cmd</span> = <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$reader</span> = <span class="re0">$cmd</span>-&gt;<span class="me1">query</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$reader</span> <span class="kw1">as</span> <span class="re0">$row</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$row</span><span class="br0">&#91;</span><span class="st0">&#8216;name&#8217;</span><span class="br0">&#93;</span>, <span class="re0">$row</span><span class="br0">&#91;</span><span class="st0">&#8216;value&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$loaded</span>++;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$loaded</span> &lt; <a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="co1">//this will not be thrown if loading all attributes</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> CException<span class="br0">&#40;</span>Yii::<span class="me2">t</span><span class="br0">&#40;</span><span class="st0">&#8216;xparam&#8217;</span>,<span class="st0">&#8216;Some of the requested params do not exist!&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">/**</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;* Deletes specified params (or all params if none specified) from the parameters table</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*</span></div>
</li>
<li class="li2">
<div class="de2"><span class="coMULTI">&nbsp;* @param array|string $params Comma-separated list of params or array of param names</span></div>
</li>
<li class="li1">
<div class="de1"><span class="coMULTI">&nbsp;*/</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">public</span> <span class="kw2">function</span> purge<span class="br0">&#40;</span><span class="re0">$params</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> = <span class="st0">&#8216;DELETE FROM &#8216;</span>.<span class="re0">$this</span>-&gt;<span class="me1">paramsTableName</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$params</span> = <span class="re0">$this</span>-&gt;<span class="me1">preprocessParams</span><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$sql</span> .= <span class="st0">&#8216; WHERE name IN (<span class="es0">\&#8217;</span>&#8216;</span>.<a href="http://www.php.net/implode"><span class="kw3">implode</span></a><span class="br0">&#40;</span><span class="st0">&#8216;<span class="es0">\&#8217;</span>,<span class="es0">\&#8217;</span>&#8216;</span>, <span class="re0">$params</span><span class="br0">&#41;</span>.<span class="st0">&#8216;<span class="es0">\&#8217;</span>)&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db</span> = <span class="re0">$this</span>-&gt;<span class="me1">getDbConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$db</span>-&gt;<span class="me1">createCommand</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span>-&gt;<span class="me1">execute</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span> &gt; <span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span> = <span class="nu0">0</span>, <span class="re0">$s</span> = <a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#41;</span>; <span class="re0">$i</span> &lt; <span class="re0">$s</span>; <span class="re0">$i</span>++<span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">remove</span><span class="br0">&#40;</span><span class="re0">$params</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">clear</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<h2><a name="usage">Usage Instructions</a></h2>
<p>Using the extension is simple. Like any extension, you should unzip it to the /protected/extensions/ folder and then set it up as an application component. To do this, you should add it with any name to the components array in the application configuration:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="st0">&#8216;par&#8217;</span>=&gt;array<span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;class&#8217;</span> =&gt; <span class="st0">&#8216;application.extensions.dbparam.XDbParam&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;connectionID&#8217;</span> =&gt; <span class="st0">&#8216;db&#8217;</span>,<span class="co1">//id of the connection component, just the same as with CDbCache</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// &nbsp;&#8217;preload&#8217; =&gt; &#8216;test,test2&#8242;, //comma-separated string or array of params to be loaded anyway. Other params are loaded only when requested.</span></div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// &nbsp;&#8217;autoLoad&#8217; =&gt; true, //setting to true enables loading of all attributes present in DB in the beginning</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// &nbsp;&#8217;caseSensitive&#8217; =&gt; true, //setting to true makes all parameters case sensitive</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>,</div>
</li>
</ol>
</div>
<p>&#8216;par&#8217; is the ID of the component, you will refer to it in any place of the application by it&#8217;s ID:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">test</span> = <span class="st0">&#8217;1234&#8242;</span>;<span class="co1">//set parameter. If it is not present, it will be created</span></div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/echo"><span class="kw3">echo</span></a> Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">test</span>;<span class="co1">//output parameter. If it is not present, exception is thrown</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co1">//load several parameters in one query. Useful if you;re going to use them in the next lines</span></div>
</li>
<li class="li1">
<div class="de1">Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">load</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;test&#8217;</span>, <span class="st0">&#8216;test2&#8242;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//OR</span></div>
</li>
<li class="li1">
<div class="de1">Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&#8216;test,test2&#8242;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//OR</span></div>
</li>
<li class="li2">
<div class="de2">Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">load</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span class="co1">//load all parameters</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//delete the specified parameters or all of them if none specified</span></div>
</li>
<li class="li1">
<div class="de1">Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">purge</span><span class="br0">&#40;</span><span class="st0">&#8216;test,test2&#8242;</span><span class="br0">&#41;</span>;<span class="co1">//delete test and test 2</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//OR</span></div>
</li>
<li class="li2">
<div class="de2">Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">purge</span><span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;test&#8217;</span>, <span class="st0">&#8216;test3&#8242;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<span class="co1">//delete test and test 3</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">//OR</span></div>
</li>
<li class="li1">
<div class="de1">Yii::<span class="me2">app</span><span class="br0">&#40;</span><span class="br0">&#41;</span>-&gt;<span class="me1">par</span>-&gt;<span class="me1">purge</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<span class="co1">//delete ALL parameters!</span></div>
</li>
</ol>
</div>
<p>That&#8217;s it! Enjoy!</p>
<p><strong>UPDATE:</strong> Updated on March, 5 2009 according to the <a target="_blank" href="http://php-thoughts.cubedwater.com/">Jonah&#8217;s</a> comments an this <a target="_blank" href="http://www.yiiframework.com/forum/index.php/topic,993.0.html">discussion</a>. Version 3 is planned with great functionality <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d129').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d129" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F&amp;title=Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F&amp;title=Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F&amp;title=Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F&amp;T=Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F&amp;title=Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database" rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F&amp;title=Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database+@+http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F04%2Fhandling-application-parameters-in-yii-using-the-database%2F&amp;t=Handling+Application+Parameters+in+Yii+%26%238211%3B+Using+the+Database" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d129').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d129').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2009/03/04/handling-application-parameters-in-yii-using-the-database/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>MySQL Workbench &#8211; The Database Modeling Tool for MySQL</title>
		<link>http://programmersnotes.info/2009/03/01/mysql-workbench-the-database-modeling-tool-for-mysql/</link>
		<comments>http://programmersnotes.info/2009/03/01/mysql-workbench-the-database-modeling-tool-for-mysql/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 05:42:13 +0000</pubDate>
		<dc:creator>Konstantin Mirin</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[database design]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[modelling]]></category>

		<guid isPermaLink="false">http://programmersnotes.info/?p=80</guid>
		<description><![CDATA[MySQL Workbench review based on my own usage experience. Pros and cons of the tool.


No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h2>The history</h2>
<p>In December I&#8217;ve got a project, that required sophisticated and quite complex DB and that DB was subject to change greatly during first development phase. Before that project I was using <a target="_blank" href="http://www.sparxsystems.com.au/">Sparx Enterprise Architect</a> both for application design and DB design. But, frankly speaking, it&#8217;s not good at databases, especially MySQL. So I decided to pick up a new DB modelling tool.<br />
<span id="more-80"></span></p>
<h2>Requirements</h2>
<p>My requirements to it were:</p>
<ul>
<li><strong>Convenient entering</strong> of the attributes and their types. When I have an idea, I want it to be recorded fast, I don&#8217;t want to spend time clicking different &#8220;add&#8221; and &#8220;save&#8221; buttons in order to enter table attributes</li>
<li><strong>Full MySQL features</strong> (including all types of indexes) and main storage engines support (MyISAM, InnoDB, MEMORY)</li>
<li><strong>Visual tables layout</strong> like in MS Access</li>
<li><strong>Maintaining table joins</strong> and involved indexes, visual creation of table connections</li>
<li><strong>SQL export</strong></li>
<li><strong>Free!</strong></li>
</ul>
<h2>On the way to perfection&#8230;</h2>
<p>I went through <a target="_blank" href="http://www.databaseanswers.org/modelling_tools.htm">this list</a> and installed and tried around 10 different tools and I didn&#8217;t like any of them. One has no visual modelling, other has inconvenient input, third has both, but doesn&#8217;t support a number of MySQL features. So finally I ended up with <a target="_blank" href="http://dev.mysql.com/workbench/">MySQL Workbench</a>. It gives me all I need and even more.</p>
<h2>Yes! It&#8217;s really perfect <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </h2>
<p><a target="_blank" href="http://dev.mysql.com/workbench/?page_id=11">Here</a> you may find a list of features together with versions comparison. You can read it yourself and I want to describe why I liked it:</p>
<h3>Nice design</h3>
<p>Yes, it matters. When you use Windows95-like program, you can&#8217;t feel as good as if you&#8217;re using excellent-designed one. Here is a screen:<br />
<div id="attachment_82" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/02/wb_model_table_editor11.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/02/wb_model_table_editor1-300x238.png" alt="Model Overview" title="Model Overview" width="300" height="238" class="size-medium wp-image-82" /></a><p class="wp-caption-text">Model Overview</p></div></p>
<h3>Creating DB</h3>
<p>I liked their &#8220;schema approach&#8221;. When you create DB, you set the schema default encoding and all the tables in DB are automatically created in this encoding. Sure, you can change it for each table, but this is very helpful. I&#8217;ve also set up mydefault storage engine &#8211; InnoDB (MyISAM is default). This setting can be found in a seconds; everything is in it&#8217;s place (Tools -> Options -> MySQL).<br />
So now I can create my table without remembering that I should change some settings each time I create new table. That&#8217;s my first requirement.</p>
<h3>Creating tables</h3>
<p>I liked their template approach to the generic field names. Near every table has ID field. In my name conventions (since I&#8217;m using Yii framework, I follow their), ID field name is [tableName]ID. So I go to the Tools -> Options -> Model and set there:</p>
<ul>
<li>Primary key pattern &#8211; %table%ID</li>
<li>Primary key default type &#8211; INT(11)</li>
<li>Foreign key defaults (since I&#8217;m using InnoDB, which takes care of data integrity, I set this. I&#8217;ll tell more about this in my future posts about MySQL&#038;InnoDB)</li>
</ul>
<p>Three little settings, but it makes my life much more simple! Actually, you can set up the naming of the auto-generated index fields, but I don&#8217;t use it, I create all tables I need myself. However, Workbench can create cross table for Many-to-Many relation for you.<br />
Now I create the table (collation and engine are set automatically), go to the &#8220;fields&#8221; tab (tabs are in the bottom &#8211; I had problems finding them first time) and have my ID field created. Unfortunately, I can&#8217;t say that I want first letter in lower-case, so I correct it manually. Then start adding fields. It is very simple. First you double click on the empty row where should one name of the field, enter your name, press TAB, enter the field type (I usually enter 1-3 letters and press &#8220;Down&#8221; key, it selects correct type), press TAB again and you&#8217;re on the next field! So you just keep populating your attributes really fast! Then just tick NN (not null) and AI (auto increment) checkboxes and your table scheme is done. All indexes are set up on the next tab &#8211; Indexes except PRIMARY KEY. ID field is PRIMARY KEY by default. To add more fields there, select field and tick PRIMARY KEY checkbox in the right part of the tab.</p>
<h3>Visual layout</h3>
<p>Consider we created tables we need, now we advance to the scheme and connections. Double click &#8220;Add Diagram&#8221; in the top of the screen and you&#8217;re there. In the centre of the right pane you have tables you created. If you drag table from that list to your diagram, you&#8217;ll see big dot near it&#8217;s name. That&#8217;s also very convenient when you have a number of tables. Sure, here you can snap to grid, show/hide it, but that&#8217;s not so impressive.</p>
<h3>Visual grouping</h3>
<p>And this feature is mega-great! When you have huge DB, you can group tables using coloured layers:<br />
<div id="attachment_85" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_zoomed_out11.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_zoomed_out1-300x239.png" alt="ER Diagram with coloured layers for grouping" title="ER diagram with layers" width="300" height="239" class="size-medium wp-image-85" /></a><p class="wp-caption-text">ER Diagram with coloured layers for grouping</p></div></p>
<h3>Visual connections</h3>
<p>Yes, it allows you to connect tables like you want. 1-1,1-N and N-M relations. If you prefer to create foreign keys automatically, yo can use these types of joins. I prefer to create all tables and fields and then connect it. So I click on the last icon in the left toolbar, select foreign key, then click &#8220;Pick referenced columns&#8221; and finally select the primary key I link to. I&#8217;m done. All InnoDB connections are automatically created.<br />
<div id="attachment_86" class="wp-caption aligncenter" style="width: 310px"><a href="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_fk_pick_columns11.png"><img src="http://programmersnotes.info/wp-content/uploads/2009/02/wb_diagam_fk_pick_columns1-300x239.png" alt="Creating relationship using existing columns" title="Creating relatinship" width="300" height="239" class="size-medium wp-image-86" /></a><p class="wp-caption-text">Creating relationship using existing columns</p></div></p>
<h3>SQL export</h3>
<p>Sure, SQL export is not new or impressive feature, but MySQL Workbench allows you not only to create SQL for the scheme, but also to create ALTER DB script for the CREATE DB script already created. For example, you designed a great DB, exported to SQL query, installed on server and then your client wants changes. You open MySQL Workbench project, make necessary changes and then create ALTER script. Very convenient thing <img src='http://programmersnotes.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Integration with Yii</h2>
<p>One clever guy (<a target="_blank" href="http://blog.orite.com.au/web_development/2009-02-06/mwbmodelcommand-yii-framework-and-mysql-workbench/">unikly</a>) created the Yii shell command, that allows to use mwb file instead of DB connection when creating Yii DB models. This command is available on the Yii <a target="_blank" href="http://www.yiiframework.com/extension/mwbmodelcommand/">extensions page</a>. As for me, it&#8217;s a very big plus.</p>
<h2>A fly in the ointment</h2>
<p>I&#8217;ve noticed several bad things in this software:</p>
<ul>
<li>When DB becomes huge, you need a good machine to work with it comfortably. It takes too much resources</li>
<li>Some interface elements are not evident (In the DB overview screen lowest part has tabs both on the top and on the bottom. Top tabs &#8211; switch between tables, bottom tabs &#8211; switch between table&#8217;s sections (properties, fields, indexes)</li>
<li>When creating joins, it doesn&#8217;t maintain the uniqueness of foreign indexes names. Take a close look at the export script (and watch for constraints and auto-created foreign keys) when it fails in phpMyAdmin (or other tool)</li>
</ul>
<p>
<strong>Disclaimer:</strong> Screenshots are taken from <a target="_blank" href="http://dev.mysql.com/workbench/?page_id=35">MySQL Workbench</a> site, I was lazy to take my own ones.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a title="Click me to see the sites." href="#" onclick="$$('div.d80').each( function(e) { e.visualEffect('slide_down',{duration:2.5}) }); return false;"><strong><em>Liked the post? Bookmark it</em></strong></a>
<br />
<div class="d80" style="overflow:hidden">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.netscape.com/submit/?U=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;T=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Netscape"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/netscape.png" title="Add to&nbsp;Netscape" alt="Add to&nbsp;Netscape" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://slashdot.org/bookmark.pl?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Slashdot"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/slashdot.png" title="Add to&nbsp;Slashdot" alt="Add to&nbsp;Slashdot" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;title=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL+@+http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http%3A%2F%2Fprogrammersnotes.info%2F2009%2F03%2F01%2Fmysql-workbench-the-database-modeling-tool-for-mysql%2F&amp;t=MySQL+Workbench+%26%238211%3B+The+Database+Modeling+Tool+for+MySQL" rel="nofollow" title="Add to&nbsp;Yahoo My Web"><img class="social_img" src="http://programmersnotes.info/wp-content/plugins/social-bookmarks/images/yahoo.png" title="Add to&nbsp;Yahoo My Web" alt="Add to&nbsp;Yahoo My Web" /></a>
<br />
<a style="font-size:90%;text-align: right; " title="Click me to hide the sites." href="#" onclick="$$('div.d80').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); return false;">Hide Sites</a>
</div>
</div>
<!-- Social Bookmarks END -->
<script type="text/javascript">$$('div.d80').each( function(e) { e.visualEffect('slide_up',{duration:0.5}) }); </script>

<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://programmersnotes.info/2009/03/01/mysql-workbench-the-database-modeling-tool-for-mysql/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

