Airline Reservation Example

Consider the following xcpp code which represents a CDM schema for an airplane reservation system

(note that this is an entirely fictitious example and not intended to be realistic, to illustrate the support for data replication and synchronisation)


$typedef+ assignable<string8> TString;    // UTF-8

/////////// Date-time

$enum+ class TMonth
{
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
};
    
$model+ TDate
{
    int16 Year;
    TMonth Month;   // 1-12
    int8 Day;       // 1-31
};

$model+ TTime
{
    int8 Hour;      // 0-23
    int8 Minute;    // 0-59
    int8 Second;    // 0-59
};

$model+ TDateTime <<multiline>>
{
    TDate Date;
    TTime Time;
};

/////////// Address
    
$model+ TAddress <<multiline>>
{
    TString Street;
    TString City;
    TString State;
    TString PostalCode;
};
    
/////////// Passenger

$enum+ class TSex
{
    Male,
    Female
};

$enum+ class TMarriedStatus
{
    Single,
    Married
};

$model+ TPassenger <<multiline>>
{
    TString LastName;
    TString FirstName;
    TAddress Address;
    TSex Sex;
    assignable<TDate> DateOfBirth;
    TMarriedStatus MarriedStatus;
    TString PhoneNumber;
    TString EmailAddress;
    int32 FrequentFlyerMiles;
};

/////////// AirPlane
    
$typedef+ int32 TSeatNumber;
    
$enum+ class TSeatType
{
    Window,
    Aisle
};

$enum+ class TSeatClass
{
    First,
    Business,
    Economy
};

$enum+ class TSmoking
{
    Smoking,
    NonSmoking
};
    
$model+ TSeatInfo <<multiline>>
{
    int32 Level;
    int32 Row;
    char8 Pos;          // '0'-'5'
    TSmoking Smoking;
    TSeatType SeatType;
    TSeatClass SeatClass;
};
    
$enum+ class TAirplaneMake
{
    Boeing,
    Airbus,
    Bombardier,
    Embraer,
    Raytheon,
    Cessna
};
    
$model+ TAirPlane <<multiline>>
{
    TAirplaneMake AirPlaneMake;
    TString ModelNumber;
    TString RegistrationNumber;
    int32 SeatingCapacity;
    float64 CruisingSpeed;
    xmap<TSeatNumber,TSeatInfo> SeatInfo;
};

/////////// Flight
    
$model+ TEftPOS
{
    bool DomesticOnly;
    bool ChipEnabled;
    TString AccountName;
};

$model+ TCheque
{
    int32 Number;
    TString AccountName;
};
    
$variant+ TPayment
{
    void;
    TEftPOS;
    TCheque;
};

$typedef+ float64 TWeight;

$model+ TSeatAllocation <<multiline>>
{
    assignable<TDateTime> DateTime;
    bool Allocated;
    TPassenger Passenger;
    TPayment Payment;
    xvector<TWeight> BaggageItems;
};
    
$typedef+ int32 TFlightNumber;
$typedef+ int32 TGate;
$typedef+ TString TAirline;
    
$model+ TAirport <<multiline>>
{
    TString IATACode;
    TString City;
    TString Country;
};

$class+ TFlight <<multiline>> isa IPersistable :
    model
    {
        TAirline AirLine;
        TAirPlane AirPlane;
        xmap<TSeatNumber, TSeatAllocation> SeatAllocations;
        TFlightNumber FlightNumber;

        assignable<TDateTime> DepartureDateTime;
        TAirport DepartureAirport;
        TGate DepartureGate;

        assignable<TDateTime> ArrivalDateTime;
        TAirport ArrivalAirport;
        TGate ArrivalGate;
    }
{
};

$class+ TAirplaneReservationSystem isa IPersistable :
    model
    {
        xvector<movable<cref<TFlight> > > Flights;
    }
{
public:
    TFlight& AddFlight()
    {
        TFlight* f = $new TFlight;
        Flights.insert(0,f);
        return *f;
    }    
};

