Monday, December 16, 2013

SQL server, SQLExpress,SQLExpress user instance and localDB

MS SQL server has many versions available, sometimes it creates more confusion than help when an asp.net app works with visual studio but not after it is deployed to iis.


SQL server is the easiest one to understand, it has a single instance to be accessed.

SQL Express is a simplified version of SQL server. Note it requires a different installation to install. 

SQL Express User Instance and LocalDB: These are more for easy integration with Visual Studio, so the database are private to the application. But it causes permission issue if you need to work with iis deployment or developing environment switch. If you are not quite familiar with them like me, it makes sense  to avoid them in your project, as the effort to fix the configuration or permission issues may take longer than using a shared sqlExpress database instance. At least, it is easy to debug and understand if anything goes wrong. Simply is always better. 

To debug asp.net project after iis deplyment, attach visual studio to w3wp.exe.

If your asp.net application does not work after deploying to iis, the following issues may cause it:
1. The permission issue from SQL Express User Instance and LocalDB, change the database connection to SQL server or SQLExpress shared instance.

2. After that, for "opening database errors" when connecting to database, it may happen because the SQL server or SQLExpress instance is missing, first check whether the instance is available, open "SQL server configuration manager" under sql server 2012's "Configuration tools" application, select SQL Server Service node, and see whether the shared instance service is there.

3. For database permission issue, you may want to change the logon user for SQL server or SQLExpress service to local system to avoid any permission issue.

4. For Asp.net application pool permission issue, open iis manager, change all application pool's advanced settings' identity to local system.

5. if an error happen say "'NT AUTHORITY\SYSTEM" account cannot access the database, then either use database authentication instead of Windows authentication in connection string or open database manager studio, and make sure 'NT AUTHORITY\SYSTEM' exists under security/logins node. then change the "Default database" to the application's database, and also under "User Mapping", select the application database, and "public" adn "db_owner" role.

Sunday, December 15, 2013

Deploy VS 2012 asp.net project to iis with ssl

Deploy asp.net project to iis from visual studio 2012
1. In visual studio 2012, open the asp.net project.
2. right click the project, and select "publish web site"" menu
3. select profile dropdown list, and <new> to create new profile
4. set the profile name, for example "iis"
5. select deploy method to "web deploy"
6. set server name to localhost, and site name to "Default Web Site/MyAppName"
7. then publish the application

