Friday, August 5, 2022

How to download and install PostgreSQL?

Introduction

This article will teach you how to download and install PostgreSQL on your system.

 

Downloading and Installing PostgreSQL

To get started working with Postgres, you need two components. 

  1. Postgres Server
    It houses your data 
    and manages connections, security, and data maintenance. 

  2. Management Application
    You need a way to communicate with a server 
    to work with and view the data it contains. For this, you'll need a management application or what is sometimes referred to as a front-end client. There are lots of different clients that you can use to interface with a Postgres Server. 

 

The easiest way to get started is to use an installer that gives us both components in one step. Follow the below step to download and install PostgreSQL:

Step 1

You'll start the installation at the URL postgressql.orgIt is the official site for Postgres, and you will find a big download button on the top and click on it.

 

 

Step 2

Now a new page will open, with several different application installers available depending on what operating system you're working on.

If you're working on a Linux machine, you will likely already have a version of Postgres since it comes pre-installed with the OS. 

The instructions you'll find at these links will help you install an alternate version if you need to. The installation for your macOS and Windows is almost identical. I'm working on a Windows computer, so I will click on the Windows button highlighted with the yellow color. 

Step 3

That takes me to a page that describes what versions of Postgres are available on each platform, either a 64-bit or 32-bit. 

 

After viewing the platform support information, you can click on the link up here that says download the installer. It takes you to a page maintained by a company called EnterpriseDB. 


Step 4

Finally, here you can choose which version of Postgres you want. 

 

I'll select the downloader for your Postgres by clicking on the download link underneath Windows. 

Step 5

It will start the installation package download, and once the download is completed, as I can see my screen's download progress, you can close the web browser and start the installation process. 

 

You should find the file inside the downloads folder for your computer. Go ahead and double-click on it to start it up. I'll allow it to make changes to my computer. 

Step 6

So that starts the setup wizard. Let's press the next button on this screen. 

 

Step 7

The default installation directory will be on my computer, inside the program files folder, a new folder for PostgreSQL, and then the version. I'll leave it to default and press next. 

 

Step 8

Here, you have four different components that you can install. 

The PostgreSQL Server is the main component, so I want to make sure that that's turned on. 

You have two interface clients that are coming along, pgAdmin 4 is a graphical user interface, and I'll leave that on, as well as the command line tools, and I'll leave those on as well. 

Stack Builder is a tool that will help you install additional add-on packages if you're interested in extending Postgres' capabilities. You can turn this off if you'd like. I'll leave it on here to install everything, and I'll go ahead and press the next button. 

Step 9

Next, it sets up a default data directory. And once again, on my computer, as in program files, PostgreSQL version, and then a new folder called data.

 I'll choose that default and press next. 

Step 10

You'll need to have a user account to connect to the server. Here, the installer is creating a default user that's named Postgres. And you need to create a password for this user. 

You can type in whatever password you'd like. Just make sure that you remember it moving forward. This user account is going to be an administrator-level account. So this user will have permission to do anything on the server.

Using this, you can create additional user accounts to control access to the stored data in Postgres. Once you've typed in the password and retyped the same password, press the next button. 

Step 11

The default port that Postgres will communicate on is 5432. 

You'll just leave that there and press next. 

Step 12

On this screen, you get to choose a default location. Once again, I'll leave this as the default locale and press next. 

Step 13

Now the installer will give me an installation summary. 

I'll press the next button and the next one more time to install the software. 


Step 14

When that finishes, the database server and client applications have been installed. 

Now, if you can also choose to install the Stack Builder application, you can turn off this checkbox here. You don't need to run Stack Builder when you finish out of this wizard, and I'll uncheck this checkbox and press the finish button. 

 

All done. It is time to test the installation, and you will find the management application to connect with the server.

Now you can go into my start menu, and I'm going to scroll down and find the new folder that was just added for PostgreSQL <version>. Inside of here, you have a couple of applications.

 

 

 I am only interested in below two applications:

  1. pgAdmin 4 - This is a graphical user interface for Postgres that'll run inside your web browser. 
  2. SQL Shell or PSQL - This is a command line tool popular with programmers. 

    You'll find the PostgreSQL <version> folder on macOS inside your applications folder. And inside, there will be the same pgAdmin and PSQL applications. So now you have Postgres Server and a couple of client applications for us to work with.

 Open the SQL Shell, a command-line window, and start the login process.

You need to know some connection details to log into a Postgres server.

