Sunday, May 23, 2021

Why Kotlin is Domain Specific Language?

There was this question asked to me recently by a developer and as a programmer, I can program this and tell you why kotlin is a domain-specific language? and have many advantages as a domain-specific language.

My Answer:

What Is a Domain Specific Language?

Kotlin is a great programming language with many features. One of the most amazing abilities it has is to allow developers to author DSLs.

 So let's say you have a customer who wants a manufacturing system that can assemble a fort. the customer could easily just want an Android app with many screens, but it could be fort, so let's keep talking about that. you might make some code that looks like this, a series of imperative commands to the computer.

 Create some objects and wire them together to create a fort that has two walls and a tower. This code is normal code we see everywhere throughout our projects. The code is imperative, which I use to describe code that tells the computer exactly what to do.
 
In comparison, So suppose now the customer wants something bigger and new style but fort. The new fort has four towers, four walls, a keep in the middle. Additionally, the fort has some new requirements about how towers can be connected. So you add more imperative code. It constructs the various objects and wires them together to create the final fort object. 

The code still fits fort this requirement at least. The customer is really enjoying his fort and has bigger plans for your fort building system. Now he is requesting a grand fort consisting of many towers, walls, and keeps going. Additionally, he wants to add some new kinds of structures that have additional requirements. 

You can imagine a lot of code is going to be needed just to create this complicated structure. After a lot of typing, you manage to code it and the customer, once again, leaves you alone. However You sit down at your computer to write another 1, 000 lines of configuration code but stop, maybe there is a way to make this configuration code simpler. 

How are you feeling about writing the code using your imperative style? Your initial fort construction code was only about 10 lines. The slightly more complicated fort was a little more, but then you hit this point where larger forts require thousands of lines of configuration, not only that, you can see that in the future business is good and you will be writing many more forts over and over again. 

When you encounter this type of situation, you start to look for some ways to make it easier to construct forts with less code. Now there are several ways you could accomplish this. You could improve the object model. Maybe you have objects that create parts of the fort and create some reasonable components. This is always a good idea because reducing code complexity is important. However, it may not help to make it easier to construct a fort with less code because you are still limited with your imperative programming style and you have not tried to clean up noisy syntax. 

Another option is to use a configuration file. It could be represented as JSON, for example. The JSON can describe the fort and its components, another part of your code reads into JSON and creates the fort object. The file serves as the domain-specific language for your fort object. 

The advantage of this is that you are free to express the problem in any way you like. The downside is you need to implement the parser and other tools to interpret this new syntax. 
DSLs with their own syntax like this are called external DSLs. Often, they are not a good option because external DSLs require the extra work of writing parsers and result in DSLs with no IDE support. 
Now your third option is to create a DSL written in the Kotlin programming language. You can write the DSL to be just regular Kotlin syntax, however, you will not be writing normal Kotlin code. Instead, you're going to focus on using Kotlin's features to improve the syntax and customize it for forts building. 
This way allows you to create a DSL that helps you write more concise fort building code that is more easily understood. These are called internal DSLs and I think they are the sweet spot for utilizing DSLs effectively. 

Let's look at the problem another way.

Demo: Create a List of Towers

It looks like the customer is sending you a gentle reminder, we need to add towers to the DSL. One task you might need to accomplish in a DSL is to add a list of items. Doing so requires creating a special object within a DSL implementation. To get a clean syntax for specifying the towers, the DSL implementation needs a helper class. The Helper class is focused on creating a list of TowerBuilder objects.

Now, let's look into our code how it will look  like rather explaining things 

My Main Class will build any type of forts-based customer configuration and let's look at how easy is to configure this as compared to damn any-any language in the CS field.

Before jump into code just think of a real fort or castle how it can be.

fun main(args : Array<String>) {
FortBuilder().build()
}

