<?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>Doing better &#187; Uncategorized</title>
	<atom:link href="http://www.longacre-scm.com/blog/index.php/category/uncategorized/feed" rel="self" type="application/rss+xml" />
	<link>http://www.longacre-scm.com/blog</link>
	<description>Opinions on CM, software development, and process automation from Longacre.</description>
	<lastBuildDate>Sat, 28 Aug 2010 21:23:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Add VC &#8220;branch&#8221; to your prompt</title>
		<link>http://www.longacre-scm.com/blog/index.php/2010/03/add-vc-branch-to-your-prompt</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2010/03/add-vc-branch-to-your-prompt#comments</comments>
		<pubDate>Wed, 31 Mar 2010 20:40:18 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/?p=85</guid>
		<description><![CDATA[Inspired by a recent discussion on IRC, here&#8217;s another little piece of bash script goodness. This one goes in your startup files, and it integrates with your $PS1 prompt variable. The script adds your VC branch to the prompt. I&#8217;ve included SVN and GIT, and I&#8217;m sure you could trivially add CVS if need be. [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by a recent discussion on IRC, here&#8217;s another little piece of bash script goodness. This one goes in your startup files, and it integrates with your $PS1 prompt variable. The script adds your VC branch to the prompt. I&#8217;ve included SVN and GIT, and I&#8217;m sure you could trivially add CVS if need be. Other VC tools may not be such a good fit &#8212; in many cases, they encode project info as part of the path, so the standard &#8217;show the working directory&#8217; prompt is enough.</p>
<p>(On the other hand, if you&#8217;ve got one that needs special treatment, drop me a line and I&#8217;ll add it here.)</p>
<p><code>
<pre>
if which git > /dev/null
then
	parse_git_path() {
		if [[ -d .git ]]
		then
			git branch --no-color \
			| sed -rne '/^\*/s/^\* (.*)$/(git:\1) /p'
			return 0
		else
			return 1
		fi
	}
else
	parse_git_path() {
		return 1
	}
fi

if which svn > /dev/null
then
	parse_svn_path() {
		if [[ -d .svn ]]
		then
			local rroot=$(svn info | sed -ne 's/Repository Root: //p')
			svn info 		\
			| sed -rne "s#^URL: $rroot/(trunk|branches/[^/]*).*#(svn:^/\1) #p"
			return 0
		else
			return 1
		fi
	}
else
	parse_svn_path() {
		return 1
	}
fi

parse_vc_path() {
	parse_git_path \
	|| parse_svn_path
}

export PS1="\[\e]0;\$(parse_vc_path)\w\a\]${debian_chroot:+($debian_chroot)}\$(parse_vc_path)\w\$ "
</pre>
<p></code><br />
The key is that bash performs command substitution on PS1 each time it prints it, so you can have whatever command sequence you want get run. In this case, it&#8217;s a script that does whatever processing is needed in order to determine the &#8220;branch&#8221;, if any, that you&#8217;re on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2010/03/add-vc-branch-to-your-prompt/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[wiki &#124; database_cm:three_ways]</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/05/database_cmthree_ways</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/05/database_cmthree_ways#comments</comments>
		<pubDate>Wed, 21 May 2008 14:24:05 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/05/[[database_cm:three_ways]]</guid>
		<description><![CDATA[

Table of Contents



Manual list of changes
Computed list of changes
Longacre Deployment Management




There are three ways to do change or configuration management of a database. Two of them are “traditional,” and the third is LDM. Let&#039;s look at them all.




Manual list of changes



SQL is by its nature a change language. The individual statements in SQL are mostly [...]]]></description>
			<content:encoded><![CDATA[<div class="dokuwiki">
<div class="toc">
<div class="tocheader toctoggle" id="toc__header">Table of Contents</div>
<div id="toc__inside">

<ul class="toc">
<li class="level1"><div class="li"><span class="li"><a href="#manual_list_of_changes" class="toc">Manual list of changes</a></span></div></li>
<li class="level1"><div class="li"><span class="li"><a href="#computed_list_of_changes" class="toc">Computed list of changes</a></span></div></li>
<li class="level1"><div class="li"><span class="li"><a href="#longacre_deployment_management" class="toc">Longacre Deployment Management</a></span></div></li></ul>
</div>
</div>

<p>
There are three ways to do change or configuration management of a database. Two of them are “traditional,” and the third is LDM. Let&#039;s look at them all.
</p>



<h1><a name="manual_list_of_changes" id="manual_list_of_changes">Manual list of changes</a></h1>
<div class="level1">

<p>
<acronym title="Structured Query Language">SQL</acronym> is by its nature a change language. The individual statements in <acronym title="Structured Query Language">SQL</acronym> are mostly focused on changing an existing database. While you use <code>CREATE TABLE</code> at first, every subsequent update will use <code>ALTER TABLE</code>. Manipulating data is done with <code>INSERT</code> and <code>UPDATE</code> commands. To explicitly set the entire contents of a row is an elaborate form of update.   Not surprisingly, the easiest way to track the changes made to your database is by writing down the <acronym title="Structured Query Language">SQL</acronym> statements that get issued to make those changes. If you insert a new column in a table, or change the data type of a column, you will use <code>ALTER TABLE.</code> Writing those statements down in a file is a quick and easy way to keep track of the changes you make. Create a file called <code>update.sql</code> and append the <acronym title="Structured Query Language">SQL</acronym> statements to it one after another.   If you are trying to automate the deployment of these changes, you can protect each database change with a check to make sure the change has not been applied before &ndash; maybe a table of change id numbers. Alternatively, you could force the developers to reset the <code>update.sql</code> to an empty file whenever they start developing. This lets you blindly execute the script, which most of the time will be empty, with each deployment. 
</p>

<p>
The CM system will track database changes by connecting them to the <code>update.sql</code> file, or however you store update scripts. The deployment process will operate by fetching successive versions of the update script, or iterating through an ordered list of update file names, until the target configuration is reached. 
</p>

<p>
Because the update scripts are generated based on the actual commands executed, this approach allows the updates to be split up or merged together when needed. In cases where a roll-back script is needed, recording the sequence of changes makes coding the reversion easier (which is not to say &#039;easy&#039;). 
</p>

<p>
Tracking the updates does not, obviously, track the overall state of the database. When a /baseline/ is needed, some extra action will be required to produce a single set of scripts that generate the baseline configuration.
</p>

</div>
<!-- SECTION "Manual list of changes" [156-2296] -->
<h1><a name="computed_list_of_changes" id="computed_list_of_changes">Computed list of changes</a></h1>
<div class="level1">

<p>
   At the extreme other end of the spectrum, there are tools that can compare live database schemas with other schemas, or the <acronym title="Structured Query Language">SQL</acronym> scripts that would create them. You can use these tools by establishing a rigorous standard for storing <acronym title="Structured Query Language">SQL</acronym> scripts as part of your source code, so that for each object type (trigger, stored procedure, table, index, constraint, etc.) in the system, the mapping from entity to script is mechanically computable. Once all changes to the database (for a given work item) have been made, the tool is used to compare the “pre-” and “post-” images, and generate some <acronym title="Structured Query Language">SQL</acronym> code that maps one to the other.
</p>

<p>
If the tool supports comparing <acronym title="Structured Query Language">SQL</acronym> scripts, or comparing a live database against a set of scripts, then the comparison will match the live database against a set of checked-in scripts for generating the previous version of the schema. If the tool requires comparing two databases, you will have to devise a clever work-around. 
</p>

<p>
Automating deployment of the changes will require either computing the differences and storing them (as in the case above) or comparing the live state of the deployment target with the required state associated with the change and automatically synchronizing the two. I don&#039;t know of a tool that directly supports monitoring data changes in addition to schema changes. This can jeopardize the entire implementation. It is best if this approach is not used when the project involves a significant amount of metadata (business logic or other program data stored as table date).
</p>

<p>
Because the update scripts are generated mechanically by comparing the entire state of the database, before and after, there is little support for splitting up or merging two change sets. These operations will have to involve inspecting the generated update scripts and merging or reversing them from the development database. Splitting up a change set into two or more smaller units will therefore tend to lose data, unless the database configuration is saved away before you begin. Depending on the capability of the tool, it may or may not be possible to simply generate roll-back scripts for simple cases. Complex cases will always require hand coding. The mechanical approach may be configured to generate an empty roll-back section, which would be filled in by hand.
</p>

<p>
Because this development approach is based on extracting the entire state of the database, generating a single unified script to recreate the database at a given baseline will be trivial.
</p>

</div>
<!-- SECTION "Computed list of changes" [2297-4834] -->
<h1><a name="longacre_deployment_management" id="longacre_deployment_management">Longacre Deployment Management</a></h1>
<div class="level1">

<p>
Longacre Deployment Management (LDM) views all development in the context of deployment operations. Development activities produce updates to be applied against a particular target. This is exactly in accord with <acronym title="Structured Query Language">SQL</acronym>, as described above. While source code tracking tools focus on explicitly replacing one version with another version, LDM abstracts the version selection activity as a “workspace update” operation. The result, from an LDM point of view, is that there are two kinds of activities: workspace update and database update. 
</p>

<p>
LDM assumes the ability to extract <acronym title="Structured Query Language">SQL</acronym> update scripts. The mechanics of this are up to you to implement, depending on the tools you are using. The resulting updates are exported as part of a “bundle,” along with a list of the workspace change sets that must be applied. Each bundle is archived, of course. But bundles cannot be modified&ndash;they are products. If a developer finds a bug in her work, she must deliver a different change set (or <acronym title="Structured Query Language">SQL</acronym> update) in a later bundle to fix it.    Once a bundle is archived, it can be applied at any time to any target platform. The act of deploying a bundle to a target creates a deployment record object. The deployment records connect bundles with locations, while the bundles serve as a link into the change request/task/work item part of the repository. Traversing the graph from either end provides the answers to the questions “which servers have received this update” (Change Request &rarr; Tasks &rarr; Bundles &rarr; Deployment &rarr; Location) and “what changes are deployed to this server?” (Location &rarr; Deployment &rarr; Bundles &rarr; Task &rarr; Change Request)   The low-level mechanics of LDM are closer to the “manual list of changes” approach than to the “computed list of changes.” At the high level, LDM simply uses a different paradigm. There is no notion of “roll back”. If a change is made in error, the LDM approach is to keep running and deliver a new change that fixes the problem(s) caused by the erroneous change.    
</p>

</div>
<!-- SECTION "Longacre Deployment Management" [4835-] -->
<!-- cachefile /home/ahasting/public_html/wiki/data/cache/b/b0ba39c1c41a8bb568ff04df4439e03f.xhtml used -->

</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/05/database_cmthree_ways/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[wiki &#124; database_cm]</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/05/database_cm</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/05/database_cm#comments</comments>
		<pubDate>Wed, 21 May 2008 14:18:57 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/05/[[database_cm]]</guid>
		<description><![CDATA[



Database Change Management



Database CM, like software CM, means different things to different people. From our perspective, though, it is about providing the same benefits to a development shop that SCM does, even when some or all of the development involves a database. Database CM is just SCM on a database, if you will.   [...]]]></description>
			<content:encoded><![CDATA[<div class="dokuwiki">



<h1><a name="database_change_management" id="database_change_management">Database Change Management</a></h1>
<div class="level1">

<p>
Database CM, like software CM, means different things to different people. From our perspective, though, it is about providing the same benefits to a development shop that SCM does, even when some or all of the development involves a database. Database CM is just SCM on a database, if you will.   Unfortunately, “SCM on a database” is damn hard. Hard enough, in fact, that there are a bunch of tools, free and commercial, trying to get a handle on it.
</p>

<p>
Most people haven&#039;t “got it” yet, though. Database CM is what inspired the creation of Longacre Deployment Management (an DBCM/SCM technique).
</p>

<p>
There are various ways to do database change management. Here&#039;s one take: <a href="/wiki/doku.php/database_cm/three_ways" class="wikilink1" title="database_cm:three_ways">Database CM three ways</a> 
</p>

</div>

<!-- cachefile /home/ahasting/public_html/wiki/data/cache/6/61706876182f0a67eafc0dbf634a9298.xhtml used -->

</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/05/database_cm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Pattern: Table Data Gateway</title>
		<link>http://www.longacre-scm.com/blog/index.php/2006/02/design-pattern-table-data-gateway</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2006/02/design-pattern-table-data-gateway#comments</comments>
		<pubDate>Wed, 22 Feb 2006 23:51:11 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.longacre-inc.com/blog/?p=13</guid>
		<description><![CDATA[A table data gateway is a gateway?an interface to a separate component or subsystem?that provides access to its data by abstracting an entire database table (or entire file, or entire tree, or entire other data structure) behind a single interface object. All of the standard CRUD operations are performed by accessing methods of the table [...]]]></description>
			<content:encoded><![CDATA[<p>A table data gateway is a gateway?an interface to a separate component or subsystem?that provides access to its data by abstracting an entire database table (or entire file, or entire tree, or entire other data structure) behind a single interface object. All of the standard CRUD operations are performed by accessing methods of the table data gateway. For SQL data stores, table data gateway methods correspond directly to SQL statements: DELETE, INSERT, SELECT, UPDATE. The method arguments are mapped into SQL statements directly. In general, table data gateway will provide all methods for accessing the data store, including <em>Finder Methods. </em>If complex query statements are needed, table data gateway may accept attribute/value pairs and construct a ?generic query? internally.</p>
<p><img src='http://www.longacre-scm.com/blog/wp-content/uploads/2008/04/tabledatagateway.PNG' alt='Table Data Gateway class diagram' /></p>
<p><span id="more-13"></span><br />
The key distinction between table data gateway and a <em>Row Data Gateway </em>is that a table gateway encapsulates the <em>entire data structure </em>behind a single object or class, while a row gateway encapsulates a <em>single entry </em>behind one instance of the gateway object. When the application is dealing with only one object at a time, the two are very similar. However where a row data gateway may use a separate <em>Finder </em>class or method, a table data gateway will provide the lookup method itself. </p>
<p>The difference between table data gateway and <em>Table Module </em>is that a table data  gateway contains no business logic. Table modules are expected to contain business and/or application logic, as well as data access. </p>
<p>Applications commonly need access to only one object of a given class at a time, or to the results of aggregate functions (COUNT, SUM, etc.) provided by the database system. This is the interface provided by a table data gateway. </p>
<p>Table data gateway provides only a single point of access to the data store. Because of this, it is nearly impossible to implement this pattern in a stateful manner. Table data gateway should not try to track state, or to remember data between calls. Dealing with lists of values is challenging, especially if using a cursor or other database-specific, stateful entity. In these cases it is particularly important to remove the statefulness from the pattern. </p>
<p><em>Record Set, </em>or some other pattern that can extract the entire list from the table in a single logical interaction, is an important partner. Even with record set to resolve the stateful nature of list traversal, table data gateway operations are performed one at a time.</p>
<p>Table data gateway is particularly usable when the access code is template-based or automatically generated. Implementing record sets then becomes a matter of storing a link to the appropriate gateway object with the record data. For many applications, a single table data gateway class can be used for all data access.  Because PHP uses hashes as a core data type, an array of key/value pairs makes good sense. </p>
<p>Fowler does some hand-wringing in (PoEAA) bemoaning the various ways that table data gateway can lose compile-time type checking if they return generic objects like maps. This is more a problem with Java than with the table data gateway pattern, and obviously any pattern that needs to return aggregate data structures will have the same risk. (In C++, for example, you could create a template gateway class and instantiate a different class to get different return types. But that&#8217;s an awful lot of work for not much reward.)</p>
<p><strong>Indications</strong></p>
<p>In general, use table data gateway. This is the simplest of the interface patterns. It is more stable than row data gateway, since there is little or no tendency to ?drift.? It is amenable to machine-generated code, and fairly easy to implement by hand. For simple applications, a single class can serve as the gateway for all data tables.</p>
<p>When application data is not totally table-oriented (as in the example application), or when a single table may store values for multiple different purposes (see <em>Class- </em>and <em>Single- Table Inheritance, </em>below, for examples), table data gateway is challenged. Implementation is still possible, however, if some external mechanism is available for disambiguation. In the case of single table inheritance, for example, the gateway could return all field values (including some NULL values) to a factory (virtual constructor) that constructed and returned appropriate objects.</p>
<p>In general, use the ?iterator test? to determine the suitability of this pattern for your application: if all operations involving the data can be implemented using iterators (one-at-a-time access), then table data gateway is a viable pattern.</p>
<p><strong>Contraindications</strong></p>
<p>Avoid using table data gateway if the ?iterator test? fails. If the application requires access to multiple objects of the same class simultaneously, or if the application requires that objects be related to each other in a complex fashion (such as a tree or graph structure) then table data gateway may not be appropriate.</p>
<p>Of course, in-memory representation of the objects is possible, with table data gateway providing marshalling services and no more. But failure of the iterator test is a good indicator that <em>some </em>thought about the data layer is needed.</p>
<p>Beware of data models that store relationships between objects in separate tables. Having to use two or more different data gateways to get or set relationship data is likely to cause problems. In this scenario a more ?domain aware? pattern is probably indicated: consider active record or an object/relational mapper.</p>
<p>As with row data gateway, using a table data gateway can mean distributing the application&#8217;s data model through many separate classes. This will cause headaches when updating the code unless you are careful. For most data gateways it is possible to centralize the access code using composition (has-a) or inheritance (is-a) with a single core gateway class.</p>
<p><strong>Example</strong></p>
<p><code><br />
// IOU: A big mess o' PHP code<br />
</code></p>
<p><strong>Notes</strong></p>
<p>Both <em>Data Mappers </em>and table modules can be built on top of table data gateway classes, especially when the gateway classes are standardized. Using automatic code generation, or using a single core class with table-specific instances, or using database metadata to extract table details, can provide a simplified data layer interface so that your mapper or table module consists of nothing but object or application logic, respectively.</p>
<p>In particular, as Fowler points out in (PoEAA:146), a table data gateway can be implemented using stored procedures in SQL. In this scenario, every application, regardless of language, can share the same semantics for data layer access. The PHP (or other language) interface then becomes a mechanical translation of function arguments into SQL stored procedure arguments. </p>
<p>Finally, it bears repeating that table data gateway classes need to be stateless. Trying to write a gateway class so that one call to the class ?sets up? data to be used by a later call is a recipe for disaster. Because a table data gateway is such a simple interface, any complexity will <em>have </em>to come from the application. When the application tries a complex series of operations involving two or more different records, it will fail miserably if some of the operations expect to be invoked sequentially. If you need to implement a complex, stateful operation, either provide it as a single method call, or use a different pattern.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2006/02/design-pattern-table-data-gateway/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