Server IP:

First, it asks for the server location. If you're in a typical office environment where the Postgres server is running on a centralized computer, then you'll need the IP address of that machine. In our case, we're running the server and client on the same physical machine. So we can use the word localhost instead.

You can either type that in or press Enter, and localhost, the default indicated by the text in square brackets, will be used instead. I'll leave this blank and press Enter to enter in localhost.

Database:

Next, it asks you which database you want to connect to. Each Postgres server can hold many different databases. If you have just installed the server, it is brand new, and there's just one database called Postgres, so I'll log into that one. Again, you can press Enter to accept the default value of Postgres.

Communication port:

Next, we need the communication port that the server is listening on. This was set up during the installation step but is typically left at the default of 5432. I'll press Enter to accept that value.

User Name:

Then we need to provide the user account credentials. Again, during the installation, we created a superuser account named Postgres. So we'll use that. You will supply that username here if you've been assigned your own personal user account for your server.

Password:

Finally, you have to enter the user's password. Again, we gave the Postgres user account a password during setup. So I hope that you remember what you filled in during that step. Go ahead and type it in now. When you type, it will not appear on the screen, so just type it out and press Enter when you're done.

If everything was filled in correctly, you should be connected to the Postgres server, and the command prompt will change. Now we can start sending commands to the server.

Conclusion

We have successfully installed PostgreSQL with these simple steps.

 

 

Thursday, August 4, 2022

How to Create a JavaScript Library/Framework?

 

Introduction

This article will teach you how to Create a Javascript Library or Framework.

Creating a JavaScript library

Library Name: Greeter

  • When given a first name, last name, and options language, it generates formal and informal greetings.
  • Supports English and Spanish languages.
  • Reusable library/framework.
  • Easy to type ‘G$()’ structure. -Support jQuery

Structure Safe code

HTML

<html>
  <head>      
  </head>
  <body>
      <script src="scripts/jquery-3.6.0.js"></script>
      <script src="scripts/greetr.js"></script>
      <script src="scripts/app.js"></script>
    </body>
</html>

Include jQuery first to enable the jQuery support.

greetr.js

We require a global variable window and jQuery. Set up an IIFE function by passing the windows and the jQuery function.

Now create an IIFE function to start with.


(function(global, $) {
}(window, jQuery));

Now, this is safe to use in any of the applications and ready to use.

The next step is to set up the greeter object and the alias similar to jQuery $. You can review code the code of the jQuery library understands the safe entry method to work with any library.


(function (global, $) {

  var Greetr = function (firstname, lastName, language) {
    return new Greetr.init(firstName, lastName, language);
  };

  // You can create your properties and function here
  Greetr.prototype = {};

  Greetr.init = function (firstName, lastName, language) {
    var self = this;
    self.firstName = firstName || "";
    self.lastName = lastName || "";
    self.language = language || "en";
  };

  Greetr.init.prototype = Greetr.prototype;

  //Set the alias
  global.Greetr = global.G$ = Greetr;
}(window, jQuery));


Adding Language support

Now we set up the language support for English and Spanish. Along with this

(function (global, $) {
  var Greetr = function (firstname, lastName, language) {
    return new Greetr.init(firstName, lastName, language);
  };

  var supportedLanguages = ["en", "es"];

  var greetings = {
    en: "Hello",
    es: "Hola",
  };

  var formalGreetings = {
    en: "Greetings",
    es: "Saludos",
  };

  var logMessages = {
    en: "Logged In",
    es: "iniciar la sesión",
  };

  // You can create your properties and function here
  Greetr.prototype = {
    fullName: function () {
      return this.firstName + " " + this.lastName;
    },
    validate: function () {
      if (supportedLanguages.indexOf(this.language) === -1) {
        throw "Invalid language";
      }
    },
    greeting: function () {
      return greetings[this.language] + " " + this.firstName + "!";
    },

    formalGreetings: function () {
      return formalGreetings[this.language] + " " + this.fullName() + "!";
    },
    greet: function (formal) {
      var msg;
      //if undefined or null, it will be coerced to 'false.'
      if (formal) {
        msg = this.formalGreetings();
      } else {
        msg = this.greeting();
      }

      if (console) {
        console.log(msg);
      }

      //'this' refers to the calling object at the execution time
      // makes the method chainable
      return this;
    },
    log: function () {
      if (console) {
        console.log(logMessages[this.language] + ": " + this.fullName());
      }
      return this;
    },
    setLanguage: function (lang) {
      this.language = lang;
      this.validate();
      return this;
    },
  };

  Greetr.init = function (firstName, lastName, language) {
    var self = this;
    self.firstName = firstName || "";
    self.lastName = lastName || "";
    self.language = language || "en";
  };

  Greetr.init.prototype = Greetr.prototype;

  //Set the alias
  global.Greetr = global.G$ = Greetr;
}(window, jQuery));


