January 24, 2023

C# Yield Return & Break Statements

The yield keyword makes the method (in which it appears) as an iterator block. An iterator block, or method, will return an IEnumerable as the result. Within this iterator block or method, we will use the yield keyword to return the values for the IEnumerable.

Note that IEnumerable is lazily evaluted. If you call a method with an iterator block (with yield keyword), it will not run any code until we actually access the IEnumerable result values.

Lets see an exmaple.

Usually you may find code similiar to this where we are creating a temp list to hold the items, and at the end return the list from a method:

public IEnumerable<int> MyList()
{
	List<int> list = new List<int>();
	list.Add(1);
	list.Add(2);
	list.Add(3);
	list.Add(4);
	list.Add(5);

	return list;
}

You can simplify the method using the yield return statement, it allows us to remove the intermediate/temporary list required to hold the values.

public IEnumerable<int> MyList()
{
	yield return 1;
	yield return 2;
	yield return 3;
	yield return 4;
	yield return 5;
}

This method will return the same list of intergers but it does not need a temporary list to hold values.

You can use the yield break statement to explicitly stop the current iteration and cancel the iterator block. In this case it will return all these values which are produced with yield return statement. Once it reaches the yield break statement, it will stop producing any further value and exit the iterator block.

Lets see this example:

public static IEnumerable<int> MyList()
{
	yield return 1;
	yield return 2;
	yield break;
	yield return 3;
	yield return 4;
	yield return 5;
}

This method will only produce two values 1 and 2. Once it reaches the yield break statement, it will exit from the iterator block.

Typically you would do this when a certain condition is met, you only want to return a specific set of values from the iterator block.

Let see this example:

IEnumerable TakeWhilePositive(IEnumerable<int> numbers)
{
    foreach (int n in numbers)
    {
        if (n > 0)
        {
            yield return n;
        }
        else
        {
            yield break;
        }
    }
}

If you call this method like:

foreach (var item in TakeWhilePositive(new[] { 1, 2, 3, -1, 4, 5}))
{
	Console.WriteLine(item);
}

It will print the values from given array as:

1
2
3

Once it found a negative value, the iteration loop will be stopped and control is returned to the caller method.

References:

December 20, 2022

What is the purpose of using tsconfig.json file ?

tsconfig.json file allows you to point the root level files and different compiler options to setup that require to compile a TypeScript based projects. The existence of this file in a project specifies that the given directory is the TypeScript project folder root.

Here is an example tsconfig.json file.

{
"compileOnSave": true,
"compilerOptions": {
        "target": "es5",
		"module": "system",
		"moduleResolution": "node",
		"noImplicitAny": true,
		"sourceMap": true,
        "removeComments": false
},
	"files": [
		"program.ts",
		"sys.ts"
	],
	"include": [
		"src/**/*"
	],
	"exclude": [
		"node_modules",
		"src/**/*.spec.ts"
	]
}

