Bart Simons

Using MySQL in Swift with Perfect

 •  Filed under swift, mysql, perfect

So I recently got a chance to play around with Perfect - a "web app framework" for Swift that provides you with multiple building blocks to get your project going. One of the really neat things about this framework is that it contains anything you need to get stuff connected. I came across their MySQL library that can be used in projects with or without the other Perfect dependencies involved. You can't get any more modular than this!


My development environment

I tend to always use Linux for my projects, and this little project is no exception. My dev box is equipped with the following stuff:

  • Ubuntu Server 16.04 LTS
  • MySQL Server
  • Swift 3.0.2

You also need to install the libmysqlclient-dev package through apt-get in order to use and build the Swift MySQL package.


Creating a new project

Create a new directory for this project on your server. I called mine mysql-app. Change your current directory to that directory and run swift package init --type executable to generate a blank Swift project. If you have a Mac and plan to use Xcode for your project: you can initialize an Xcode project file with swift package generate-xcodeproj


Adding Perfect-MySQL to the project

Edit your Package.swift file and include Perfect-MySQL as a dependency, like this:

import PackageDescription

let package = Package(  
    name: "mysql-app",
    dependencies: [
        .Package(url: "https://github.com/PerfectlySoft/Perfect-MySQL.git", majorVersion: 2)
    ]
)

Now it's time to write some code!


The database structure


The code

Just put the following code inside Sources/main.swift:

import MySQL

let sqlHost     = "127.0.0.1"  
let sqlUser     = "app_authentication"  
let sqlPassword = "testing01"  
let sqlDB       = "app_authentication"

func fetchData()  
{
    let mysql   = MySQL()
    guard mysql.connect(host: sqlHost, user: sqlUser, password: sqlPassword, db: sqlDB) else
    {
        print(mysql.errorMessage())
        return
    }

    defer {
        mysql.close()
    }

    let theStatement = MySQLStmt(mysql)

    _ = theStatement.prepare(statement: "SELECT * FROM users")
    _ = theStatement.execute()

    let theResults = theStatement.results()

    print("\r\n")

    _ = theResults.forEachRow {
        e in

        for i in 0..<e.count {
            let theFieldName = theStatement.fieldInfo(index: i)!.name
            print("\(theFieldName): \(e[i]!)")
        }

        print("\r\n")
    }
}

fetchData()  


Build and run

Just run swift build to build your project and run .build/debug/mysql-app to run your application. It should return this as the output in your terminal:


Extra information

I made this small tutorial after I had to fiddle around with this library for one whole day. The documentation suggests to use mysql.query to run queries, but there's too little information available about running prepared statements. Not only in the documentation of Perfect, but also on the whole web. Then - a couple hours later - I discovered the MySQLStmt class, after digging into the Swift Tests available on their Github repo.

Another reason to only use the MySQLStmt class is because the class contains a function called fieldInfo which returns the name of a column by ID. mysql.query simply doesn't have that...

Oh well, at least I got some of my code fixed today. Enjoy programming in Swift!

Controlling iTunes via Swift using SBApplication

 •  Filed under swift, itunes, sbapplication, scriptingbridge

Since I took my hands down on Swift, I discovered SBApplication, Apple's take on making scriptable calls to the applications you already have on your computer. Want to get a list of currently opened tabs in Safari, and each of their titles? No problem!

I used tingraldi's SwiftScripting repository to generate Swift headers for any application that is scriptable. The generated headers give you full access to all the available calls you can make to a scriptable application.

I came up with an idea that might be great for demoing the purposes of the SBApplication class: a simple command-line application that controls and/or fetches information from and to iTunes. I uploaded my code as a Github repository, it should work for any Intel-based Mac.

https://github.com/bmsimons/itunescli

The how-to-use and build guide can be found inside the readme file on my repository.

Interactive website tracking with NodeJS - Proof of Concept

 •  Filed under node.js, node, interactive, website, tracking

Interactive website tracking is the future! Why do you want to aggregate static data if you can make your data dynamic? This mindset motivated me to make a small interesting proof of concept to show off the capabilities of dynamic tracking.

The development stack