Calling the library in the application

var g = G$("Niranjan", "Singh");
//Chained behavior and call to display greetings
g.greet().greet(true);
//Change the language and then greet
g.greet().setLang('es').greet(true);


Adding jQuery support

We need to add jQuery support and provide the functionality to give the id to Greetr library for updating the element text.

Update the HTML page with the below text to enable/demonstrate the jQuery incorporation.


<html>

<head>
</head>

<body>
  <div id="logindiv">
    <select id="lang" div>
      <option value="en">English</option>
      <option value="es">Spanish</option>
    </select>
    <input type="button" name="login" id="login" value="Login">
  </div>
  <h1 id="greeting"></h1>
  <script src="scripts/jquery-3.6.0.js"></script>
  <script src="scripts/greetr.js"></script>
  <script src="scripts/app.js"></script>
</body>

</html>

It requires changes in the Greetr library also. So add a new method called HTMLGreeting with a selector parameter.


    HTMLGreeting: function (selector, formal) {
      if (!$) {
        throw "jQuery not loaded";
      }
      if (!selector) {
        throw "Missing jQuery selector ";
      }

      var msg;
      //if undefined or null, it will be coerced to 'false.'
      if (formal) {
        msg = this.formalGreetings();
      } else {
        msg = this.greeting();
      }

      $(selector).html(msg);

      return this;
    },

Below is the simple library/framework which we have developed. It could be referred to and used to create a library.

(function (global, $) {
  // 'new' an object
  var Greetr = function (firstName, lastName, language) {
    return new Greetr.init(firstName, lastName, language);
  };
  // hidden within the scope of the IIFE and never directly accessible
  var supportedLanguages = ["en", "es"];
  // informal greetings
  var greetings = {
    en: "Hello",
    es: "Hola",
  };
  // formal greetings
  var formalGreetings = {
    en: "Greetings",
    es: "Saludos",
  };
  // logger messages
  var logMessages = {
    en: "Logged In",
    es: "iniciar la sesión",
  };

  // You can create your properties and function here
  Greetr.prototype = {
    fullName: function () {
      return this.firstName + " " + this.lastName;
    },
    validate: function () {
      if (supportedLanguages.indexOf(this.language) === -1) {
        throw "Invalid language";
      }
    },
    greeting: function () {
      return greetings[this.language] + " " + this.firstName + "!";
    },

    formalGreetings: function () {
      return formalGreetings[this.language] + " " + this.fullName() + "!";
    },
    greet: function (formal) {
      var msg;
      //if undefined or null, it will be coerced to 'false.'
      if (formal) {
        msg = this.formalGreetings();
      } else {
        msg = this.greeting();
      }

      if (console) {
        console.log(msg);
      }

      //'this' refers to the calling object at the execution time
      // makes the method chainable
      return this;
    },
    log: function () {
      if (console) {
        console.log(logMessages[this.language] + ": " + this.fullName());
      }
      return this;
    },
    setLanguage: function (lang) {
      this.language = lang;
      this.validate();
      return this;
    },
    HTMLGreeting: function (selector, formal) {
      if (!$) {
        throw "jQuery not loaded";
      }
      if (!selector) {
        throw "Missing jQuery selector ";
      }

      var msg;
      //if undefined or null it will be coerced to 'false'
      if (formal) {
        msg = this.formalGreetings();
      } else {
        msg = this.greeting();
      }

      $(selector).html(msg);

      return this;
    },
  };
  // the actual object is created here, allowing us to 'new' an object without calling 'new'
  Greetr.init = function (firstName, lastName, language) {
    var self = this;
    self.firstName = firstName || "";
    self.lastName = lastName || "";
    self.language = language || "en";
    self.validate();
  };
  // trick borrowed from jQuery so we don't have to use the 'new' keyword
  Greetr.init.prototype = Greetr.prototype;

  //Set the alias, attach the Greetr to the global object and provide a shorthand '$G' for the ease our poor fingers
  global.Greetr = global.G$ = Greetr;
}(window, jQuery));

