The Napa Valley Marathon was run on Sunday, March 1st, 2009. 26.2 miles of the most gorgeous countryside in the world. It’s my favorite race because A) it runs the length of the Silverado Trail from Calistoga to Napa, and B) the male and female winners of the race (neither of which was me) win their weight in Napa Valley wine.
This is my third consecutive Napa marathon, and after two years of absolutely gorgeous conditions, we fell victim to the odds and it POURED the entire race. I was completely soaked thru and thru by the first mile marker, and that contributed to a miserable finishing time of 4:43. I stopped to wring out my socks on several occasions… I have to keep telling myself that finishing a full marathon is still an accomplishment, and I’ll do better in the next one.
The highlight of the weekend was, of course, the wine tasting! We had three separate private barrel tastings set up:
Del Dotto was first up on Saturday, and their new tasting room and caves out in St. Helena are just spectacular. The entire experience was first-rate. The 2006 Sangiovese was the star of the show for me. It’s just sublime, with silky tannins and bright red fruits coming through. Love their Pinot Noir as well, but it’s definitely not for lovers of a more “traditional” Pinot. Darker ruby color, almost opaque, and very fruit-forward. Felt more like a Syrah than a Pinot, but still delicious.
We also visited Bennett Lane, Clos Pegase, and Chateau Montelena (featured in the movie “Bottle Shock”) on Saturday.
Sunday (for me) started at 4:45 am. The starting gun went off in Calistoga at 7am, and I crossed the finish line just before 11:45, wet and tired, but satisfied that I’d given it all I had. Proving that I bounce back like a man half my age, I had a glass of wine in my hand by 1pm!
The Sunday wine-related festivities began with a barrel tasting at Reynolds Family winery in Oakville. Their ’06 Russian River Pinot is gorgeous – Bing cherries and raspberries all day with a silky mouthfeel. They have hand-labelled bottles that contain dried pressings from the wild mustard plants that fill the Valley. Beautiful wines and a great experience.
The real highlight of the weekend came at our final private cave tour/barrel tasting at Chateau Boswell in St. Helena. Boswell owns the property, and rents space in the caves to a relatively new label – Realm Cellars. Boswell’s tasting room is not open to the public, so you have to call ahead for an appointment. This session lasted nearly 4 hours, and we tasted just about everything that Realm and Chateau Boswell had to offer. Everything was just spectacular, each one better than the next… Scott from Realm took us first, and we started with their ’05 Beckstoffer/ToKalon Cab. Wow. It was absolutely perfect. Realm is definitely one to keep on the radar. We must have tasted from 8 or 9 different barrels, and everything just shone – drinkable now, but definitely with a backbone to age and develop.
Joshua Peeples from Chateau Boswell then led our group to their section of the caves, and we started with some of the whites in their Jacqueline label. The Jacqueline Cuvee Blanc is a “Bordeaux Blanc”-style blend of Sauvignon Blanc and Semillon, and I absolutely loved it. The Semillon gives this wine some real depth and a nice long finish. The CB Chardonnay is a lush Burgundian-style chard. It’s from the Wente clone, and is fermented for a full year on the lees with weekly battonnage. This gives it great tropical fruit flavors, but a hazelnut/vanilla undertone that was fantastic without being overoaked. I grabbed a half case of each. Then we moved onto the Cabs, and they were equally as wonderful.
We couldn’t have been treated better, and the wines were glorious.
Unfortunately, the rainy weather out in Napa kept us from enjoying the Valley to its fullest. We’d wanted to take a side trip up into Healdsburg and Geyserville for some Pinot tastings, but we never made it. The Healdsburg marathon is October 11th – maybe I’ll make it then!!
The annual Sybase International User Conference known affectionately as “Techwave” is no more, at least as we know it…. The new plan is to hold several regional events around the world, so instead of a single 5-day conference somewhere in the US, there will be 5 shorter events held at international locations.
Some questions I know you’re going to ask:
Is this a cost cutting measure? Is Sybase in financial trouble?
No. In fact, Sybase just posted it’s best financial results ever, for both a year and a quarter. The cost of holding multiple events will actually exceed that of holding one single event, so this is more about (re-) establishing customer relationships and educating the market on Sybase initiatives.
What will the new events look like? How will the programming change now that the event isn’t centralized?
Sybase will be hosting a series of 2-day regional events in global markets during the second half of 2009. There will be both business and technical content. In certain locations, there may also be vertical content, and certain sessions may even be conducted in the local language.
What are the dates and locations of these events?
To be determined. As soon as these are decided, look for a public announcement here, or at http://www.sybase.com.
Was TechWave losing its popularity with attendees over the years?
Just the opposite – TechWave has always been a popular event for Sybase customers, and the 2008 conference was voted “best ever” by the attendees. This is about increasing Sybase’s flexibility in corporate activities. A significant percentage of TechWave attendees came from countries outside North America, and this new model will help Sybase reach out to an ever-growing global customer base.
What will the new sessions cost? Will there be cancellation fees for people that have already registered for TechWave?
Sybase will be announcing the registration process and costs over the coming weeks and months. It is anticipated that the registration cost will be somewhere in the US$200 range. Since registration for TechWave 2009 had not yet opened, there will be no cancellation fees.
Will Sybase Senior Management be attending these conference sessions?
Sybase’s executive management team has a strong commitment to make these conferences, and the customer, a priority. There will be Executive keynotes at each session to describe the corporate vision and technology roadmap, but the actual agenda for the conferences is still under development.
How will sponsors who have participated in the past, or committed to sponsor in 2009 be affected?
Sybase is working to develop a conference sponsorship package that will work for the various sponsors. The thought now is to have global sponsorships, as well as local sponsorships in specific markets.
That having been said, I’ll miss the old TechWave. I’ve been to nearly every one – even back to the days of the PowerSoft User Conferences. I missed the first one in Dallas, ’97 in Nashville and ’98 in Los Angeles, but have been a fixture at all the years they were held in Orlando, San Diego, or Las Vegas. I even quit a job once because my Director told me I couldn’t attend… I found another one while at the conference. :)
Thoughts on this announcement? Favorite TechWave memories from years past? Leave me some comments…
…and its name is SySAM.
Sybase Software Asset Management 2.0, to be more precise. This is the new software licensing mechanism, based on FlexNET, that now governs a good portion of the Sybase product catalog. It has been in use with ASE and PowerDesigner for some time, and will eventually cover IQ and SUP as well. SySAM support was introduced into PowerBuilder as of 11.0, and it now governs all installed copies of PowerBuilder and InfoMaker. Prior releases of PowerBuilder and PowerDesigner relied on the “honor system” of license enforcement. To paraphrase a famous movie quote, “it’s not cheating unless you get caught, and if you’re not cheating, you’re not trying”. Software companies that don’t enforce their licensing terms won’t be in business for long.
So like it or not, SySAM is here to stay…
Anyone that is considering an upgrade to 11.x from 10.x release or earlier will have to understand the ramifications of SySAM license management. The good news is, it’s fairly simple once you understand the basics. The Help file and product documentation cover the ins and outs of SySAM in exhaustive detail. This post is just going to cover the basics.
Decide on a license model
There are two basic license models available with PowerBuilder’s implementation of SySAM. These are “served” and “unserved”. Let’s start by describing the unserved model first, since it’s easier to understand.
With an unserved model, each workstation receives an .LIC file that is generated specifically for that machine. The Sybase Software Product Download Center website is where you go to create these files. An .LIC file can be generated based on the MAC address of the network card or the serial number of the harddrive, so collect this information before you logon to the SPDC website. When you install PowerBuilder, it will ask whether you’re using a Served or Unserved license, and if you answer “unserved”, it will prompt you for this .LIC file. You can also apply the .LIC file after installation by going to Tools > Update License…
A served model means that a SySAM server process has been installed and is running somewhere on the network. This process hosts the actual licenses and serves them up whenever a development workstation connects. When using the SPDC for a served model, you are not prompted for individual MAC addresses or hard drive serial numbers – just the number of authorized licenses that you’ve purchased. The SPDC generates a single .LIC file that gets loaded into the SySAM server. When you install PB on the workstation and say “Served license”, you’re prompted for the IP address (or DNS name) of the server running SySAM. As each workstation connects, they decrement the available license count until it is exhausted.
Now, one might infer that if you’re running a served model, and don’t have access to the SySAM server when starting PB, you’d be denied access… Well, yes and no! SySAM allows a “grace period” for each workstation, which allows you to run disconnected from SySAM for up to 30 days before PB won’t start. Once you re-authenticate to the SySAM server, PB gets unlocked again.
It’s pretty clear that a served license model would benefit larger installations, because it saves someone the hassle of collecting all the MAC addresses of the development workstations. Smaller shops will probably lean toward standalone “unserved” models, so that nobody has to tend to the SySAM server process.
Other random things to consider
Alternate Use licenses
SySAM allows you to generate a second, “alternate use” license for each purchased license of PB. This can be used for a home workstation or a dedicated “build machine”. The theory here is that a user should be allowed to work from home (or any other second machine) without requiring a second license to be purchased – you can’t be in two places at once! And if you’ve dedicated a single machine for nothing but the deployment process (i.e., no active development work is being done on it), that’s perfectly acceptable for an alternate use license.
Citrix MetaFrame or Remote Desktop development
In this architecture, PB is installed on one single machine, and the developers connect to it and run Virtual sessions. Development shops that use this architecture MUST use the served model. The standalone unserved license model is not supported for Citrix or RDP users. Now, this statement only applies to running the PowerBuilder IDE. Deployed PB applications can still be run via Citrix or RDP without licensing implications.
Can I change from Served to Unserved (or vice-versa)??
Yes. This is done at the SPDC website. All you do is “check in” the existing license file and generate new ones with the new parameters. However, if you’re doing a lot of checkins and generations, expect a call from your Sales Rep to find out the reasons why. PowerBuilder does not support a “floating” license model, and a big volume of checkin/regenerate activity is a clear indication of someone trying to get away with something fishy…
The bottom line is this: Sybase has a right, and in fact a duty, to enforce its licensing terms. SySAM is an effective tool to do just that. It may be a bit of a headache initially, but once it’s set up, you usually don’t have to bother with it again. It really is in everyone’s best interests.
On the eve of this historic event – the Inauguration of Barack Obama as our 44th President – I thought it only fitting to provide a post that combined PowerBuilder with Politics… The web service in question serves up a random quote from our incomparable, (and soon to be unemployed) 43rd President, George W. Bush.
This entry will show you how easy it is to consume a web service using the .NET web services engine within PB11.5.
Step 1. Get yourself some WSDL
The language of SOAP-based web services is WSDL, or Web Services Descriptor Language. This highly arcane XML syntax contains the entire description of a web service, from the methods it exposes to the datatypes of the parameters it accepts and returns. Most web service engines will serve up the WSDL for their service by simply adding ?WSDL to the end of the URL. For example, we’ll be using the service at http://greg.froh.ca/fun/random_bushism/.
To see the WSDL, use this link: http://greg.froh.ca/fun/random-bushism/soap/?wsdl
(Save that last URL to your clipboard, you’ll need it in step 2 below…)
Step 2. Build a Web Services Proxy
PB11.5 ships with a sample Web Services application. I’ll add the Random Bushisms web service to that application, since it already has most of the app infrastructure in place. That workspace can be found in
C:\Documents and Settings\All Users\Documents\Sybase\PowerBuilder 11.5\Code Examples\Web Services.
To create a web services proxy, select File * New. In the Project tab, select Web Service Proxy, as shown in image #1.
The Web Services Proxy project object consists of two tabs – General and Web Service.
Let’s start with the General tab.
Deployment PBL: This is where PB will generate the Proxy class, so you’re selecting a PBL. The best practice (and the standard followed in the example workspace) is to create a PBL specifically for Proxy classes.
Proxy Name Prefix: This allows you to set your naming conventions for the proxy classes and their associated artifacts. I prefer “s” (for service) followed by a sequential number and an underscore. For the Bushism service, I used the prefix s21_
Now on to the Web Service tab (image 2 above).
The top field is the WSDL location, and you have two choices. You can either paste in a URL to web services WSDL somewhere out on the internet, or you can click the button with the elipses to select a file on your local file system that has a .WSDL extension. In our case, we’re using a public service, so paste in http://greg.froh.ca/fun/random_bushism/soap/?WSDL. (I told you that you’d need it…)
Note: If this URL is unreachable or returns an error, I’ve included the .WSDL file in the PB115_webservices.zip file, which can be downloaded from http://blogs.sybase.com/phoran/wp-content/uploads/2009/03/pb115_webservices.zip. PH
The next step is to click the Services… button. This causes PB to introspect the WSDL file, and bring back this nice graphical treeview dialog containing the methods and structures contained in the WSDL. Here’s what that dialog looks like:
Trust me – be thankful for this dialog. You don’t want to have to read that WSDL syntax yourself… What you’re doing in this dialog is selecting the service’s methods that you want to expose through the proxy. And, if those services return structures instead of simple datatypes as parameters, you’ll select the corresponding structures as well. This service is fairly simple – there’s one method: RandomBushismService, and one structure: RandomBushism.
Finally, in the WSDL Engine box, select the .NET engine, and provide a name for the .NET assembly DLL that will be generated. Click Save to save the project definition, and click Deploy to create the proxy. You should see two new entries in the Proxies PBL.
s21_randombushismservice: This is the proxy itself. You can open it and see the exposed method “getRandomBushism()”.
s21_randombushism: This is an NVO with two public instance variables – Bushism and Context, which represents the structure returned from the web service call.
Step 3. Create a visual interface to display the results.
In the tabpages.pbl file, the ancestor class uo_ancestor contains all the plumbing to instantiate the service proxy. All you need to do is provide the invocation code, and then process the output. Since the service returns two strings – the quote itself, and the corresponding context in which it was said, I created a simple layout with two statictext controls.
In the clicked event of the Invoke button, add the following code:
if instantiateService(px_Service, "s21_randombushismservice") then
lstr_bushism = px_Service.getRandomBushism( )
st_bushism.text = lstr_bushism.bushism
st_context.text = lstr_bushism.context
CATCH (Throwable t)
MessageBox("Invocation Error", t.GetMessage(), StopSign!)
It couldn’t be simpler. Instantiate the proxy class, invoke the method, use the results…
Save the object into the tabpages.PBL as uo_bushisms. The instantiateService() method is defined in the ancestor class uo_ancestor, so browse that at your discretion.
Step 4. Add the new service definition to the Service treeview.
The final step hooks this all together and allows the application to run with our changes. This isn’t really a requirement to get Web Services working from PB, it’s just to get them callable from this particular application. The main treeview is driven from a datawindow whose resultset is hard-coded into the .data attribute.
In the ws.pbl file, open the datawindow d_svclist.
If the Data pane is not visible, select View * Data, then go to the Data tab.
Insert a new row, and add the following column values (these can be copied and pasted from here):
svcname: Random Bushism
svcdesc: Retrieve a random George Bush quotation
svcimpl: Microsoft .NET
Save the datawindow, then try running it!
I’ve uploaded the workspace with all these revisions intact into the PB115_webservices.zip file.
Ah, the good old days of PowerBuilder 6.5…
It was a rock solid release, every consultant that could drop two commandbuttons on a window was making crazy money, and PowerBuilder shipped with it’s own Source Control package named ObjectCycle. It wasn’t a fancy integrated behemoth like Borland StarTeam or Rational ClearCase, but it was tightly integrated with PowerBuilder and its PBLs, which every other SCC package on the planet had trouble with… It did the job of basic version control for PowerBuilder, and the price was right.
ObjectCycle was EOL’d in 1999, but was still heavily used by companies that had frozen on PB 6.5 or 7.x. Then came PB8, and in that release Sybase completely revamped the SCC interface, utilizing the Microsoft SCC API. A new, basic SCC package called PBNative was developed for PB8, and is still shipping today. PBNative is extremely limited in scope, offering only Checkout/Checkin control and “Get Latest Version” operations. It stores only the most recent revision in its “repository” (which is just a folder on a shared LAN drive), and does not manage the version history of an object. A robust SCC package should store its repository in a full-featured DBMS, not the Windows filesystem… In my opinion, every development shop that is currently using PBNative (or doing nothing!) should be actively pursuing a real SCC provider…
There’s clearly a niche here. The PB world desperately needs a basic Version Management package with more functionality than PBNative, at an attractive price point, that is well-integrated with PowerBuilder.
As they say in the Bible – ask and ye shall receive.
Our good friends at E. Crane Computing, the creators of the now-legendary PowerGen product, are releasing a new SCC tool called PowerVCS. I spoke with E. Crane’s CEO, Phil Wallingford, and he gave me some general information about the new product, which is tentatively scheduled for limited beta here in Q1.
- PowerVCS will have a pure “web” architecture, with a mySQL repository on the backend and a browser-based administration console on the front-end.
- It will be offered in two modes: Private – where the PowerVCS server is installed and running inside your data center; and Hosted – where E. Crane will host the server-side components.
- There will be a commandline interface, so batch-scripted build procedures can be developed.
- Pricing is still being determined, but E. Crane is considering a monthly subscription model in the US$10 to $20 per month range.
I consider this to be a HUGE announcement, one that a lot of PB shops will absolutely benefit from. If you’ve ever used the PowerGen tool for automating your PB build process, you know that E. Crane puts out quality software, and is intimately familiar with the ins and outs of PowerBuilder development. (And if you haven’t used PowerGen, what are you waiting for???)
For more information on PowerVCS or E. Crane, drop them an e-mail at firstname.lastname@example.org
We all know that PB has the HProgressBar and VProgressBar controls, and they work exactly as advertised. You set the min/max position properties, the starting position, and the step increment, and then just call the StepIt() method to kick the progress bar into action. You get two basic styles – a “blocky” style and a “smooth” style. That’s it…
Well, I was goofing around on iTunes today, and was quite enamored with their nice animated progress bar. If you haven’t seen it, it’s got a nice angled gradient that moves along the bar from left to right, as the bar creeps forward. It looks like this:
It’s just a nice GUI effect, and I wondered if I could implement that same effect in PowerBuilder… And I got pretty close! Here’s a screen shot showing the application in action.
There were a couple of challenges I had to overcome in this project: a) how to get the “progress bar” column to increment like an HProgressBar, and how to animate it with a sliding gradient image. Let’s tackle these one at a time.
First – what would I use to simulate a progress bar? I decided to create an external freeform datawindow, with two columns in the result set. The first column is the actual bar itself, which I called “progress_bar” (because I’m clever like that…). I placed this column into the detail band, and gave it an angled gradient from Silver to Gray. The first image below is the Design pane of the datawindow painter, showing the column itself (ignore that computed column for now, we’ll discuss that in a moment), and the second image is of the Background properties pane.
I decided I would make the progress_bar column “grow” by dynamically changing its .Width property, starting at 0 and growing to it’s fully defined length 1% at a time in 100 increments. I also decided to do this with a datawindow expression, rather than coding Modify() calls from the PowerScript.
Which leads us to the second column in the result set – a hidden numeric value named “col_width”. In each iteration of the Timer event, I do a SetItem() of the value 1 to 100 into this column. By placing an expression that used that value as the “current percentage” of the original width, the datawindow rendering engine does all the heavy lifting! Now I just had to come up with the correct expression for the width property.
Since I was going to trigger 100 Timer events, and increment the progress_bar.width property by 1% of its “painted” length, my expression needed to determine what the original “painted” length of the column was. However, I can’t just use
Describe( 'progress_bar.width'), because there’s an expression in there, separated from the original width value by the “~t” (tab) character. I had to monkey around with it to extract out the initial width value. That tricky part of the expression was placed into the aforementioned computed column – just for legibility.
long( mid( describe( 'progress_bar.width'), 2, (pos( describe( 'progress_bar.width'), '~t') - 1)))
That says, strip out the characters in the Width property between position 2 and the first ~t, and cast those into a Long value. The actual expression in the .Width property is then simply
compute_1 * (col_width / 100.0), or “the original width of the column times the current iteration percentage. That gets our “progress_bar” incrementing right in step with the HProgressBar control!
Now let’s look at how I accomplished the gradient animation trick…
The first step is creating the angled gradient itself, and understanding how the new properties affect that gradient’s appearance. The Focus property of a background gradient changes the “center” of the gradient – in other words, the point at which there is 100% of the primary color. By choosing an gradient angled to about 45 degrees, and sliding the Focus property from 0 to 100, you can achieve that animated “sliding” effect that we’re after. The trick is to do it quickly, so it doesn’t appear jumpy. This relies on a little-used characteristic of the datawindow: it has it’s own internal Timer mechanism! By setting the “Timer interval” property on the General tab of the datawindow, any expression that uses the Now() function automatically gets recalculated at that interval.
I set the Timer Interval property to 10 milliseconds (1/100th of a second), and then wrote the following expression into the Focus property of the “progress_bar” background gradient:
integer( string( Now(), 'ff')). That takes the current time, gets the current 100th of a second from it, and makes an integer out of that. This causes the Focus of the gradient to move smoothly from the left side of the column, and then start over when it reaches the end.
As I said at the start, this doesn’t exactly duplicate the iTunes effect, but it does get close. The iTunes progress bar has more than one Focus point, i.e., it’s more heavily striped, whereas the datawindow only gets one Focus point, but it’s still a neat effect!
Download the TipsnTricks.zip file to see the code for this. It’s the uo_gradient_progressbar object. Let me know your thoughts on it.
OK, we all know that the “selling point” for PowerBuilder’s datawindow object is the ease with which it can retrieve data from a relational database, abstract out the complexities of binding that data to visual controls in the UI layer, and handle all the tedium of data validation and transaction management.
Been there, done that, got the t-shirt! (Trust me, I have a LOT of PowerBuilder t-shirts…)
In this posting, let’s take a look at a new feature of PB 11.5 that will let you use datawindows in ways you probably never thought of. And they have NOTHING whatsoever to do with data!
I’m sure your users would love to have a nice, subtle gradient (or even an image of your company logo?) in the background of your application’s windows and tabpages. You’ve been stuck with a solid background forever. Well, with PB 11.5, Sybase introduced support for gradients and transparency!
Problem solved, right?!? Not so fast, cowboy…
The new gradient capabilities are limited to one object – the datawindow. You can’t set a gradient in the background of a window or custom visual user objects (yet). This posting is going to show you how to accomplish that same effect using a datawindow!
Step 1. Create a freeform, external datawindow.
Since the data doesn’t matter, create this as an external dw with a single string column. You won’t have to bother with an InsertRow() or SetItemXXX(), so even the name of the column is immaterial. In the TipsnTrick sample app (which can be downloaded from the Box.net widget on the front page of this blog.) I called this datawindow “d_gradient_only”.
Step 2. Set the gradient properties in the datawindow background
I chose a subtle angled gradient that transitions from Teal in the upper left-hand corner, to Silver in the lower right. The figure below shows the Background properties panel for that datawindow. Mine are just examples – choose your own color schemes and brush types.
The Angle property setting only pertains to the AngleGradient brush mode, and it controls the direction of the transition from color #1 to color #2. I have that set at about 20, which causes the transition to go from top-left to bottom-right. Experiment with the various gradient settings to get the exact look that you want.
Step 3: Drop a datawindow control on your window or user object.
This is easy PowerBuilder 101 stuff. You place a datawindow control on the surface of whatever you’re using, and move it to the top left corner. You don’t need to stretch it to fill the entire parent, since we’ll be adding resize logic in step 4. (For you OOP noobs, making these changes to an ancestor class for the window or user_object would be a good design choice here).
In the sample app, I created a user object named uo_gradient_background, and the dw control is named “dw_grad”.
Step 4: Add resize logic so that the datawindow always fills the parent.
Programming note: Window objects come with a “resize” event already defined, but User Objects do not, so if you’re using a custom visual user object, you have to define a prototype for the resize event. If you open the uo_gradient_background object, you’ll see that I have the “resize” event mapped to the
pbm_size system event.
Place this code in that event:
setRedraw( FALSE )
dw_grad.resize( newWidth, newHeight )
setRedraw( TRUE )
I also placed one line of code in the window Resize event which resizes the Tab control.
tab_1.resize( newWidth, newHeight )
Now you have a datawindow as the background of the user object (or window, if you went that way), and whenever the parent container is resized, the datawindow always fills the available space. Consider this the actual background of the parent, and drop whatever actual UI controls your users will see right on top of the datawindow. The figure below shows the effect it creates:
Enjoy! And Happy Holidays!