I decided to make my small app in JavaScript, both for the server and client. Data transfer had to be effective, modern and bandwidth-effective, so I chose websockets over legacy AJAX technology.

I used this bootstrap form as an example:

<form>  
    <div class="form-group">
        <label for="exampleInputEmail1">Email address</label>
        <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
    </div>
    <div class="form-group">
        <label for="exampleInputPassword1">Password</label>
        <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
    </div>
    <div class="form-group">
        <label for="exampleInputFile">File input</label>
        <input type="file" id="exampleInputFile">
        <p class="help-block">Example block-level help text here.</p>
    </div>
    <div class="checkbox">
        <label>
        <input type="checkbox"> Check me out
        </label>
    </div>
    <button type="submit" class="btn btn-default">Submit</button>
</form>  

And the page has this client-side code:

$(document).ready(function()
{
    new Fingerprint2().get(function(result, components)
    {
        var sessionidentifier = "ID"+Date.now().toString()

        const socket = new WebSocket("ws://formstream:8080")

        var interval = 750

        var eventarray = []

        setInterval(function()
        {
            if (eventarray.length != 0)
            {
                socket.send(JSON.stringify(eventarray))
                eventarray = []
            }
        }, interval)

        $('form').on("click textInput", function(e)
        {
            var eventroot = {}
            eventroot['session'] = sessionidentifier
            eventroot['event'] = e.type
            eventroot['id'] = e.target.id
            eventroot['value'] = e.target.value
            eventroot['timestamp'] = Date.now()
            eventarray.push(eventroot)
        })
    })
})

As shown in the code sample above, I used fingerprintjs2 to create a unique browser identifier. This identifier can not be used as a personal identifier, but rather a unique anonymous identifier that matches your 'specific browser'. After a fingerprint has been generated, the script continues to run a continuous loop defined as an interval, which can be set to your desired value in a variable.

A UNIX epoch timestamp is generated for every event taking place, linked to that is every bit of event information that matters:

  • The event itself
  • The DOM object ID
  • The object's value

All this information is stored inside a JSON object. Once an event takes place, the JSON object gets pushed to the eventarray array.

Once the script reaches the end of an interval, the JSON objects stored in the eventarray get stringified and pushed to the websocket server but only in the case where there are more than 0 JSON objects available in the array, just to prevent the script from sending empty data on every interval.

The server application
var ws = require('nodejs-websocket')

var server = ws.createServer(function (conn)  
{
        console.log("NEW CONNECTION!")
        conn.on("text", function (str)
        {
                console.log(str)
        })
        conn.on("close", function (code, reason)
        {
                console.log("CONNECTION CLOSED.")
        })
}).listen(8080)

The server application is quite simple, it runs on NodeJS and only requires the nodejs-websocket dependency. No big deal, as it only functions as a console application that prints the received data from the client.

Server-sided console output

Remember that this is just a proof-of-concept that just captures form events. In reality you could capture any possible event and put it in a server side database. I hope that this article was informative enough for you, stay tuned for more 👍🏽

Bootstrap Tables to JSON, and vice versa.

 •  Filed under html, bootstrap, tables, json, jquery, javascript

This is just a quick post and/or announcement about a JavaScript library I have been working on:

github.com/bmsimons/bootstrap-jsontables

The main goal of this library is to make the link between a Bootstrap/HTML5 table with JSON a lot easier. Do you have an API available that returns data in JSON format? No problem! Bootstrap-jsontables takes care of that. Take a look at the examples on my GitHub repo if you need a quick visual glance of what this library could do for your project.


More features coming soon!

I'm having big plans to improve the search functionality of bootstrap-jsontables. The search functionality in its current form is just too simple, so that's going to be improved in the future.


Converting a table to JSON data

Say that we have this Bootstrap table:

<table id="appUsers" class="table">  
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>Bart</td>
        </tr>
        <tr>
            <td>2</td>
            <td>Nick</td>
        </tr>
    </tbody>
</table>  


Use this JavaScript/jQuery code to convert the table to JSON:

// Create a new JSONTable object on the #appUsers table.
var jsonTable = new JSONTable($("#appUsers"))

