Storing data

MySql, MariaDB, PostgreSQL

MySql or MariaDB are supported. Data are stored into "passings" table and the table is created if not already present. The design of the table can be improved by indexes, partitions etc; once created in the database

Connecting to database using --db parameter:

  • Mysql and MariaDB example connecting to mysql database:
ammc-amb.exe --db mysql://root:password@localhost:3306/mysql 192.168.1.11
  • PostgreSQL example connecting to postgres database:
ammc-amb.exe --db postgresql://postgres:mysecretpassword@localhost:5432/postgres 192.168.1.11

Need any other database? Let us know

The passings table

AMMC creates the table itself. On every start, right after connecting, it runs

CREATE TABLE IF NOT EXISTS passings (...)

so the first run against an empty database sets everything up and no manual step is needed. One row is inserted per passing, with these columns:

ColumnHolds
idauto-increment row id
passing_numberthe decoder's own counter
timertc_time as text, exactly as the decoder reported it
decoder_idwhich decoder recorded it
transponder, tran_codethe transponder number and/or its code
strength, hits, loop_idsignal detail, where the decoder sends it
low_battery, resend, modified, gps_lockedflags
track_infothe --trackId / --trackName values as JSON, see Track info
insertedwhen AMMC wrote the row, defaulted by the database

The schema is never upgraded

CREATE TABLE IF NOT EXISTS does exactly what it says: if the table is already there, AMMC leaves it completely alone. It does not compare it with what the current version expects, and it never runs an ALTER TABLE. There are no migrations at all.

That is deliberate — the table is yours, and AMMC will not rewrite it under you — but it has one consequence worth knowing. If a newer AMMC adds a column and your database still has a table created by an older one, every insert fails, because the insert names its columns explicitly. Failed inserts are retried forever, so you get a log full of

[WARN  ammc_db] Error inserting to DB, ..., queued for local retry

and nothing is stored. track_info is the column most likely to be missing, as it was added after the others.

The fix is one statement. Either add what is missing:

ALTER TABLE passings ADD COLUMN track_info text;

or, if you do not need the old rows, let AMMC rebuild the table from scratch:

RENAME TABLE passings TO passings_old;   -- MySQL / MariaDB
ALTER TABLE passings RENAME TO passings_old;   -- PostgreSQL

and restart AMMC. Check the log after any AMMC upgrade — a working converter and an empty table together always mean a schema mismatch.

Tuning the table

Because AMMC never touches an existing table, anything you add to it survives upgrades. It creates no indexes of its own beyond the primary key, so on a database that has collected a season of racing it is worth adding:

CREATE INDEX idx_passings_number ON passings (passing_number);
CREATE INDEX idx_passings_inserted ON passings (inserted);

The first speeds up your own queries; the second speeds up -r, which finds the last stored passing by ordering on inserted.

Partitioning, extra columns, triggers and views are all safe for the same reason.

The MySQL row limit

On MySQL and MariaDB the id column is a MEDIUMINT, which stops at 8 388 607 rows — counted over the lifetime of the table, not rows currently present, since deleting rows does not reuse the numbers. Past that, every insert is rejected with

ERROR 167 (22003): Out of range value for column 'id'

and, as above, AMMC retries forever and stores nothing. Most users will never reach it; a permanent installation logging every practice session for years can. Raising it is one statement, and it can be done before or after the fact:

ALTER TABLE passings MODIFY id BIGINT NOT NULL AUTO_INCREMENT;

PostgreSQL uses a SERIAL, which stops at 2 147 483 647 — far enough away not to matter in practice.

Hiding the connection string

The --db parameter contains the database password in plain text, so it is visible in a shortcut, a service definition or a process list. AMMC can take the same connection string base64-encoded instead, using --de:

ammc-amb.exe --de bXlzcWw6Ly9yb290OnBhc3N3b3JkQGxvY2FsaG9zdDozMzA2L215c3Fs 192.168.1.11

The value is the whole connection string encoded, not just the password. Produce it with:

  • Linux / macOS
printf 'mysql://root:password@localhost:3306/mysql' | base64
  • Windows PowerShell
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('mysql://root:password@localhost:3306/mysql'))

Use printf rather than echo on Linux and macOS: echo appends a newline, which becomes part of the encoded value.

If both --db and --de are given, --de wins. If the value is not valid base64, AMMC logs Invalid DBE url and starts with no database at all — passings are still converted, but nothing is stored, so check the log after changing it.

This is encoding, not encryption. Base64 only stops the password being readable at a glance; anyone who can see the command line can decode it in a second. Treat an encoded connection string as just as sensitive as a plain one, and rely on database permissions and network access control for real protection.

Common database parameters

-c sets how long AMMC waits for the database to connect, and -y how many parallel connections the pool may open. Both are listed with their defaults and environment variables on Parameters.