Database GNATCOLL or ado

I have an sqlite database which I wish to access with Ada. I found two APIs both with one document and no example programs:

  • GNATCOLL
  • ADO

GNATCOLL seems relatively straightforward once you’ve figured out what with and use statements the authors were using when they wrote the documentation and also what with statements to use with alire.

ADO documentation is interspersed with XML, YAML and dynamo and quite difficult to follow. If I skip the dynamo bit and make direct calls to ADO, it complains about missing drivers. If I add an initialize routine for the drivers, it complains about missing tables.

I was wondering which is the current preferred way of accessing databases: ADO or GNATCOLL?

Simple components has some SQL bindings and examples:

Ah a third method.

I had a look at this earlier. There is some explanation and it gives the source code but no example code. The Simple Components SQL interface looks very similar to that of GNATCOLL.

Problem is, since it is a http website, I can get to it at home but not at work. Chrome and work blocks any downloading because it is not https.

The library comes with example code. Try cloning or viewing the Alire version here (https): GitHub - alire-project/dak_simple_components: Simple Components by Dmitry A. Kazakov

There are multiple SQL test examples. Here is just one of them: dak_simple_components/test_components/test_sqlite_persistence.adb at da9b0f3a3d56a2e60490fa5f23ca510862c252cd · alire-project/dak_simple_components · GitHub

Here is another example: dak_simple_components/test_components/test_sqlite_benchmark.adb at da9b0f3a3d56a2e60490fa5f23ca510862c252cd · alire-project/dak_simple_components · GitHub

Here is an example using GNATCOLL:

BTW, the actual version is here: Simple components for Ada

SQLite source is a part of the project, so it is statically linked to.

Unfortunately, I cannot push things to Alire for several reasons. I would gladly do it if Alire supported automated upload and a root gpr file with basic target settings. It is simply impossible to me to do this manually because Simple Components is actually about 23 more or less independent projects, each one must be crate. For example you likely would not need an implementation of ELV eQ3 protocol when using SQLite or JSON parser!

The list of projects is here: Simple components for Ada

Yep, but the OP indicated that he cannot access websites that come from “http” addresses only and needs a website that provides “https”, which your website doesn’t appear to support. A lot of companies are moving to this security requirement.

If I understand you correctly, I believe Alire supports a root gpr file. Can you maybe elaborate a bit more here?

I need variables:

  • Target OS, e.g. Windows, Linux, OSX, FreeBSD
  • Target architecture: X86_64, aarch64, i686, armhf.
  • 64-bit vs. 32-bit. E.g. Microsoft ODBC bindings differ for 32 and 64 bits!
  • Pragma atomic, how many bits are supported by the compiler, e.g. 32-bit, 64-bit, 128-bit.
  • Stream_Element_Offset size in the standard library, 32-bit, 64-bit. Note this is independent on the architecture. You can have 32-bit i686 and 64-bit offsets.

The sources are selected according to a combination of these settings.

Interesting. I will contact my hosting.

If the old Bill Shakespeare wrote Henry IV today he would probably replace “Let’s kill all the lawyers” with “Let’s kill all the IT.” :rofl:

Forgot to mention, Simple Components are mirrored here: Simple components for Ada download | SourceForge.net

1 Like

Anything you can do in a single GPR file, you can also do from alire. You can pass in variables externally from alire straight to the GPR file using the -- switch with build or run:

Pass alr build switches to gprbuild

You can also setup an aggregate project just for Alire that can call your custom gpr file with whatever external variables example

Not saying you should change anything up necessarily, but just wanted you to know there may be more options than you think.

I don’t know values of these variables! Alire knows the target and I want Alire describing the target, e.g. in the form of some standard gpr-file Alire would generate upon installation of GNAT. Then I could include this file into my project file.

Thanks. This is very similar to C# linq. I have yet to use this approach on a complicated query. I was just looking for something simple like

with GNATCOLL.SQL.Sqlite;
with GNATCOLL.SQL.Exec; use GNATCOLL.SQL.Exec;

procedure A27sqlcoll is
    db_desc: Database_Description;
    db_conn: Database_Connection;
    query: Prepared_Statement;
    cursor: Forward_Cursor;
begin
   db_desc := GNATCOLL.SQL.Sqlite.Setup("blueline.db");
   db_conn := db_desc.Build_Connection;
   
   -- Try a query with one entry
   query := Prepare(
      "select count(*) from vartype",
      use_cache => True);

   cursor.Fetch(db_conn, query);

   if Has_Row(cursor) then
      put_line("Count " & Value(cursor,0));
   else
      put_line("SQL unsuccessful");
   end if;

   -- Now do a query with more than one entity
   query := Prepare(
      "select * from vartype",
      use_cache => True);

   cursor.Fetch(db_conn, query);

   while Has_Row(cursor) loop
      put("PK:" & Value(cursor,0));
      put_line("  variant:" & Value(cursor,1));
      Next(cursor);
   end loop;

   Free(db_conn);
   Free(db_desc);
end A27sqlcoll;

That way, I can put all the queries into an external file and change the SQL without having the rebuild the code.

Just to throw another option out there, I wrote a binding too. It doesn’t implement the whole API, just the parts I needed for a specific application. Should be straightforward to extend if necessary.

Specification
Example

You can add it to your project with

alr with sqlite3 --use=https://github.com/JeremyGrosser/sqlite3_binding
1 Like

@JeremyGrosser I am getting

sqlite3.c:(.text.fts5Bm25Function+0x46c): undefined reference to `log'

Looks like it is missing a -lm somewhere but I don’t know how to add it in alire. I got around it by adding with Ada.Numerics.Elementary_Functions to the program but what is the proper way of doing this.

I tried alr with libm but it tells me that libm doesn’t exist.

Try adding this to your project’s gpr file:

package Linker is
      for Switches ("Ada") use ("-lm");
end Linker;

I don’t know if this is the proper way, but it is ‘a’ way

In the project I’m looking at, I also have -ldl but I can’t remember if that was for SQLite or something else

@JeremyGrosser the linker trick works.

libdl is for dload stuff: dynamically loading libraries.