I’ve already announced that I’ll be holding a Model-Glue training program in Raleigh, NC from October 6th to 9th. Unfortunately early bird pricing has expired. However, if you still want a discount on the training program you can register before September 26th and save $400 per seat. If you have any questions about the training program please feel free to contact us.
Archive for September, 2008
Over the weekend I received a question from a blog reader asking how to create a backup script for SQL server. Rather than answering this in email I thought I’d share this knowledge with the world at large.
First off, you don’t need to do anything too complicated to create a backup script. SQL Server Management Studio has everything built in that you need.
To start creating a backup script first check that SQL Server Agent is running. If not, you’ll get error saying that the ‘Agent XPs’ component is turned off. To turn SQL Server on, simply open SQL Server Management Studio and rick click on SQL Server Agent and click Start. SQL Server Agent will start and you should no longer get the error about ‘Agent XPs’.
Unlike SQL 2000, creating a backup plan in SQL 2005 is not really very intuitive. In SQL 2000 you could simply use a wizard to create a maintenance plan. However in SQL 2005 you actually create a SQL Server Integration Services project which runs the backup for you. (Actually this is the same basic thing you did in SQL 2000, but the interface was nicer.)
First, click to expand the Management node under your server and then right click on the Maintenance Plans node and click New Maintenance Plan.
Give the new plan a name and click ok. This opens a new maintenance plan. On the surface the new interface looks completely useless.
However, you actually have a fair amount of power. The first thing you may notice is that you can give you plan a description and set the schedule for it. I’ll come back to scheduling this in a bit. Also note the Connections button. This is where you can select which servers your backup script will apply to. This automatically uses localhost, which is what I want for my script. You may wish to change this to another server for your script.
Look under the Object Explorer and you’ll see a Toolbox window. This is where you can decide what you want to do in your Maintenance Plan. Your options include backing up you databases, checking database integrity and more. All of the tasks essentially follow the same patterns as well. I’ll show you how to backup your databases and run integrity checks. After that you should know enough to start playing with some of the other tasks available to you.
Let’s start dragging the Back Up Database Task to the big open area in the center of your window. Once it’s there right click on it and click Edit.
Now you will be looking at the properties for the Back Up Database Task. If you’ve ever manually backed up a database this will look familiar.
Select which databases you want to backup from the databases drop down. I tend to choose all user databases.
Once you have selected the databases you want to backup you choose a destination. I’m assuming you’re backing up to disk. I also create a backup file with a subdirectory for each database.
Note that when you select the directory you want to backup into you may expect to see the directory structure on the computer you’re currently using. If you are not working from the console of your SQL server you may be surprised to instead see the directory structure of you SQL Server. Keep in mind that in this case the SQL Server Management Studio is actually connecting you to a server process that is on another computer. For this reason you’ll see that server’s directory structure. You also can’t browse to any network shares. For the purposes of this tutorial I’m simply going to select a directory local to the SQL server. However, if you want to backup to a network share you’ll need to make sure that the SQL Server Agent (I believe) is running on an user account that has access to that network share. And at that point you can manually type in the path to the network share you want to backup to.
Lastly I always check the backup integrity.
Click OK to return back to you plan.
Next let’s add a Check Database Integrity Task by dragging it into your backup plan.
Right click on this task and click edit to view its properties. For my plan I selected to check all user databases.
The last thing you need to do is tell your backup plan what order you want the backup and check database tasks to run in. This is actually very simple and (once you’ve done it once) intuitive. I want my backup script to run first so I’m going to select my Back Up Database Task. Note that once it’s selected a green arrow hangs down from it. Just select the tip of that arrow and drag it to the Check Database Integrity Task. This will set the sequence that first the backup task is run then the Check Database task.
Save your plan by clicking the save icon or using the File menu. If you now refresh your Maintenance Plans node in the Object Explorer you’ll see your plan listed.
To run you plan you simply right click on it and click Execute.
The last thing you’ll want to do is create a schedule for your plan. To do so, click on the ellipsis (…) next to the schedule box under the description of your plan.
Use the dialog to control when you want backups to run. I’m setting mine to run once a day at 1:00 AM.
And that’s it. Your databases will now be backed up to the location you specified according to the schedule you specified.
Of course, this was a simple example. You can get a lot more complicated if you dig around in the various tasks you have at your disposal.
One of my favorite methods in Model-Glue is makeEventBean(). For those who may not know about makeEventBean() here is the definition of makeEventBean() from the Model-Glue documentation:
Loops over a CFC instance, looking for any methods whose names start with set. For any setter methods where a like-named value exists in the viewstate, the setter will be called, passing this value.
For example, lets say you have a user object, and that user object has methods named setFirstname() and setlastName(). When you want to update this user through the use of a form submission, if you label to the form fields the same as the property they represent, then makeEventBean( user ) (where user is an instance of your user object) will call the setFirstname() and setLastName() methods, passing in the correct values, on the user object.
This is an example of code that might exist in your controller.
<cfset var user = getUserService().getUser( arguments.event.getValue( "userId", 0 ) ) /> <cfset arguments.event.makeEventBean( user ) />
MakeEventBean() is really handy when you have large forms to process as it eliminates the need to call all the setters manually.
When using Transfer, if you have relationships defined (such as a manyToOne) you must set those relationships before you can save the original object. For example, if you are creating a new user, but this user has a property that is another object (company for example), you will need to set the company property in your user Transfer object before you can save the user.
In this case, your code may look like this.
<cfset var user = getUserService().getUser( arguments.event.getValue( userId, 0 ) ) /> <cfset var company = getCompanyService().getCompany( arguments.event.getValue( "companyID", 0 ) ) /> <cfset user.setCompany( company) /> <cfset arguments.event.makeEventBean( user ) />
I will admit that this does not add a lot of code, but if you have a lot of these kind of relationships defined it can get burdensome. Also, to me, it feels like some logic or business process is creeping into our controller that maybe should not be there.
One solution I have started to implement on objects that have manyToOne relationships defined is to make use of Transfer decorators to simplify setting the properties that are other objects. I create methods in the user decorator with names like setCompanyId() that would get executed when makeEventBean() is called. These methods then take responsibility of setting the appropriate property with the corresponding object.
Here is an example of what the setCompanyId() method in our user decorator might look like:
<cffunction name="setCompanyId" access="public" returntype="void" output="false"> <cfargument name="companyId" type="numeric" required="true" /> <cfset var company = getTransfer().get("company",arguments.companyId)> <cfset setCompany(Company)> </cffunction>
Now, when makeEventBean() is called for the user, and companyID exists in the event this new method will take that value and set the correct company object inside of our user object.
This has been working well on a fairly large and complex project I am invovled in and I plan on using this technique moving forward on projects that will utilize Transfer. It has saved us quite a bit if time, and code.
Hello everyone from sunny Phoenix. My name is Layne Vincent. While I’m not the newest memeber of the Alagad team I am the newest to the blog-o-sphere.
My career in tag based meta-languages started back in the late 80’s when a colleage asked if I would like to learn SGML. Over the course of the next several years I wrote hundreds of DTDs and FOSI’s (there’s a term you won’t hear much anymore) while also teaching the fundamentals of document analysis and SGML implementation to clients such as Lockheed, Bell South, Alcatel and GTE.
During the mid-nineties I decided that HTML was the wave of the future and being that HTML is just a subset of SGML, it seemed a perfect fit. I went to work for Nortel and while I was there I came upon a requirement for an employee database. After looking around for a good way to implement it I found this new application called ColdFusion. It was version 1.0. Well, after spending my entire adult life wondering what I wanted to be when I grew up, I had finally found it.
After Nortel I moved on to Hewlett Packard where I enjoyed many years of ColdFusion development. One day a young intern named Jeff Chastain walked into my office and asked if I knew of a good language to use to design a web site with a database backend. The answer was obvious and now you know the beginning’s of Jeff’s career in CF.
As many developers do, I decided it was time to go it alone and form my own company. As those of you who are going it alone probably know, it can be both rewarding and frustrating. About a year and a half ago I decided to throw in the towel and sign on with Alltel. Alltel is a terrific company to work for and I have nothing but rave reviews for them. I have a question though, "When Doug Hughes asks you to join his team, how do you say no?". The answer is, you don’t.
So here I am at Alagad, diving deeply into all things OO and loving every minute of it. In the future I hope to write articles on anything and everything I can think of. Hopefully some of you will find them interesting or helpful or perhaps both.
Well, time to get back to work,
See you all soon.
I’d like to take a quick moment to announce a new blogger on Alagad.com, Layne Vincent. Layne actually started at Alagad a few months ago, but we’re just now getting around to unleashing him on the blog. Actually, in all honesty, Layne has never written publicly before and he’s somewhat hesitant but he’s is up the challenge.
Layne came to Alagad from his own consultancy company where he worked with a number of notable companies including Alltel. He has a broad range of experience he’ll be brining to the blog. So far, at Alagad Layne has been a jack of all trades and is our quazi-DBA.
I’d expect some upcoming posts on a range of topics including, perhaps, databases, object oriented programming, testing, and other topics relevant to what Alagad is working on at the moment.
Please take a moment to welcome Layne to the blog-o-sphere.
A disclaimer up front – I am not sure if this pattern is specific to ColdFusion, but I have never seen it in another object oriented language before.
A design pattern is a template solution for how to address a common issue in object oriented development. So here is a problem. In an ideal object oriented system, you are dealing with a server that never goes down and has unlimited memory. Therefore, when your application has five thousand user accounts, you just have five thousand little user business objects floating around in memory waiting to be used. In reality this is not really practical.
So here is the dilemma – you want to stay true to object oriented practices and benefit from the use of business objects, but trying to create a business object for every user record in the database just to display a list of users is not really practical. At the very least, the current request will be very slow and at worst, if it is a common request, you could bring the server down trying to do that kind of object initialization and garbage collection.
Some time back, I was introduced to the concept of an iterating business object (IBO) by Peter Bell. Simply put, the IBO is a business object with all of the desirable object oriented characteristics – getter and setter functions, data encapsulation, etc. However, instead of just containing the data for a single record, it can contain one or more records. Therefore, when you need to deal with a collection of user records, instead of creating a new business object for each user record, you can create one single user IBO instance and load all of the user records into the one object instance.
Internal to the business object, each record is now stored as a structure within an array. The business object maintains a pointer to the “current” record and has a variety of infrastructure functions to manage this array of structures. These functions include:
- add() – this function adds a new record (array element) to the business object and updates the current record pointer to point to the new record, leaving it ready to be populated.
- asQuery() – this function takes the internal array of structures and converts it to a ColdFusion query object which is returned. This is useful for serializing the result to JSON or for other display purposes.
- asStruct() – this function returns the current record as a structure. While returning records as structures looses the benefits of the object oriented business object, it can still be useful on occasion.
- currentRecord() – simply returns the current record number being pointed to by the record pointer.
- get( propertyName ) – a generic getter style function which will retrieve the value associated with the specified property for the current record. By using onMissingMethod(), this function can easily respond to the traditional getPropertyName() function call as well.
- loadQuery( queryObj ) – accepts a ColdFusion query object and loads it into the iterating business object. This is useful when using a DAO to quickly load multiple records into a business object at one time.
- loadStruct( structObj ) – accepts a ColdFusion structure and loads it into the current record of the iterating business object. This is useful for loading data like form submissions into a business object in that you can pass the entire form scope into the function at one time.
- next() – advances the internal record pointer to the next record. This function is very useful in looping through an iterating business object.
- recordCount() – returns the total number of records in the iterating business object.
- reset() – resets the current record pointer to point to the 0 record. This in combination with the next() function makes it very easy to loop through an iterating business object.
- set( propertyName, propertyValue ) – a generic setter style function which will set the specified value for the specified property for the current record. Again, by using onMissingMethod(), this function can easily respond to the traditional setPropertyName( value ) function call as well.
In another post, I will show some examples of how we have been using this functionality in our latest project as well as how we have encapsulated this functionality into a base object that all of our business objects extend, making it very simple to add new business objects to the system.
If you would like to learn more about object oriented development, and more specifically object oriented development with Model Glue, we have training opportunities that are coming up next month with early registration ending Wednesday. In addition, feel free to contact us to see how we can help with your next project.
I just wanted to quickly let the world know that I will officially be including training materials on Model-Glue 3:Gesture features in my October Enterprise ColdFusion with Model-Glue training class.
The class was initially written for Model-Glue 2 and the content is still relevant for Model-Glue 3. In fact, I would teach the class entirely on Model-Glue 3, but there are still a few minor features (such as scaffolding) that are not yet present in Model-Glue 3. For this reason Ill be teaching both versions at the same time!
Also, a former student Rich Leach recently had said some very nice things about the class. I thought it was fantastic and I couldnt resist sharing it here:
So what has Doug accomplished to earn his claim to fame? He not only tolerated my caffeinated, fuzzy mind in his Model-Glue training class for an entire week, but he got the message through. In a big way! Doug is an excellent instructor and runs a successful web development firm in North Carolina. He employs some great minds and generates even greater results. He’s educated, trained, experienced but most importantly sincere about what he does and how he does it. Since his training class I’ve produced 2 complete Model-Glue sites and I’m working on my 3rd. Couldn’t have done it without his training.
Be sure to register soon. The early registration gift, a $200 gift card to BestBuy is only being offered through Wednesday the 10th.
I hope to see a lot of CFers and the class in October!
Im happy to announce that I will once again be holding my full Enterprise Model-Glue with ColdFusion class. This time the class will be held on my “home turf” of Raleigh, North Carolina.
Here are some things people have had to say about the past classes:
“Excellent Class! I got all I wanted and more.”
“I learned more concepts than I ever expected to.”
“I thought the CFCunit and ColdSpring seminar was excellent!”
“Very well done. All the content was helpful.”
“Very good first day. Covered a lot of ground and the pace was good. Good mix of lecture and hands-on.”
“Class content is right on.”
This class will be a bit different in that Im going to use virtual machines to help smooth the getting-started process. In the past simple things like database connections have slowed the class down. By using pre-configured virtual machines these issues should be smoothed out this time around.
This is technically a Model-Glue 2 training class. However, I try to let the participants steer the direction of the class. So, if its requested enough I may also add a section on Model-Glue 3 features as well!
Early bird pricing starts at $1200, an absolute steal! Furthermore, the first three people who register will get $200 Best Buy gift cards.
There are only 15 seats in this class, so register early! I hope to see you there!