class FortBuilder {
fun build() {
var builder = FortBuilder()

// function sequence
builder.keep("keep")
builder.tower("sw") // these are directions south-west
builder.tower("nw")
builder.tower("ne")
builder.tower("se")
builder.connect("sw", "nw") // connects with each other
builder.connect("nw", "ne")
builder.connect("ne", "se")
builder.connect("se", "sw")

// apply
builder.apply {
keep("keep")
tower("sw")
tower("nw")
tower("ne")
tower("se")
connect("sw", "nw")
connect("nw", "ne")
connect("ne", "se")
connect("se", "sw")
connect("keep", "nw")
connect("keep", "nw")
connect("keep", "se")
connect("keep", "sw")
}

// builders
builder = FortBuilder()
builder.keep("keep").tower("sw")
.tower("nw").tower("ne").tower("se")
builder.connect("keep", "sw").connect("keep", "ne")
.connect("keep", "se").connect("keep", "sw")
builder.connect("sw", "nw").connect("nw", "ne")
.connect("ne", "se").connect("se", "sw")
val castle = builder.build()
println("result: $castle")

// use varargs for this one
builder.connectToAll("keep", "sw", "nw", "ne", "se")

// using map syntax
builder.connect(mapOf("sw" to "nw", "nw" to "ne",
"ne" to "se", "se" to "sw"))
}
}

class FortBuilder {
private var towers = mutableListOf<Tower>()
private var keep: Keep? = null
private var connections = mutableMapOf<String, String>()

fun tower(name: String) : FortBuilder {
val tower = Tower(name)
towers.add(tower)
return this
}

fun keep(name: String = "keep") : FortBuilder {
keep = Keep(name)
return this
}

fun connect(from: String, to: String): FortBuilder {
connections[from] = to
return this
}

fun connectToAll(from: String, vararg to: String): FortBuilder {
for (toConnect in to) {
connect(from, toConnect)
}
return this
}

fun connect(map: Map<String, String>) {
map.forEach { from, to ->
connect(from, to)
}
}

fun build(): Castle {
val symbols = StringSymbolTable<Connectable>()
towers.forEach { symbols.add(it.name, it) }
keep?.let {
symbols.add(it.name, it)
}

val allWalls = connections.map { (from, to) ->
Wall(symbols.lookup(from), symbols.lookup(to)) }
return Fort(keep, towers, allWalls)
}
}

data class Fort(var keep: Keep?, var towers: List<Tower>
,var walls: List<Wall>)
data class Keep(override var name: String = "keep"): Connectable
data class Tower(override var name:String): Connectable
data class Wall(var from: Connectable, var to: Connectable)

Done that's it.

how easy it is as a developer if I think of Java here believe me it will be huge lines of code and very complex objects we need to handle. So would request to make them in any other language. you will notice the difference.
here you can connect to any towers to anything and create a bridge, wall, etc.
Suppose client asked you to create any other type of fort the idea is the base configurations will remain the same I mean you need a wall, the tower you need to connect them even you can any other configuration very easily without breaking anything and you do not have to write everything from scratch this is the beauty of the Kotlin and that is why I say it says domain-specific language.

Thanks.




Sunday, May 16, 2021

Difference between Single Linked List and Generalized Linked List ?

What is the difference between Single Linked List and Generalized Linked List?

Generalized Linked List

A Generalized Linked List L, is defined as a finite sequence of n>=0 elements, l1, l2, l3, l4, …, ln, such that li are either atom or the list of atoms. 

Thus

L = (l1, l2, l3, l4, …, ln)

where n is a total number of nodes in the list.

To represent a list of items there are certain assumptions about the node structure.

Flag = 1 implies that down pointer exists

Flag = 0 implies that next pointer exists

Data means the atom

Down pointer is the address of node which is down of the current node

Next pointer is the address of node which is attached as the next node

Why Generalized Linked List?

Generalized linked lists are used because the efficiency of polynomial operations using linked lists is good but still, the disadvantage is that the linked list is unable to use multiple variable polynomial equations efficiently. It helps us to represent multi-variable polynomial along with the list of elements. 

Representation of GLL, for example: 

When the first field is 0, it indicates that the second field is variable. If the first field is 1 means the second field is a down pointer, which means some list is starting.

Polynomial Representation using Generalized Linked List
The typical node structure will be:

Here Flag = 0 means variable is present
Flag = 1 means down pointer is present
Flag = 2 means coefficient and exponent is present

Now let's take an example:


This is basically 9x^5 + 7xy^4 + 10xz

Single Linked List :

import java.util.*;

import java.io.*;

import java.lang.*;

class AbhiBlog { 

    static class Node{

        int data;

