mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 10:21:08 -04:00
File > New restarted its counter every day while names only carry the year, so the first nest of each day was always N26-223, and each PC kept its own counter. In Database mode the nest server now hands out the year's next number (POST /api/nest-names/next, nest_sequences table, schema v6), staying above every stored generated name so offline or pre-existing names are never reissued. The per-PC counter remains the fallback when the server is unreachable or older, resets per year, and is raised past each server allocation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.5 KiB
C#
68 lines
2.5 KiB
C#
using OpenNest.Data;
|
|
|
|
namespace OpenNest.Server;
|
|
|
|
public sealed partial class NestDatabase
|
|
{
|
|
private const string NestSequenceSchema = """
|
|
CREATE TABLE IF NOT EXISTS nest_sequences (
|
|
year INTEGER PRIMARY KEY,
|
|
next INTEGER NOT NULL
|
|
);
|
|
PRAGMA user_version=6;
|
|
""";
|
|
|
|
/// <summary>
|
|
/// Allocates the next nest number for <paramref name="year"/>, shared by every client.
|
|
/// The number is also kept above every stored generated name for the year (active or
|
|
/// deleted), so names created offline or before the server counted are never reissued.
|
|
/// </summary>
|
|
public int AllocateNestNumber(int year)
|
|
{
|
|
if (year is < NestNames.MinYear or > NestNames.MaxYear)
|
|
throw new ArgumentOutOfRangeException(nameof(year));
|
|
|
|
lock (_sync)
|
|
{
|
|
using var transaction = _connection.BeginTransaction();
|
|
var next = 1;
|
|
using (var command = _connection.CreateCommand())
|
|
{
|
|
command.Transaction = transaction;
|
|
command.CommandText = "SELECT next FROM nest_sequences WHERE year=$year";
|
|
command.Parameters.AddWithValue("$year", year);
|
|
if (command.ExecuteScalar() is long stored)
|
|
next = checked((int)stored);
|
|
}
|
|
|
|
using (var command = _connection.CreateCommand())
|
|
{
|
|
command.Transaction = transaction;
|
|
command.CommandText = "SELECT name FROM nests WHERE name LIKE $prefix";
|
|
command.Parameters.AddWithValue("$prefix", $"N{year % 100:D2}-%");
|
|
using var reader = command.ExecuteReader();
|
|
while (reader.Read())
|
|
{
|
|
if (NestNames.TryParse(reader.GetString(0), year, out var used) && used >= next)
|
|
next = checked(used + 1);
|
|
}
|
|
}
|
|
|
|
using (var command = _connection.CreateCommand())
|
|
{
|
|
command.Transaction = transaction;
|
|
command.CommandText = """
|
|
INSERT INTO nest_sequences (year, next) VALUES ($year, $next)
|
|
ON CONFLICT(year) DO UPDATE SET next = excluded.next
|
|
""";
|
|
command.Parameters.AddWithValue("$year", year);
|
|
command.Parameters.AddWithValue("$next", checked(next + 1));
|
|
command.ExecuteNonQuery();
|
|
}
|
|
|
|
transaction.Commit();
|
|
return next;
|
|
}
|
|
}
|
|
}
|