// Convert the table to JSON
var tableData = jsonTable.toJSON()

// The tableData object:
[{"ID":"1","Name":"Bart"}, {"ID":"2","Name":"Nick"}]



Keeping a log of all progress over here would be a bad choice, so please check out my GitHub for any future updates, changes and improvements:

https://github.com/bmsimons/bootstrap-jsontables

I hope that this library helps you with your project. Your feature requests and/or contributions are welcome, please let me and the community know in the form of a GitHub issue :)

WireGuard.io Getting Started Guide/Tutorial

 •  Filed under getting started, guide, tutorial, WireGuard, WireGuard.io

In todays networking world, virtual private networks are unmissable. With IT needs growing exponentially in the current modern era, it is essential to make the right choices on what VPN software you are going to use. While IPSec tunnels are commonly deployed and proven to deliver good performance while being stable at the same time, are there any other alternatives?

Yes there are. Here are some VPN solutions I have deployed in the past:

  • OpenVPN, both in peer-to-peer and remote access configurations
  • PPTP (with pptpd on Linux)
  • SoftEther (Has its own VPN protocol over an SSL connection)

Recently - on a long journey on Google - I came across WireGuard. They claim to have the networking code of their VPN software running in kernel-space for optimal performance, so that seems all good. I decided to dig deeper into WireGuard, so I could write a guide/tutorial on the getting started and configuration process.

My test environment

My test environment consists over two Linux servers in the cloud, they are directly connected to each other over a private network:

  • server-01: 10.129.29.151
  • server-02: 10.129.30.154

For benchmarking networking speeds I used iperf, and this is the traffic speed test result I got over this private network:

iperf raw network speeds

Installing WireGuard

This step is pretty straight forward, just copy and paste this code into your terminal:

add-apt-repository -y ppa:wireguard/wireguard  
apt update  
apt install -y wireguard-dkms wireguard-tools  

If you don't use Ubuntu on your servers, check out this page on the WireGuard website to find out how to install it on your Linux distribution of preference.

Initialisation of WireGuard's virtual interfaces

Configuring a simple peer-to-peer tunnel on WireGuard is not that complicated.

First of all, let's create the wg0 interface on both servers - this will be the virtual interface for your virtual private network between both servers:

ip link add dev wg0 type wireguard  

Your virtual network also needs an IP address for each node so that machines can communicate between each other over IP:

# For server-01:
ip address add dev wg0 192.168.2.1/24

# For server-02:
ip address add dev wg0 192.168.2.2/24  


Generating a configuration for each node

WireGuard uses a key-based VPN solution for communication between nodes. This system insists of a private key and a public key for each node. You can generate these keys on each node with the following command:

# For server-01:
wg genkey | tee privatekey01 | wg pubkey > publickey01

# For server-02
wg genkey | tee privatekey02 | wg pubkey > publickey02  

Create a configuration file named wireguard.conf and store it somewhere safe with the right Linux permissions applied on this file (chown/chmod). Here's what you need to put in this configuration file:

# On server-01:

[Interface]
ListenPort = 4820  
PrivateKey = privatekey01's content goes here

[Peer]
Endpoint = ip:port of endpoint (10.129.30.154:4820)  
PublicKey = publickey02's content goes here  
AllowedIPs = 0.0.0.0/0  
# On server-02:

[Interface]
ListenPort = 4820  
PrivateKey = privatekey02's content goes here

[Peer]
Endpoint = ip:prt of endpoint (10.129.29.151:4820)  
PublicKey = publickey01's content goes here  
AllowedIPs = 0.0.0.0/0  

Link the configuration to the interface on all nodes:

wg setconf wg0 wireguard.conf  

Bring the interface up on all nodes:

ip link set up dev wg0  

You are now connected, you can test connectivity by sending ICMP echo packets:

WireGuard ICMP connectivity test


Benchmarking performance

Run this command on the first node (server-01 in my case):

iperf -s  

Run this command on the second node (server-02 in my case):

iperf -c 192.168.2.1  

These are the results I got over the tunnel:

Pretty good results for just a dual-core server. I'm sure that there are possibilities/tweaks to make WireGuard perform even better, we'll see...