        Node next;

        Node(int x){

            data=x;

            next=null;

        }

    }

    public static void main(String args[]) 

    { 

        Node head=new Node(10);

    Node temp1=new Node(20);

    Node temp2=new Node(30);

    head.next=temp1;

    temp1.next=temp2;

    System.out.print(head.data+"-->"+temp1.data+"-->"+temp2.data);

    } 

So it is like a One-way chain or singly linked list that can be traversed only in one direction. In other words, we can say that each node contains only the next pointer, therefore we can not traverse the list in the reverse direction.

But we can add two polynomial using a doubly-linked list efficiently.




Saturday, May 15, 2021

WhatsApp - Forwarding multiple messages in whatsapp follows which type of data structure

Interesting Interview Question for Senior Developer :  

Well I have multiple opinions on the same such as 

1) Whatsapp and most chat clients on the client-side use SQLite (A tiny embeddable database software) to store the data, and so the chat client does NOT use any data structure on their own and just calls the order-by query on the database, which gives them the list of chats ordered by the time.

This means the database has an index on the date and time of the last chat, and for this, if you look at the SQLite documentation, they use the often-used data structure of b-trees.



2)The data structure used in the queue.

A queue essentially works on the principle of "First In First Out".

A queue is maintained for each user which contains the message to be delivered to the user.

When the user comes online the messages in the queue are delivered and the queue is deleted.

Nothing is stored on the server.

3)WhatsApp uses a customized version of the open standard Extensible Messaging and Presence Protocol (XMPP)

WhatsApp follows a 'store and forwards' mechanism for exchanging messages between two users. When a user sends a message, it first travels to the WhatsApp server where it is stored. Then the server repeatedly requests the receiver acknowledge receipt of the message. As soon as the message is acknowledged, the server drops the message.

Well according to me it would be based on some key facts about networking.

For Delivered: After the message would be received at the client's phone an acknowledgment message sent would be pushed from the client's phone.

For Reading by When the user opens the screen where the message is present, again a notification would be sent this won't require implementing complex data structures but utilizing the features of the protocols being used for transmission. Which have become a part of WhatsApp now.

Whereas sent would indicate message being sent from your phone to the servers at WhatsApp

So for implementing this when in a group chat the message response needs to be stored in a queue that would verify all the above steps for each member in the group and accordingly will set the Status.

Now coming to an important point the original and "native" transport protocol for XMPP is Transmission Control Protocol (TCP), using open-ended XML streams over long-lived TCP connections, and TCP/IP protocol uses a network congestion-avoidance algorithm that includes various aspects of an additive increase/multiplicative decrease (AIMD) scheme, with other schemes such as slow-start to achieve congestion avoidance.

This could be one of the algorithms being implemented for network acknowledgments, they added a lot more features as they have customized XMPP to use on top of their transmission.

I hope I have answered your queries. Thanks.


Upload-Download Any FileType .PDF,MP3,MP4,.DOCX in Database and Without Database in SpringBoot Gradle Build System - Java

 Upload-Download Any FileType .PDF,MP3,MP4,.DOCX in Database and Without Database in SpringBoot :

I have asked to create a file upload-download demo in spring boot on the Gradle build system. So this for my students and beginners who want to understand the API how to develop file upload-download. Even you can view the same in your browser.

Our Spring Boot Application will provide APIs for:

Uploading File to MySQL database

downloading File database with the link

These are APIs to be exported:

Methods Urls Actions

POST /upload upload a File

GET /files get List of Files (name, url, type, size)

GET /files/[fileId] download a File

The uploaded files will be stored in the MySQL Database files table with these fields: id, name, type, and data as BLOB type (Binary Large Object is for storing binary data like file, image, audio, or video).

Let me explain it briefly.

– FileDocument is the data model corresponding to the files table in the database.

– FileDBRepository extends the Spring Data JPA repository which has methods to store and retrieve files.

– FilesStorageService uses FileDBRepository to provide methods for saving new file, get file by id, get list of Files.

– FilesController uses FilesStorageService to export Rest APIs: POST a file, GET all files’ information, download a File.

– FileUploadExceptionAdvice handles exceptions when the controller processes file upload.

– ResponseFile contains information of the file (name, URL, type, size) for HTTP response payload.

