Measuring SQLite performance with C++ code

I did a quick Google search on “SQLite performance” and found the following:

Then to benchmark SQLite performance by myself I used the following C++ code that inserts 1000 batches of 1000 000 rows to a single table with an integer primary key:

(more…)

Adding interstitial ads to a QT application on Android platform

I keep working on my Lines Game and probably I try to make it the best Lines Game in the world, but there is some disappointing incident that prevents it from being the best and makes it a usual game that glitches a bit. To see the glitch in action download the beta version of the game.

Adding Interstitial Ads to a QT application on Android platform is an interesting and relatively exciting job. I learned the following facts while doing it:

  1. To build my app with Google Play Services I add com.google.android.gms:play-services-ads:18.1.1 dependency to build.gradle and add com.google.android.gms.version and com.google.android.gms.ads.APPLICATION_ID to the manifest.
  2. I do not specify additional permissions (uses-permission attributes INTERNET, WRITE_EXTERNAL_STORAGE, ACCESS_NETWORK_STATE) required by ads, but they are detected automatically when I upload the app to Google Play store and the used is not prompted to allow them when the app starts.
  3. QT main thread (on which QML UI is run) is not Android UI thread. So I cannot call Java advertising API from QML or C++ directly, but all the calls should be queued with runOnUiThread method.
  4. To access Context required by Java advertising API I replace QtActivity with my own custom activity that implements all the advertising logic and forwards all the lifecycle events to original QtActivity.
  5. When the interstitial ad is open my activity is paused and stopped (onPaused / onStopped event handlers are called in Java and onApplicationStateChanged with Qt::ApplicationInactive / Qt::ApplicationSuspended respectively ) and when the interstitial ad is closed my activity is resumed but in different ways either with onRestart.
(more…)

Updating my Google Play app settings.

I switched the advertising on at Store Presence->Pricing & Distribution page:

(more…)

Parsing GUID in C++ with a regular expression

The code below demonstrates how to parse GUID in C++ using a regular expression:

#include <iostream>
#include <string>
#include <regex>

int main()
{
    static const std::wregex regex(L"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}");
    
    std::wstring sample = L"850fe1da-0ea6-c1a8-9810-0c1cece30698";

    std::match_results<std::wstring::const_iterator> match;

    if (std::regex_match(sample, match, regex))
    {
        std::wcout << L"matches" << std::endl;
    }
    else
    {
        std::wcout << L"does not match" << std::endl;
    }

    return 0;
}
(more…)

A simple example demonstrating how std::forward works in C++

For example, std::forward comes to play if I implement a template container with two ‘insert‘ function overloads that take the parameters of type const T & and T && respectively. I implement all the private insertion logic with T&&, but when I need to know the original value type passed to ‘insert‘ method I use std::forward as shown in the example below:

#include <iostream>
#include <string>

class Value
{
public:

    Value(const char * sz) : m_s(sz)
    {
    }

    Value(const Value & other) : m_s(other.m_s)
    {
        std::cout << "copy constructor: " << m_s << std::endl;
    }

    Value(Value && other) : m_s(std::move(other.m_s))
    {
        std::cout << "move constructor: " << m_s << std::endl;
    }

    const std::string & ToString() const
    {
        return m_s;
    }

private:

    std::string m_s;
};
(more…)

Compiling OpenSSL 1.1 with MSVC2017 for using with QT 5.13

QT does not work with OpenSSL 1.0 anymore. Versions QT 5.12.4 and above require OpenSSL 1.1, but fortunately OpenSSL 1.1 can be easily compiled with MS2017 as follows:

set PATH=%PATH%;C:\Perl64\bin
set PATH=%PATH%;C:\PFiles\nasm-2.14.02-win64
perl Configure VC-WIN64A
nmake

The key to the success is using ‘VS2017 x64 Native Tools Command Prompt‘, but not ‘VS2017 Developer Command Prompt’.

To make QT use OpenSSL, two dlls

libcrypto-1_1-x64.dll
libssl-1_1-x64.dll

should be copied to QT binary directory, for example, C:\Qt\Qt5.13.0\5.13.0\msvc2017_64\bin

Oracle Database user and role IDs

Below I provided the results of two following queries:

SELECT USERNAME, USER_ID FROM DBA_USERS ORDER BY USER_ID DESC;
SELECT ROLE, ROLE_ID FROM DBA_ROLES ORDER BY ROLE_ID DESC;

that display Oracle Database 18 users, roles and their IDs:

(more…)

How to change MySQL 5.7 root password

First, check MySQL version:

SHOW VARIABLES LIKE "%version%";
+-------------------------+-------------------------+
| Variable_name           | Value                   |
+-------------------------+-------------------------+
| innodb_version          | 5.7.25                  |
| protocol_version        | 10                      |
| slave_type_conversions  |                         |
| tls_version             | TLSv1,TLSv1.1           |
| version                 | 5.7.25-0ubuntu0.16.04.2 |
| version_comment         | (Ubuntu)                |
| version_compile_machine | x86_64                  |
| version_compile_os      | Linux                   |
+-------------------------+-------------------------+
(more…)

Different type names in different C++ compilers.

The string representation of a type is implementation defined in C++, for example the following code produce the different output with MSVC, GCC and CLang:

#include <string>
#include <iostream>

struct A {};
class B {};

namespace ns
{
    struct X {};
}

int main()
{
    std::cout << typeid(A).name() << ", " << typeid(B).name() << ", " << typeid(ns::X).name() << ", " << typeid(std::string).name() << std::endl;
    return 0;
}
(more…)

Determining .NET Framework version from the native C++ code.

.NET Framework version 4.5 and higher can be determined with the following C++ code:

#include <windows.h>

bool IsDotNet45Installed()
{
    DWORD value{};
    DWORD dataSize = sizeof(value);
        
    const LONG retCode = ::RegGetValue(
        HKEY_LOCAL_MACHINE,
        L"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\",
        L"Release",
        RRF_RT_REG_DWORD,
        nullptr,
        &value,
        &dataSize
    );

    if (retCode != ERROR_SUCCESS)
    {
        return false;
    }

    return value >= 378389;
}
(more…)