June 29, 2012

Proper script inclusion in PowerShell

It is handy to use simple script inclusion in PowerShell called dot sourcing:
. .\include.ps1
There is a problem however. If you try to call the script from another directory that script lives in, an error occurs. include.ps1 will not be found since PowerShell uses current folder by default as a starting point.
To avoid this, script directory can be used:
$scriptDirectory = Split-Path -parent $MyInvocation.MyCommand.Definition
. $scriptDirectory\include.ps1

UPD: In newer versions script directory variable is provided on the shelf, just use $PsScriptPath variable

June 20, 2012

External program execution handling in Windows .cmd files

It is common to use .cmd or .bat files to run some simple scheduled tasks. But if you run some external .exe and it reports an error, your script will continue running. So, how to stop execution and exit with error code (usually it is any exit code except 0)? Just write next ugly line after each external program execution:
if %errorlevel% neq 0 exit /b %errorlevel%
For example:
svn update
if %errorlevel% neq 0 exit /b %errorlevel%
sqlcmd -S . -i task.sql
if %errorlevel% neq 0 exit /b %errorlevel%

June 14, 2012

Explicit datetime values in SQL server queries

It is common to type some temporary queries by hand in SQL Server Management Studio. In order to filter results by date easy to read datetime format can be used:
select * from Posts where CreationDate > '12 Apr 2012 09:07'
Time part can be omitted as well:
select * from Posts where CreationDate > '12 Apr 2012'
This format should work in most scenarios since it is difficult for SQL parser to mess with such an obvious date format. Certainly I would not recommend using it in production code.

June 20, 2011

Reference Ext JS components as instance fields

In our project we used to work with Ext.getCmp method if we need some dynamic interactions with our components. Which is not a very good experience actually. Instead of calling Ext.getCmp('usersPanel').doLayout() I would prefer just use this.usersPanel.doLayout().

To simplify our life we just can assign all needed fields in initComponent method:

initComponent: function() {
  Ext.apply(this, {
    items: [{
      xtype: 'panel',
      id: 'usersPanel'
    }]
  });

  this.callParent(arguments);

  this.usersPanel = Ext.getCmp('usersPanel');
}

Could be a nice solution, but there are some drawbacks: id property will correspond to html id attribute which should be unique in scope of html page. If we need to create several instances of our custom control we will run into troubles.

Ok, there is another way to achieve our aim:

initComponent: function() {
  this.usersPanel = new Ext.panel.Panel();
  Ext.apply(this, {
    items: [this.usersPanel]
  });

  this.callParent(arguments);
}

Well, quite straightforward way for autogenerated content, but will become quite unreadable in a component with several components. I can not call Ext designer very smart tool as well when it gets to the part with modifying generated components.

Happily enough there is a built in support for local ids in Ext JS.

initComponent: function() {
  Ext.apply(this, {
    items: [{
      xtype: 'panel',
      itemId: 'usersPanel'
    }]
  });

  this.callParent(arguments);
  this.usersPanel = this.getComponent('usersPanel');
}

It has a pitfall though. Method getComponent works only with items collection, but for deep hierarchy this approach doesn't work. My components usually have several layers of nested components. Especially when some layout work is required.

After some thinking we decided to allow components register themselves in a root container when they are created. Performing this work in initComponent is a good idea, but we need to have a reference to a container itself. So, initialConfig must contain two additional arguments: local identifier and parent component. We decided to do one pace further and make it more concise to be written in one line. Something like this: saveAs: { component: this, fieldName: 'usersPanel' }

Let's stop here for a while and discuss one small tip for JavaScript. Managing scope for code should be done carefully. If not it is easy to get some annoying 'undefined' errors. To simplify life we can just store a reference to an object in a variable once and let closures work for you. Usually I define me variable in the beginning of instance method which is equal to this.

initComponent: function() {
  var me = this;
  // ...
}

Back to our instance fields stuff let just make it more fluent: save: me.as('usersPanel')

As you may guess we defined a method as in current component which just returns a new object similar to { component: this, fieldName: 'usersPanel' }. All components in Ext JS are descendants of Ext.Component, it is a good place to put our registration extensions there:

Ext.Component.implement({
  as: function (fieldName) {
    return {
      component: this,
      fieldName: fieldName
    };
  }
});
  
Ext.Component.override({
  initComponent: function() {
    this.callOverridden();
   
    if (this.initialConfig.save) {
      this.save.component[this.save.fieldName] = this;
    }
  } 
});

Our initial example will look like:

initComponent: function() {
  var me = this;
  Ext.apply(this, {  
    items: [{
      xtype: 'panel',
      save: me.as('usersPanel')
    }]
  });
   
  this.callParent(arguments);
  // usersPanel is created and registered
  // me.usersPanel is available
}

You can check working example of this technique.