– application.YAML contains configuration for Servlet Multipart and MySQL database connection.

– pom.xml for Spring Boot, Spring Data JPA, and MySQL connector dependency.

Full Souce Code Accessible Here on below path:
https://github.com/Abhinaw/demo/tree/master

Below is the test results for reference :



Folder Location where file is getting stored : FileStorage Folder in project

     Folder Location where file is getting stored

Source Code :

import com.greenlearner.fileuploaddownload.dto.FileUploadResponse;
import com.greenlearner.fileuploaddownload.service.FileStorageService;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@RestController
public class UploadDownloadWithFileSystemController {

private FileStorageService fileStorageService;

public UploadDownloadWithFileSystemController(FileStorageService fileStorageService) {
this.fileStorageService = fileStorageService;
}

@PostMapping("single/upload")
FileUploadResponse singleFileUplaod(@RequestParam("file") MultipartFile file) {

String fileName = fileStorageService.storeFile(file);

///http://localhost:8081/download/abc.jpg
String url = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/download/")
.path(fileName)
.toUriString();

String contentType = file.getContentType();

FileUploadResponse response = new FileUploadResponse(fileName, contentType, url);

return response;

}

@GetMapping("/download/{fileName}")
ResponseEntity<Resource> downLoadSingleFile(@PathVariable String fileName, HttpServletRequest request) {

Resource resource = fileStorageService.downloadFile(fileName);

// MediaType contentType = MediaType.APPLICATION_PDF;

String mimeType;

try {
mimeType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException e) {
mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
}
mimeType = mimeType == null ? MediaType.APPLICATION_OCTET_STREAM_VALUE : mimeType;

return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(mimeType))
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName="+resource.getFilename())
.header(HttpHeaders.CONTENT_DISPOSITION, "inline;fileName=" + resource.getFilename())
.body(resource);
}

@PostMapping("/multiple/upload")
List<FileUploadResponse> multipleUpload(@RequestParam("files") MultipartFile[] files) {

if (files.length > 7) {
throw new RuntimeException("too many files");
}
List<FileUploadResponse> uploadResponseList = new ArrayList<>();
Arrays.asList(files)
.stream()
.forEach(file -> {
String fileName = fileStorageService.storeFile(file);

///http://localhost:8081/download/abc.jpg
String url = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/download/")
.path(fileName)
.toUriString();

String contentType = file.getContentType();

FileUploadResponse response = new FileUploadResponse(fileName, contentType, url);
uploadResponseList.add(response);
});

return uploadResponseList;
}

@GetMapping("zipDownload")
void zipDownload(@RequestParam("fileName") String[] files, HttpServletResponse response) throws IOException {
//zipoutstream - zipentry+zipentry

try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
Arrays.asList(files)
.stream()
.forEach(file -> {
Resource resource = fileStorageService.downloadFile(file);

ZipEntry zipEntry = new ZipEntry(resource.getFilename());

try {
zipEntry.setSize(resource.contentLength());
zos.putNextEntry(zipEntry);

StreamUtils.copy(resource.getInputStream(), zos);

zos.closeEntry();
} catch (IOException e) {
System.out.println("some exception while ziping");
}
});
zos.finish();

}

response.setStatus(200);
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;fileName=zipfile");
}
}

This is without a database just upload and download files to a particular location.

application.yaml:

server:
port: 8081

file:
storage:
location: fileStorage

spring:
servlet:
multipart:
enabled: true
location: temp123
file-size-threshold: 5MB
max-file-size: 20MB
max-request-size: 20MB

datasource:
url: jdbc:mysql://localhost:3306/db?useSSL=false
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver



Gradle dependency:

dependencies {
//my sql connector
compile 'mysql:mysql-connector-java:8.0.17'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}

Thanks.


Sunday, May 9, 2021

Ktor Kotlin Backend Development with MySql Database Demo Project - Mobile Development

Kotlin-Ktor-MySql-Webservice Development

GitHub Full Source Code:
https://github.com/Abhinaw/nearbyapi_abhi/tree/master

I was getting demand for Ktor Kotlin Backend Development with Sample MySql Database Code So in this blog I will give you all full access to the source code on my Github URL.