Enable SSL for iis web app
1. From iis manager, select the root item
2. select "Server Certificates" icon, and click "create self-signed certificate" item
3. select the web site and click "binding..." (ssl only applies to web site, not individual app"), for port 443, select ssl certificate to the one just created.
4. select the web application, and click on "ssl settings" icon, check require SSL checkbox
5. visit the site with https:// and a certificate exception will be prompted.

Create certificate with customized common name
1. IIS only creates certificate which uses computer name as common name. If the web site name is different from computer name, then you need to create certificate differently.
2.Download selfssl7 from the link of http://blogs.iis.net/thomad/archive/2010/04/16/setting-up-ssl-made-easy.aspx, and unzip selfssl7.exe to local
3. run the below command to create the certificate
selfssl7 /N cn=torn00461340a.amer.global.corp.sap /K 1024 /V 18250 /X /F torn00461340a.pfx /W password
4. import the certificate to iis.






Tuesday, December 10, 2013

Common git commands

Common basic git command

git init:
To create a new local git repository to run the git command

git branch new-branch-name
To create a new branch
This will use the current workspace's HEAD to create a branch. This command will create the new branch in repository, but it will not switch the current workspace to the new branch; use "git checkout <newbranch>" to switch to the new branch.

git checkout branch
switch the current workspace to the specified branch.
To combine the operation of create a branch and checkout it in a single command, use the following command:
"git checkout -b NewBranchName referenced-headername"
If the current branch has local added but uncommitted change, then you cannot switch to another branch by using git checkout. you need first commit or reset the change in current branch.

git branch
git branch -a
Execute "git branch" will show all local branches available in the repository, the current head branch is started with *.
"git branch -a" will list all remote and local branches

git add:
Add local change
take a stage snapshot of the local workspace change for future commit, it just creates snapshot for the current change in the workspace, no new head will be added in git repository. You can use git add multiple times and then commit them altogether

git commit
git commit --amend
To commit local change to repository
Git commit only commit the change from the snapshot created by git add.
--amend will add then new staged change into the previous commit. Running this when there is nothing staged lets you edit the previous commit’s message without altering its snapshot. After the commit message is changed in vi, for windows, press esc key and then type ":wq" to save the change and exit the editor.

git branch -d BranchName
delete a branch in local repository

git rebase SomeBranch
To apply the change in SomeBranch to the current branch from their common parent base head.

git pull
To pull server change without local committed change

git pull --rebase
integrate remote change to local branch

git fetch origin remoteBranchName
git checkout remoteBranchName
fetch a remote branch content to local and then checkout the branch. This command can be used when someone sends you a branch which contains some temporary change.

git push origin master
To push the local committed change to server branch

git clean -f -d
Remove local untracked file and folder

git checkout .
Revert all local change in existing files that are not staged with "git add" command.

git reset
revert the staged change made with "git add" command. the local change in workspace is still kept as local, unstaged change.  (git reset FilePath can also be used for single file )

git reset --hard
remove the staged change created by git add, and revert the local change back to the most recent commit. The local change will be lost

git revert PreviousCommitHash
make a commit to revert the previous change specified in previousCommitHash

git reset HEAD^
remove the last commit but keep the change in local

git add -u
Add all deleted file into added change for commit.

git cherry-pick head1
merge the change from one branch to another
1. get the sha1 number for the change
2. goto the dest branch and update the code to latest
3. run git cherry-pick sha1
4. commit the change to the new branch

git stash
save the current change with default name

git stash push PathOfFileOrFolder
save the current change for a particular file or folder

git stash save "name"
save a named change to stash

git stash list
show the existing stash

git stash pop
git stash pop stash@{0}
pop up a saved stash

git stash drop
delete the top stash without using it.

git stash apply
apply the last saved stash change, but do not delete it


Common comparison commands

git diff
compare local workspace change with added change (or committed change if no staged change available)

git difftool --cached
compare the difference between the added snapshot (before commit) and the last committed change

git difftool HEAD^ HEAD
compare the difference between the last commit and the previous commit

git diff HEAD
compare local workspace un-added change with the last committed change

git diff head1
compare the specified commit (head1) with the last commit (HEAD)

git diff commit1 commit2
compare all the changes made after commit1 (commit1's change is excluded), but including the changes made in commit2

git diff head1 head2
compare the specified commit head1 with head2

git diff head1^ head1
compare the change made by commit head1 with its parent

gitk -all &
show the visual commit history for all branches without block the terminal command

Git Tag for version management

git tag -a yourReleaseVersionNumber -m "release comment"
after a version is released, a git tag should be created to stamp the code that is associated with this release

git tag
show the existing tags

git show yourReleaseVersionNumber
show the commit message for the tag

git tag -d yourReleaseVersionNumber
delete an existing tag

git push origin yourReleaseVersionNumber
push the tag to remove repository

git checkout yourReleaseVersionNumber
checkout an existing tag. After checkout a tag (v1.0) as detached header, you need to use checkout -b to create a new branch (v1.1) based on the tagged code base, and then check in the change into the new branch (v1.1)


Update forked repository

assume you already in your local master branch, then follow the below steps

1. add remote (original) repo and call it upstream
git remote add upstream https://github.com/manishjanky/ngx-select-dropdown.git

2. fetch the change from remote upstream
git fetch upsteam

3. update local master to remote upstream's master
git rebase upstream/master

4. push your local master change to your remote forked master
git push origin master --force

Monday, December 9, 2013

Understanding ios dispatch queue and tasks

Type of dispatch queues:
serial queue:
A task on the queue will be executed only after its previous queued task is returned, the tasks are executed based on first in first out order, so at any given time, only one task from the queue is executed. Note independent serial queues (which have different names) are processed concurrently with respect to each other, so serial only applies to the tasks within a specific serial queue.

concurrent queue:
the tasks on the queue are still executed in first in first out order, but the next tasks may be executed before the previous task returns, so there may be multiple tasks run at the same time.

Find which queue is serial or concurrent?
All global queues returned by dispatch_get_global_queue are concurrent queues
The main thread queue returned by dispathc_get_main_queue is a serial queue
Queues created by dispatch_queue_create may be serial or concurrent queue depending on the second parameter, if it is null or DISPATCH_QUEUE_SERIAL, then it is a serial queue. If the parameter is DISPATCH_QEUE_CONCURRENT, then it is a concurrent queue.


Ways to submit a queued task:
dispatch_async:
When the task is submitted, the call will return immediately, the queue will decide how to invoke it based on whether the current queue is concurrent or serial.
dispatch_sync
When the task is submitted, the call is blocked and cannot continue until the block is executed and returned.

Notice when submitting a block task to dispatch queue, the dispatch_block_t does not take any parameter or does not return any value. This should not be a big issue, as block can access the variables in caller's scope with enclosure.

Other notes:
1. Queue created by dispathc_queue_create method must be released by dispatch_queue_release method.
2. Any pending blocks submitted to a queue hold a reference to that queue, so the queue will not be released until all pending blocks have completed

Sunday, December 8, 2013

Understanding ios block

Syntax
Blocks for objective c is similar to anonymous functions javascript, one can pass it as parameters of methods or return it from methods. Blocks have a typed parameter list and an optional return type. Block can be assigned to a variable and then be called as a function. The syntax of block follows C convention instead objective C, so it uses ',' to separate parameter, and use () to invoke a block.

Declare a block is similar as declare a function pointer, you can specify the return type and parameter types, but not the parameter names as shown below:
NSInteger (^mathOperation)(NSInteger, NSInteger);
void (^simpleBlock)(void);

Likes any other variables, the block variable can be assign to a value as shown below, note the parameter names are set in the block definition. However, the returning type specification is optionals, if missing it is inferred from the actual return type. To specify return type, it needs to be put after ^
NSInteger (^mathOperation)(NSInteger x, NSInteger y) = ^NSInteger(NSInteger x,NSInteger y){    
  return x + y;
}; 

void (^simpleBlock)(void) = ^{
        NSLog(@"This is a block");

    };

Another point is the parameters in block type definition uses ',' to separate each other, like C convention as shown below
NSInteger sum = mathOperation(1,2);

Note for block parameter type declared in method declaration is different from block variable, it moves the parameter name to the end of the declaration, like shown below. 

-(void) myMethodTakeBlockAsParameter: (NSInteger(^)(NSIntegerNSInteger))mathOperation;

When actually call the method, do not specify the return type, but specify the parameter names as below


 [self myMethodTakeBlockAsParameter: ^(NSInteger int1, NSInteger int2){
      return int1+ int2;
   }];


Variable Enclosing Scope
Block can access the data within its definition scope, similar to javascript enclosure function. If you implement a method and that method defines a block, the block has access to the local variables and parameters of the method (including stack variables), including instance variables. This access is read-only, but if a variable is declared with the __block modifier, its value can be changed within the block. Even after the method or function enclosing a block has returned and its local scope has been destroyed, the local variables persist as part of the block object as long as there is a reference to the block.

By default, the value is captured when the block is defined and is read-only. This means that if you change the external value of the variable after defining the block, then the value captured by the block is unaffected by the change. In below example, the anInteger's value in block is still 42:

    int anInteger = 42;
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
    };
    anInteger = 84;
    testBlock();

If you need to change the value of a captured variable from within a block, you can use the __block storage type modifier on the original variable declaration. This means a live instance is used by the block and the original variable scope. For example if define the above variable as
__block  int anInteger = 42;
then the output will be 84.

When to use block
1. to enumerate NSArray or NSEnumerate object
enumerateObjectsUsingBlock

2. to specify a callback method as function parameter, such as completion callback block
3. To use by dispatch queue to specify a task to run sequentially or concurrently in sync or sync ways

Wednesday, December 4, 2013

Cordova ios webview debug issue

Cordova is a great open source framework. But it is free, which means you cannot expect too much from it. The following are two ios debug issues to make it work properly

1. To avoid webview thread lock crash:

In cordova.js, find method iOSExec.nativeCallback at line 1009, and replace it with the following code

iOSExec.nativeCallback = function(callbackId, status, message, keepCallback) {
    function f0(){
       return iOSExec.nativeEvalAndFetch(function() {
          var success = status === 0 || status === 1;
          var args = convertMessageToArgsNativeToJs(message);
          cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
       });
    }
    setTimeout(f0, 100);

};

2. To avoid missing plugin call
In cordova.js line 949, change it to following
    if (true || !isInContextOfEvalJs && commandQueue.length == 1) {
        if (bridgeMode != jsToNativeModes.IFRAME_NAV) {
            // This prevents sending an XHR when there is already one being sent.
            // This should happen only in rare circumstances (refer to unit tests).
            if (execXhr && execXhr.readyState != 4) {
                execXhr = null;

            }

Sunday, December 1, 2013

Understanding logic of cordova inappbrowser plugin

When inappbrowser plugin open method is called to open a new url,  the plugin native code will create a new webview and set its delegate to a new webview's controller to handle the url loading event. So there will be two different web views existing, once for the original html page and one for the inappbrowser url.

Once the inappbrowser url is loaded, the inappbrowser's webview didStartLoad and didFinishLoad event will be called, the inappbrowser native code will report the event as plugin callback to javascript. Note as the original plugin method was called on the original html page, so the plugin js callback onloadstart, onloadstop will also be invoked on the original plugin js method implemented on original html page.

In addition, since the onloadstart or onloadstop was triggered by url loading system from inappbrowser webview, so those events will be fired again whenever the inappbrowser loads an new url after the initial open url is loaded, so if you click a link in inappbrowser's html page to load another url, then the onloadstart and onloadstop events will be fired again for the new url

The html content shown in the inappbrowser webview really does not matter, it can be a simple html page or a text file, which has nothing to do with cordova, although it should also work if a cordova app is loaded.

Certainly on exit event will only be fired once when the inappbrowser is closed.