Conclusion

We have created a small library that supports the jQuery framework also. We can create an extensive library or framework by following the same pattern. The best way to learn this is by reviewing the existing open source libraries and frameworks, e.g., jQuery.

Wednesday, February 16, 2022

How to resolve Global Exception Logger with Dependency Injection in ASP.NET Web API?

Introduction

In this article, you will learn how to resolve Global Exception Logger with dependency injection in ASP.NET Web API using Autofac.

How to resolve Global Exception Logger with dependency injection

Step 1: Create the custom exception logger by inheriting the IExceptionLogger interface to write your custom logging logic.

/// 
/// The main class GlobalExceptionLogger.
/// Handles the exception logging requests.
/// 
public class GlobalExceptionLogger : IExceptionLogger
{
    /// 
    /// 
    /// 
    public ILogger Logger { get; set; }
    /// 
    /// Initializes a new instance of the  class.
    /// 
    public GlobalExceptionLogger()
    {
        Logger = NullLogger.Instance;
    }
    /// 
    /// Logs the exception.
    /// 
    /// The exception context.
    /// 
    /// 
    public async Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
    {
        var ex = context.Exception;
        string message = $"{ex.Message}--{ex.Source}\n{ex.StackTrace}\n{ex.TargetSite}\n";
        await Task.Run(() =>
        {
            Logger.Error(ex, message);
        });
    }

}

Step 2: Register your custom exception logger class in the Autofac container to resolve it through dependency injection.

/// 
/// The main class AutofacConfig.
/// Provides Autofac DI configuration of the API.
/// 
public static class AutofacConfig
{

    #region Autofac Container
    private static Lazy builder =
      new Lazy(() =>
      {
          var autofacbuilder = new ContainerBuilder();
          RegisterTypes(autofacbuilder);
          return autofacbuilder.Build();
      });

    /// 
    /// Configured Autofac Container.
    /// 
    public static IContainer Container => builder.Value;
    #endregion

    /// 
    /// Registers the type mappings with the autofac container builder.
    /// 
    /// The autofac container builder to configure.
    /// 
    /// 
    public static void RegisterTypes(ContainerBuilder builder)
    {
       string baseDirectoryPath = AppDomain.CurrentDomain.BaseDirectory + "bin";
        if (!Directory.Exists(baseDirectoryPath))
            baseDirectoryPath = AppDomain.CurrentDomain.BaseDirectory;

        builder.RegisterModule(new LoggingModule());
        builder.RegisterModule(new FileStoreModule());
        //builder.RegisterModule(new CloudJobManager.CloudJobManagerModule());
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
        //builder.RegisterType().InstancePerLifetimeScope();

        var assemblies = Directory.EnumerateFiles(baseDirectoryPath, "*.dll", SearchOption.TopDirectoryOnly)
            .Where(filePath => Path.GetFileName(filePath).StartsWith("MyApp"))
            .Select(Assembly.LoadFrom).Where(assemblyType =>
            (assemblyType.FullName.StartsWith("MyApp") && !assemblyType.FullName.Contains("MyApp.Framework") &&
            !assemblyType.FullName.Contains("MyApp.Reporting.API")
            )).ToArray();

        builder.RegisterAssemblyTypes(assemblies)
        .AsImplementedInterfaces().InstancePerLifetimeScope();

        builder.RegisterType().AsSelf().AsImplementedInterfaces();
        builder.RegisterType().AsSelf().AsImplementedInterfaces();

        builder.RegisterType<ReportService>().As<IReportService>().InstancePerRequest();

    }
}

Step 3: Replace the custom exception logger in the HttpConfiguration services to use it in the place of the default ASP.NET exception logger.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.DependencyResolver = new AutofacWebApiDependencyResolver(AutofacConfig.Container);

        // Web API configuration and services
        //config.Services.Replace(typeof(IExceptionLogger), new  GlobalExceptionLogger());
        //config.Services.Replace(typeof(IExceptionHandler), new GenericExceptionHandler());

        // Inject our exception logger and handler
        config.Services.Replace(typeof(IExceptionHandler), config.DependencyResolver.GetService(typeof(GenericExceptionHandler)));
        config.Services.Replace(typeof(IExceptionLogger), config.DependencyResolver.GetService(typeof(GlobalExceptionLogger)));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Conclusion

Whenever an unhandled error occurs then you have a chance to log it. The information regarding the can be stored somewhere for review. There you can write the issue to a log or write custom logic.