SQL file is also committed to the parent folder and you can easily import and configure the project.

Why Ktor?

Use what you need. Ktor allows you to transparently configure only the functionality your project requires. No magic involved!

Extensible

Extend what you need. With a configurable pipeline, you can create the extensions you need and place them anywhere you want.

Multiplatform

Run it where you need it. Built from the ground up with Kotlin Multiplatform technology, you can deploy Ktor applications anywhere.

Asynchronous

Scales as you need it. Using Kotlin coroutines, Ktor is truly asynchronous and highly scalable. Use the power of non-blocking development without the callback nightmare.

Java Threads Vs Kotlin Coroutines 

I myself as a programmer/developer I tested it by writing code that's what I do. I read somewhere that Courotines is much better than Java threads I did not believe it initially but to test it I did one thing like I have an 8GB RAM Multi-core Windows operating system. 

To test it, I wrote a simple Java and Kotlin Program where what i did is like created 100 threads from Fork/Join Pool of threads and the same concept with Kotlin Coroutines and the result was amazing to me. 

In the case of Java, my system got crashed and it consumes my all resources when I checked my task manager it was consuming 100% of my system but in the case of Coroutines with the same program, it only consumed my 80% resource and that is an amazing part to me and even the program did not crash. this makes me a little uncomfortable worked on Java for more than 10 years till now and maybe it proves how powerful Kotlin is. As a developer/programmer I believe it because I checked it by doing my hands dirty with it.

Thoughts for Food for Android Developers:

I strongly believe that it will take time to improve like Spring Eco-System but I find it very useful in terms of Mobile Application Development because in every mobile app we need middle-tier for data transaction and there it saves like earlier for that Mobile Developer can not cater that requirement but now they can easily cater the same because they can write the required code for Middle-Tier certainly Android Developers.

And there is one more advantage that I can see is like you can create a single project structure to care both the platforms I mean Front-End and Middle-Tier, Yes there can be an architectural difference but indeed very help full when it comes to CI/CD.

Ktor is a framework to easily build connected applications – web applications, HTTP services, mobile and browser applications. Modern connected applications need to be asynchronous to provide the best experience to users, and Kotlin coroutines provide awesome facilities to do it in an easy and straightforward way.

While not yet entirely there, the goal of Ktor is to provide an end-to-end multiplatform application framework for connected applications. Currently, JVM client and server scenarios are supported, as well as JavaScript, iOS, and Android clients, and we are working on bringing server facilities to native environments, and client facilities to other native targets.

When you create a project in IntelliJ IDE:

Name: Specify a project name.

Location: Specify a directory for your project.

Build System: Choose the desired build system. This can be Gradle with Kotlin or Groovy DSL or Maven.

Website: Specify a domain used to generate a package name.

Artifact: This field shows a generated artifact name.

Ktor Version: Choose the required Ktor version.

Engine: Select an engine used to run a server.

Configuration in: Choose whether to specify server parameters in code or in a HOCON file.

On the next page, you can choose a set of features- building blocks that provide common functionality of a Ktor application, for example, authentication, serialization, and content-encoding, compression, cookie support, and so on.

application.conf:

ktor {

    deployment {

        port = 8080

    }

    application {

        modules = [ com.jetbrains.handson.chat.server.ApplicationKt.module ]

    }

}

Application.Kt:

package com.abhinearby

import com.fasterxml.jackson.databind.SerializationFeature

import io.ktor.application.*

import io.ktor.features.*

import io.ktor.gson.*

import io.ktor.http.*

import io.ktor.http.cio.websocket.*

import io.ktor.jackson.*

import io.ktor.request.*

import io.ktor.response.*

import io.ktor.routing.*

import io.ktor.websocket.*

import org.slf4j.event.Level

import java.util.*

import kotlin.collections.LinkedHashSet

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

@Suppress("unused") // Referenced in application.conf

@kotlin.jvm.JvmOverloads