The following C++ code creates a database containing two independent working sets, populates one with some data and creates a TCP socket connection to allow them to synchronise


xstring path = GetCedaTestPath("AirplaneReservationSystem.ceda");
        
std::cout << "Open persistent store\n";
PersistStore* pstore = OpenPersistStore(path.c_str(),OM_CREATE_ALWAYS);
{
    std::cout << "Open PSpace\n";
    WPSpace pspace(OpenPSpace(pstore, "MyPSpace"));

    std::cout << "Open two working sets\n";
    WorkingSetMachine* ws1 = nullptr;
    WorkingSetMachine* ws2 = nullptr;
    {
        CSpaceTxn txn;
        ws1 = OpenWorkingSetMachine("WS1",true);
        ws2 = OpenWorkingSetMachine("WS2",false);
    }
            
    {
        Iocp* iocp = CreateIocp();
        MServer* server;
        MClient* client;
        {
            std::cout << "Open client and server\n";
            CSpaceTxn txn;
            const WsipcSessionProtocolId protocolId = { "AirlineReservation", 1 };
            server = CreateWsipcServer(iocp, ws1, protocolId, 3000);
            client = CreateWsipcClient(iocp, ws2, protocolId, "127.0.0.1", 3000);
        }
                
        {
            std::cout << "Create AirplaneReservationSystem on first working set\n";
            CSpaceTxn txn;
            UTRoot& r = GetUTRoot(ws1);
            TAirplaneReservationSystem* s1 = $new TAirplaneReservationSystem;
            r.Map["AirlineReservationSystem"].insert(0,s1);
            TFlight& f = s1->AddFlight();
            f.AirLine = "Quantas";
            f.AirPlane.AirPlaneMake = TAirplaneMake::Boeing;
            f.AirPlane.ModelNumber = "747-400";
            f.AirPlane.RegistrationNumber = "R-1025";
            f.AirPlane.SeatingCapacity = 416;
            f.AirPlane.CruisingSpeed = 920.0;   // km/h
            for (int i=0 ; i < 6 ; ++i)
            {
                f.AirPlane.SeatInfo[i].Level = 1;
                f.AirPlane.SeatInfo[i].Row = 1+i/3;
                f.AirPlane.SeatInfo[i].Pos = '0' + i%3;
                f.AirPlane.SeatInfo[i].Smoking = TSmoking::Smoking;
                f.AirPlane.SeatInfo[i].SeatType = (i==0 || i == 2) ? TSeatType::Window : TSeatType::Aisle;
                f.AirPlane.SeatInfo[i].SeatClass = TSeatClass::First;
            }
        }

        {
            std::cout << "Generate operations on first working set\n";
            CSpaceTxn txn;
            TAirplaneReservationSystem* s1 = 
                GetUTRootEntry<TAirplaneReservationSystem>(ws1,"AirlineReservationSystem");
            TFlight& f = *s1->Flights.read()[0];
            f.SeatAllocations[0].DateTime = TDateTime( TDate(2009,TMonth::February,10), TTime(21,17,23) );
            f.SeatAllocations[0].Allocated = true;
            f.SeatAllocations[0].Passenger.FirstName = "Jane";
            f.SeatAllocations[0].Passenger.LastName = "Smith";
            f.SeatAllocations[0].Passenger.Address.Street = "Old Kent Road";
            f.SeatAllocations[0].Passenger.Address.City = "London";
            f.SeatAllocations[0].Passenger.DateOfBirth = TDate(1985,TMonth::June,23);
            f.SeatAllocations[0].Passenger.Sex = TSex::Female;
            f.SeatAllocations[0].Payment = TEftPOS(true,true,"Joe Smith");
            f.SeatAllocations[0].BaggageItems.push_back(24.7);
            f.SeatAllocations[0].BaggageItems.push_back(12.2);
            f.FlightNumber = 10;
            f.DepartureDateTime = TDateTime( TDate(2009,TMonth::February,10), TTime(22,30,00) );
            f.DepartureGate = 22;
            f.DepartureAirport.IATACode = "PER";
            f.DepartureAirport.City = "Perth";
            f.DepartureAirport.Country = "Australia";
            f.ArrivalDateTime = TDateTime( TDate(2009,TMonth::February,11), TTime(05,12,00) );
            f.ArrivalGate = 7;
            f.ArrivalAirport.IATACode = "LHR";
            f.ArrivalAirport.City = "London";
            f.ArrivalAirport.Country = "England";
        }

        std::cout << "Wait for operations to be applied to second working set\n";
        while(1)
        {
            Sleep(10);
            CSpaceTxn txn;
            if (HistoryBufferSize(ws2) == 2) break;
        }
                
        {
            std::cout << "Show result on second working set\n";
            CSpaceTxn txn;

            TAirplaneReservationSystem* s2 = 
                GetUTRootEntry<TAirplaneReservationSystem>(
                    ws2,"AirlineReservationSystem");
            TFlight& f = *s2->Flights.read()[0];
            PrintInstance(std::cout, &f);
        }
        Close(server);
        Close(client);
        Close(iocp);
    }
    Close(ws1);
    Close(ws2);
}
Close(pstore);

