Skip to main content

This program demonstrates the use of MassTransit's NewId library for generating sequential, time-based GUIDs (Globally Unique Identifiers) that maintain chronological ordering.

/*
 * NewId Examples
 *
 * This program demonstrates the use of MassTransit's NewId library for generating
 * sequential, time-based GUIDs (Globally Unique Identifiers) that maintain chronological ordering.
 *
 * Examples:
 * 1. Basic NewId generation - Creating sequential GUIDs
 * 2. Chronological sorting - Showing how NewId GUIDs naturally sort in chronological order
 * 3. Dictionary ordering - Demonstrating NewId GUIDs as chronologically sortable keys
 *
 * Additional examples in comments show how these IDs can be used with PostgreSQL databases.
 */

using DotnetNewId.Console;
using MassTransit;

// Example 1: Basic NewId generation
var ids = Enumerable.Range(0, 10).Select(
        _ => NewId.Next().ToGuid())
    .ToList();

// write the list of ids to the console
Console.WriteLine("Example 1: Basic NewId generation");
Console.WriteLine(string.Join(Environment.NewLine, ids));
Console.WriteLine();

// Example 2: Chronological sorting with NewId
Console.WriteLine("Example 2: Chronological sorting with NewId");

// Create a list of items with timestamps
var items = new List<Item>();
for (int i = 0; i < 5; i++)
{
    var item = new Item
    {
        Id = NewId.Next().ToGuid(),
        Value = $"Item {i}",
        CreatedAt = DateTime.Now
    };
    items.Add(item);
    Console.WriteLine($"Created: {item}");
    Thread.Sleep(200); // Wait to ensure different timestamps
}

Console.WriteLine();

// Shuffle the items randomly
var random = new Random();
var shuffledItems = items.OrderBy(_ => random.Next()).ToList();

// Display the shuffled items
Console.WriteLine("Items in random order:");
foreach (var item in shuffledItems)
{
    Console.WriteLine(item);
}

Console.WriteLine();

// Sort items by NewId and display
var sortedItems = shuffledItems.OrderBy(item => item.Id).ToList();
Console.WriteLine("Items sorted by NewId (chronological order):");
foreach (var item in sortedItems)
{
    Console.WriteLine(item);
}

Console.WriteLine();

// Example 3: Demonstrating NewId ordering with a dictionary
Console.WriteLine("Example 3: NewId ordering in a dictionary/bag of values");

// Create a dictionary with Guid keys
var bag = new Dictionary<Guid, string>();

Console.WriteLine("Adding items to bag with timestamps...");
for (int i = 0; i < 5; i++)
{
    var id = NewId.Next().ToGuid();
    var timestamp = DateTime.Now;
    bag.Add(id, $"Value {i} created at {timestamp:HH:mm:ss.fff}");
    Console.WriteLine($"Added key {id} at {timestamp:HH:mm:ss.fff}");
    Thread.Sleep(200);
}

// Sort the keys and display in order
var sortedKeys = bag.Keys.OrderBy(k => k).ToList();
Console.WriteLine("\nBag items by sorted Guid keys (chronological order):");
foreach (var key in sortedKeys)
{
    Console.WriteLine($"{key} - {bag[key]}");
}

namespace DotnetNewId.Console
{
    // Define an item class that contains a Guid
    public class Item
    {
        public Guid Id { get; init; }
        public required string Value { get; init; }
        public DateTime CreatedAt { get; init; }

        public override string ToString() => $"{Id} - {Value} (Created: {CreatedAt:HH:mm:ss.fff})";
    }
}

/*
PostgreSQL Database Example for the Item Class
----------------------------------------------

-- Enable UUID extension if not already enabled
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- Create table for Item objects
CREATE TABLE items (
    id UUID PRIMARY KEY,
    value TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL
);

-- Insert an Item with a NewId GUID
-- Note: In PostgreSQL, we don't need to convert the GUID format as it accepts the standard format directly
INSERT INTO items (id, value, created_at)
VALUES
    ('11223344-5566-7788-9900-aabbccddeeff', 'Item 1', NOW()),
    ('22334455-6677-8899-00aa-bbccddeeff00', 'Item 2', NOW());

-- If generating IDs in PostgreSQL that should match NewId's sortable pattern,
-- you could use uuid_generate_v1() which creates time-based UUIDs:
INSERT INTO items (id, value, created_at)
VALUES (uuid_generate_v1(), 'Generated in PostgreSQL', NOW());

-- Query items in chronological order (same as NewId's natural ordering)
SELECT * FROM items ORDER BY id;
*/