Lets understand what each option specifies:

  • compileOnSave: If sets true, it instructs the IDE to automatically compile the given TypeScript files and generate the output.
  • compilerOptions: It allows specifying additional options to the TypeScript compiler:
    • target: the language used for the compiled output, e.g. es5, es6.
    • module: the module manager used in the compiled output. system is for SystemJS, commonjs for CommonJS.
    • moduleResolution: the strategy used to resolve module declaration files (.d.ts files). With the node approach, they are loaded from the node_modules folder like a module (require('module-name'))
    • noImplicitAny: if sets false, Raise error on expressions and declarations with an implied any type.
    • sourceMap: if sets true, it will generate source map files to debug directly your application TypeScript files in the browser,
    • removeComments: if set, Remove all comments except copy-right header comments beginning with /*!
  • files: Gives a list of TypeScript files that will be included by the compiler. The URL of the files can be both relative or absolute.
  • include: Allows you to include a list of TypeScript files using the glob wildcards pattern.
  • exclude: Allows you to exclude a list of TypeScript files using the glob wildcards pattern.

Install TypeScript compiler in VS Code

If you need to run the typescript from VS Code terminal you need to install the typescript compiler either globally or in your workspace.

This typescript compiler will transpile the TypeScript code to JavaScript.

Following are the steps we need to install and compile TypeScript in VS Code.

  • Install node.js Package Manager (npm).
  • Install TypeScript globally (-g) by this command:
    npm install -g typescript
    
  • If want to install TypeScript locally in a single project, you can use this command:
    npm install --save-dev typescript
    
  • Test your install by checking the version.
    tsc --version
    

TypeScript HelloWorld:

Let's start with a simple Hello World example. Create a new folder HelloWorld and open in VS Code.

mkdir HelloWorld
cd HelloWorld
code .

Create a new file called helloworld.ts.

Add the following TypeScript code in helloworld.ts file.

let message: string = 'Hello World';
console.log(message);

To compile the TypeScript code, you can open the Integrated Terminal (Ctrl+`)

Run this command to compile helloworld.ts

tsc helloworld.ts

It will create a new helloworld.js JavaScript file in the same folder.

To run the javascript file, you can use this command:

node helloworld.js

It will run the javascript code and display the script output in console.

November 21, 2022

SQL Server Logins vs Database Users

Usually there is a confusion over logins and users in SQL Server, especially for new SQL Server users. Here I have summarized the points to help understand the difference between these two concepts.

SQL Login

  • SQL Login is for Authentication. Authentication can decide if we have permissions to access the server or not.
  • Login is created at the SQL Server instance level.
  • The logins will be assigned to server roles (for example, public, serveradmin, sysadmin etc).
  • Create Login:
    CREATE LOGIN [idrees_login] WITH PASSWORD = 'password-goes-here';
    
  • Assign Server-Role to Login:
    ALTER SERVER ROLE [sysadmin] ADD MEMBER [idrees_login]
    

SQL User

  • SQL Server User is for Authorization. Authorization decides what are different operations we can perform in a database. Permissions inside the database are granted to the database users, not the logins.
  • User is created at the SQL Server database level. We can have multiple users from different databases (one user per database) connected to a single login to a server. User will always mapped to a Login.
  • Users will be assigned to roles within that database (eg. db_owner, db_datareader, db_datawriter etc).
  • Create User:
    CREATE USER [idrees_user] FOR LOGIN [idrees_login];
    
  • Assign Database-Role to User:
    ALTER ROLE [db_owner] ADD MEMBER [idrees_user]
    

General:

  • Logins only allow you to access to server. If the login is not mapped to any database user, then it will not be allowed to access any objects in the database.
  • You can not have a (database) user without a (server) login.
  • You cannot speficy the crendentials for user. Since user is mapped to a login, the login credentials are user for connection access. The same login credentials will be used to access all the databases for which a user is mapped.
  • Within a database, the objects-level permissions will be granted/revoked on user.

SQL Server - Change Authentication mode from Windows to Sql Server Authentication

During SQL Server installation, the wizard allows to select the authentication mode. At that time you can pick the required authentication scheme as per your needs.

In case if you have selected the Windows Authentication, the server will not configure the SQL Authentication mode and will not setup the default 'sa' account.

At later time if you want to enable the SQL Authentication, following steps will be required:

  1. Enable SQL Server Authentication Mode:

    • In SQL Server Management Studio Object Explorer, right-click the Server node, and then click Properties.

    • On the Security page, under Server authentication, select SQL Server and Windows Authentication mode. Then click OK.

    • When it asks you to restart the SQL Server, click OK.
  2. Enable Existing Login account sa:

    • By default, the sa account remains disable (if Windows Authentication mode is selected during SQL Server installation).

      First step is to enable sa login.

      ALTER LOGIN sa ENABLE ;
      GO
      
    • Second step is to set strong password for login sa.

      ALTER LOGIN sa WITH PASSWORD = '[enter-strong-password-here]';
      GO