fun Application.module(testing: Boolean = false) {

    install(WebSockets)

    install(CallLogging) {

        level = Level.INFO

        filter { call -> call.request.path().startsWith("/") }

    }

    install(ContentNegotiation) {

        gson {

            setPrettyPrinting()

        }

        jackson {

            enable(SerializationFeature.INDENT_OUTPUT)

        }

    }

 routing {

        /* For only Testing*/

        get("/json/jackson") {

            call.respond(mapOf("hello" to "world"))

        }

        /********************Near By App Start*********************/

        val repository: RegistrationRepository = MySqlRegistrationToDoRepository()

        post("/registration")

        {

            val todoDraft = call.receive<RegistrationDraft>()

            val todo = repository.addToRegistrationTable(todoDraft)

            call.respond(todo)

        }

        get("/getallregistrationdata")

        {

            call.respond(repository.getAllRegisteredTableData())

        }

        put("/registration/{id}")

        {

            val todoDraft = call.receive<RegistrationDraft>()

            val todoId = call.parameters["id"]?.toIntOrNull()

            if (todoId == null) {

                call.respond(HttpStatusCode.BadRequest, "id  parameter has to be a number!")

                return@put

            }

            val update = repository.updateToRegistrationTable(todoId, todoDraft)

            if (update) {

                call.respond(HttpStatusCode.OK)

            } else {

                call.respond(HttpStatusCode.NotFound, "registered user with the id $todoId not found")

            }

        }

        /**************Login********************/

        val loginRepo: LoginRepository = MySqlLoginToDoRepository()

        post("/login")

        {

            val todoDraft = call.receive<LoginDraft>()

            val todo = loginRepo.validateToLoginTable(todoDraft)

            call.respond(todo)

        }

        get("/getlogindata")

        {

            val repository: LoginRepository = MySqlLoginToDoRepository()

            call.respond(repository.getAllLoginTableData())

        }

        ///////////////////////////Websocket Chat System////////////////////////////

        val connections = Collections.synchronizedSet<Connection?>(LinkedHashSet())

        webSocket("/chat") {

            println("Adding user!")

            val thisConnection = Connection(this)

            connections += thisConnection

            try {

                send("You are connected! There are ${connections.count()} users here.")

                for (frame in incoming) {

                    frame as? Frame.Text ?: continue

                    val receivedText = frame.readText()

                    val textWithUsername = "[${thisConnection.name}]: $receivedText"

                    connections.forEach {

                        it.session.send(textWithUsername)

                    }

                }

            } catch (e: Exception) {

                println(e.localizedMessage)

            } finally {

                println("Removing $thisConnection!")

                connections -= thisConnection

            }

        }

        /////////////////////////////////////Chat////////////////////////////

    }

}

DatanbaseManager.Kt:


package com.abhinearby.database

import org.ktorm.database.Database

import org.ktorm.dsl.eq

import org.ktorm.dsl.insertAndGenerateKey

import org.ktorm.dsl.update

import org.ktorm.entity.sequenceOf

import org.ktorm.entity.toList

import java.sql.Connection

class DatabaseManager {

private val hostname = "127.0.0.1"

    private val databaseName = "nearby_abhi"

    private val username = "root"

    private val password = ""

    private val ktormDatabase: Database

    init {

        val jdbcUrl = "jdbc:mysql://$hostname:3306/$databaseName?user=$username&password=$password&useSSL=false"

        ktormDatabase = Database.connect(jdbcUrl)

    }

    /************Registration for the App*************/

    fun addRegistrationDataToDB(draft: RegistrationDraft): Registration {

        val insertedId = ktormDatabase.insertAndGenerateKey(DBRegistrationTable)

        {

            set(DBRegistrationTable.firstname, draft.firstname)

            set(DBRegistrationTable.lastname, draft.lastname)

            set(DBRegistrationTable.phoneno, draft.phoneno)

            set(DBRegistrationTable.address, draft.address)

            set(DBRegistrationTable.photo, draft.photo)

            set(DBRegistrationTable.username, draft.username)

            set(DBRegistrationTable.password, draft.password)

        } as Int

        val registration = Registration(

            insertedId,

            draft.firstname,

            draft.lastname,

            draft.phoneno,

            draft.address,

            draft.photo,

            draft.username,

            draft.password

        )

        insertRow(registration)

        return registration

    }

    private fun insertRow(registration: Registration) {

        val id = registration.id

        val username = registration.username

        val password = registration.password

        val fid = registration.id

        val sql =

            "INSERT INTO `login`(`id`, `username`, `password`, `fid`) VALUES ('$id','$username','$password','$fid')"

        ktormDatabase.useConnection { connection: Connection ->

            with(connection) {

                createStatement().execute(sql)

            }

            println("inserted!!")

        }

    }