This is the generated output:


Open persistent store
Open PSpace
Open two working sets
Open client and server
Create AirplaneReservationSystem on first working set
Generate operations on first working set
Wait for operations to be applied to second working set
Show result on second working set

TFlight
{
    AirLine = Quantas
    AirPlane = TAirPlane
    {
        AirPlaneMake = Boeing
        ModelNumber = 747-400
        RegistrationNumber = R-1025
        SeatingCapacity = 416
        CruisingSpeed = 920
        SeatInfo =
        {
            0 --> TSeatInfo
            {
                Level = 1
                Row = 1
                Pos = 0
                Smoking = Smoking
                SeatType = Window
                SeatClass = First
            }
            1 --> TSeatInfo
            {
                Level = 1
                Row = 1
                Pos = 1
                Smoking = Smoking
                SeatType = Aisle
                SeatClass = First
            }
            2 --> TSeatInfo
            {
                Level = 1
                Row = 1
                Pos = 2
                Smoking = Smoking
                SeatType = Window
                SeatClass = First
            }
            3 --> TSeatInfo
            {
                Level = 1
                Row = 2
                Pos = 0
                Smoking = Smoking
                SeatType = Aisle
                SeatClass = First
            }
            4 --> TSeatInfo
            {
                Level = 1
                Row = 2
                Pos = 1
                Smoking = Smoking
                SeatType = Aisle
                SeatClass = First
            }
            5 --> TSeatInfo
            {
                Level = 1
                Row = 2
                Pos = 2
                Smoking = Smoking
                SeatType = Aisle
                SeatClass = First
            }
        }
    }
    SeatAllocations =
    {
        0 --> TSeatAllocation
        {
            DateTime = TDateTime
            {
                Date = TDate(2009,February,10)
                Time = TTime(21,17,23)
            }
            Allocated = 1
            Passenger = TPassenger
            {
                LastName = Smith
                FirstName = Jane
                Address = TAddress
                {
                    Street = Old Kent Road
                    City = London
                    State =
                    PostalCode =
                }
                Sex = Female
                DateOfBirth = TDate(1985,June,23)
                MarriedStatus = Single
                PhoneNumber =
                EmailAddress =
                FrequentFlyerMiles = 0
            }
            Payment = TEftPOS(1,1,Joe Smith)
            BaggageItems = [24.7,12.2]
        }
    }
    FlightNumber = 10
    DepartureDateTime = TDateTime
    {
        Date = TDate(2009,February,10)
        Time = TTime(22,30,0)
    }
    DepartureAirport = TAirport
    {
        IATACode = PER
        City = Perth
        Country = Australia
    }
    DepartureGate = 22
    ArrivalDateTime = TDateTime
    {
        Date = TDate(2009,February,11)
        Time = TTime(5,12,0)
    }
    ArrivalAirport = TAirport
    {
        IATACode = LHR
        City = London
        Country = England
    }
    ArrivalGate = 7
}