    fun updateRegistrationDataToDB(id: Int, draft: RegistrationDraft): Boolean {

        val updatedRows = ktormDatabase.update(DBRegistrationTable)

        {

            set(DBRegistrationTable.firstname, draft.firstname)

            set(DBRegistrationTable.lastname, draft.lastname)

            set(DBRegistrationTable.phoneno, draft.phoneno)

            set(DBRegistrationTable.address, draft.address)

            set(DBRegistrationTable.photo, draft.photo)

            set(DBRegistrationTable.username, draft.username)

            set(DBRegistrationTable.password, draft.password)

            where {

                it.id eq id

            }

        }

        return updatedRows > 0

    }

    fun getAllRegisteredTableData(): List<DBNearByRegistrationEntity> {

        return ktormDatabase.sequenceOf(DBRegistrationTable).toList()

    }

    /**************************Registration End*************************************/

    /************************Login **************************/

    fun validateLogin(draft: LoginDraft): LoginDraft {

        val table = "login"

        val sql = "SELECT * FROM $table"

        ktormDatabase.useConnection { connection: Connection ->

            val rs = connection.createStatement().executeQuery(sql)

            while (rs.next()) {

                println(

                    "id: ${rs.getInt("id")}\t" +

                            "username: $${rs.getString("username")}\t" +

                            "password: ${rs.getString("password")}\t" +

                            "fid: $${rs.getDouble("fid")}"

                )

                val userName = rs.getString("username")

                val pass = rs.getString("password")

                if (draft.username.equals(userName)

                    && draft.password.equals(pass)

                ) {

                    break

                }

            }

        }

        return draft!!

    }

    fun getAllLoginTableData(): List<DBNearByLoginEntity> {

        return ktormDatabase.sequenceOf(DBLoginTable).toList()

    }

}

Entity.kt:

import org.ktorm.entity.Entity

import org.ktorm.schema.Table

import org.ktorm.schema.int

import org.ktorm.schema.varchar

object DBRegistrationTable : Table<DBNearByRegistrationEntity>("dbregistrationtable") {

    val id = int("id").primaryKey().bindTo { it.id }

    val firstname = varchar("firstname").bindTo { it.firstname }

    val lastname = varchar("lastname").bindTo { it.lastname }

    var phoneno = varchar("phoneno").bindTo { it.phoneno }

    var address = varchar("address").bindTo { it.address }

    var photo = varchar("photo").bindTo { it.photo }

    var username = varchar("username").bindTo { it.username }

    var password = varchar("password").bindTo { it.password }

}

interface DBNearByRegistrationEntity : Entity<DBNearByRegistrationEntity> {

    companion object : Entity.Factory<DBNearByRegistrationEntity>()

    val id: Int

    val firstname: String

    val lastname: String

    val phoneno: String

    val address: String

    val photo: String

    val username : String

    val password : String

}

RegistrationRepository.kt:

import com.abhinearby.entities.registration.Registration

import com.abhinearby.entities.registration.RegistrationDraft

interface RegistrationRepository {

    fun addToRegistrationTable(draft: RegistrationDraft): Registration

    fun updateToRegistrationTable(id: Int, draft: RegistrationDraft): Boolean

    fun getAllRegisteredTableData() : List<Registration>

}

PostMan Webservcie Request-Response Example:

1)http://localhost:8081/getallregistrationdata

[
    {
        "id"29,
        "firstname""abhi",
        "lastname""tripathi",
        "phoneno""8130752107",
        "address""siddha happyville",
        "photo""",
        "username""abhi",
        "password""abhi"
    },
    {
        "id"30,
        "firstname""abhinawtripathi34@gmail.com",
        "lastname""tripathi",
        "phoneno""8130752107",
        "address""cyfydufffi",
        "photo""",
        "username""test",
        "password""test"
    },
    {
        "id"31,
        "firstname""abhinawtripathi34@gmail.com",
        "lastname""tripathi",
        "phoneno""8130752107",
        "address""cyfydufffi",
        "photo""",
        "username""test",
        "password""test"
    },
    {
        "id"32,
        "firstname""buvu",
        "lastname""cyxx",
        "phoneno""753577789",
        "address""vyuvvjvj",
        "photo""",
        "username""test",
        "password""test"
    },
    {
        "id"33,
        "firstname""g7g7",
        "lastname""cyyc",
        "phoneno""8765677999",
        "address""gyuj",
        "photo""",
        "username""tests107@mailsac.com",
        "password""test"
    },
    {
        "id"34,
        "firstname""g7g7",
        "lastname""cyyc",
        "phoneno""8765677999",
        "address""gyuj",
        "photo""",
        "username""tests107@mailsac.com",
        "password""test"
    },
    {
        "id"35,
        "firstname""g7g7",
        "lastname""cyyc",
        "phoneno""8765677999",
        "address""gyuj",
        "photo""",
        "username""tests107@mailsac.com",
        "password""test"
    },
    {
        "id"36,
        "firstname""g7g7",
        "lastname""cyyc",
        "phoneno""8765677999",
        "address""gyuj",
        "photo""",
        "username""tests107@mailsac.com",
        "password""test"
    },
    {
        "id"37,
        "firstname""test",
        "lastname""test",
        "phoneno""875678887",
        "address""hhjbjhhj",
        "photo""",
        "username""test",
        "password""test"
    },
    {
        "id"38,
        "firstname""test",
        "lastname""test",
        "phoneno""875678887",
        "address""hhjbjhhj",
        "photo""",
        "username""test",
        "password""test"
    },
    {
        "id"39,
        "firstname""test",
        "lastname""test",
        "phoneno""875678887",
        "address""hhjbjhhj",
        "photo""",
        "username""test",
        "password""test"
    },
    {
        "id"40,
        "firstname""",
        "lastname""",
        "phoneno""",
        "address""",
        "photo""",
        "username""",
        "password"""
    },
    {
        "id"41,
        "firstname""",
        "lastname""",
        "phoneno""",
        "address""",
        "photo""",
        "username""",
        "password"""
    },
    {
        "id"42,
        "firstname""",
        "lastname""",
        "phoneno""",
        "address""",
        "photo""",
        "username""",
        "password"""
    },
    {
        "id"43,
        "firstname""",
        "lastname""",
        "phoneno""",
        "address""",
        "photo""",
        "username""",
        "password"""
    },
    {
        "id"44,
        "firstname""",
        "lastname""",
        "phoneno""",
        "address""",
        "photo""",
        "username""",
        "password"""
    },
    {
        "id"45,
        "firstname""",
        "lastname""",
        "phoneno""",
        "address""",
        "photo""",
        "username""",
        "password"""
    },
    {
        "id"46,
        "firstname""abhi",
        "lastname""sbhi",
        "phoneno""6858845",
        "address""ifdjdffuff kgufpfug bufstzcufuc kvfuk. kuddhjcfucucyddcpjvucyf",
        "photo""",
        "username""abhi",
        "password""abhi"
    }
]

2)http://localhost:8081/registration/29 (PUT Servcie)

request:

{
        "id"29,
        "firstname""abhinaw",
        "lastname""tri",
        "phoneno""8130752107",
        "address""howrah",
        "photo""/abc.png",
        "username""abhinaw",
        "password""abhinaw"
    }
Response:200OK
Time:251 ms
Size:62 B Save Response





























3)http://localhost:8081/registration (POST Service)









Websocket Communication System:

///////////////////////////Chat////////////////////////////
val connections = Collections.synchronizedSet<Connection?>(LinkedHashSet())
webSocket("/chat") {
println("Adding user!")
val thisConnection = Connection(this)
connections += thisConnection
try {
send("You are connected! There are ${connections.count()} users here.")
for (frame in incoming) {
frame as? Frame.Text ?: continue
val receivedText = frame.readText()
val textWithUsername = "[${thisConnection.name}]: $receivedText"
connections.forEach {
it.session.send(textWithUsername)
}
}
} catch (e: Exception) {
println(e.localizedMessage)
} finally {
println("Removing $thisConnection!")
connections -= thisConnection
}
}
/////////////////////////////////////Chat////////////////////////////

Very easy to communicate and very simple code for example.

Output Window: