Pizza deliveries database Example

Xc++ schema


namespace pizza
{
    $typedef+ int32 TToppingId;
    $typedef+ int32 TEmployeeId;
    $typedef+ int32 TVehicleTypeId;
    $typedef+ int32 TVehicleId;
    $typedef+ int64 TCustomerId;
    $typedef+ int64 TOrderId;
    $typedef+ float64 TCurrency;
    $typedef+ assignable<string8> TEmail;
    $typedef+ assignable<string8> TPhoneNumber;

    $model+ TAddress
    {
        int32 Number;
        assignable<string8> Street;
        assignable<string8> City;
        int32 ZipPostCode;
        assignable<string8> StateProvinceCounty;
        assignable<string8> Country;
    };

    $model+ TEmployee
    {
        TAddress Address;
        assignable<string8> FirstName;
        assignable<string8> LastName;
        TPhoneNumber PhoneNumber;
    };

    $model+ TVehicleType
    {
        assignable<string8> Description;
    };

    $model+ TVehicle
    {
        TVehicleTypeId VehicleTypeId;
        assignable<string8> LicensePlateNumber;
    };

    $enum+ class EPaymentMethod
    {
        Cash,
        EftPos,
        CreditCard
    };

    $model+ TCustomer
    {
        TAddress Address;
        assignable<string8> FirstName;
        assignable<string8> LastName;
        TPhoneNumber PhoneNumber;
        TEmail Email;
        dt::TDateTime DateOfFirstOrder;
        EPaymentMethod PaymentMethod;
    };

    $enum+ class EDeliveryStatus
    {
        Cooking,
        Delivering,
        Completed,
        Returned
    };

    $enum+ class EBaseType
    {
        Thin,
        DeepPan
    };

    $model+ TCircle
    {
        float32 Radius;    
    };

    $model+ TRectangle
    {
        float32 Width;
        float32 Height;
    };

    $variant+ TShape
    {
        default TCircle(200);
        TCircle Circle;
        TRectangle Rectangle;
    };
    
    $model+ TTopping
    {
        TCurrency Price;
        assignable<string8> Description;
    };

    $model+ TOrderedPizza
    {
        TShape Shape;
        EBaseType BaseType;
        xvector<TToppingId> ToppingIds;
    };

    $struct+ TPizzaOrder isa ceda::IPersistable :
        model
        {
            TOrderId Id;
            TCustomerId CustomerId;
            TEmployeeId TakenByEmployeeId;
            TEmployeeId DeliveredByEmployeeId;
            EDeliveryStatus DeliveryStatus;
            TVehicleId VehicleId;
            dt::TDateTime DateTimeOrderTaken;
            dt::TDateTime DateTimeOrderDelivered;
            TCurrency TotalOrderPrice;
            xvector<TOrderedPizza> Pizzas;
        }
    {
    };

    $struct+ TPizzaDeliveryDatabase isa ceda::IPersistable :
        model
        {
            xmap<TVehicleId, TVehicle> Vehicles;
            xmap<TVehicleTypeId, TVehicleType> VehicleTypes;
            xmap<TEmployeeId, TEmployee> Employees;
            xmap<TToppingId, TTopping> Toppings;
            xmap<TCustomerId, TCustomer> Customers;
            xvector< movable< cref<TPizzaOrder> > > Orders;
        }
    {
    };
}

Python


def printMap(name,m):
    print('  len({}) = {}'.format(name, len(m)))
    for key in m:
        print('  {}.has_key({}) = {}'.format(name, key, m.has_key(key)))
    for key in m:
        print('  {} in {} = {}'.format(key, name, key in m))
    for key in m.iterkeys():
        print('  {}[{}] = {}'.format(name, key, m[key]))
    for value in m.itervalues():
        print('  value: {}'.format(value))
    for item in m.iteritems():
        print('  item: {}'.format(item))
    for key,value in m.iteritems():
        print('  key: {}  value: {}'.format(key,value))

def selectDate():
    y = random.randint(2016,2017)
    m = random.randint(0,11)
    d = random.randint(1,28)
    return dt.TDate(Year=y,Month=m,Day=d)

def selectTime():
    h = random.randint(0,23)
    m = random.randint(0,59)
    return dt.TTime(Hour=h,Minute=m,Second=0)

def selectDateTime():
    return dt.TDateTime(selectDate(), selectTime())

def setDate(d):
    d.Year = random.randint(2016,2017)
    d.Month = random.randint(0,11)
    d.Day = random.randint(1,28)

def setTime(t):
    t.Hour = random.randint(0,23)
    t.Minute = random.randint(0,59)

def setDateTime(dt):
    setDate(dt.Date)
    setTime(dt.Time)

def addVehicleTypes(pdd):
    for s in [ 'Ford Fiesta', 'Mazda3', 'Kia Rio', 'Toyota Yaris', 'Honda Civic', 'Mitsubishi Lancer', 'Subaru Impreza', 'Volkswagen Passat']:
        id = len(pdd.VehicleTypes)+1
        pdd.VehicleTypes[id].Description = s

def selectLicensePlateNumber():
    s = ''
    for i in range(3):
        s += random.choice(string.ascii_uppercase)
    s += '.'
    for i in range(3):
        s += str(random.randint(0,9))
    return s

def setVehicle(v):
    v.VehicleTypeId = random.randint(1,8)
    v.LicensePlateNumber = selectLicensePlateNumber()

def selectStreet():
    return random.choice([ 'Old Kent Road', 'Mayfair St', 'Oxford St', 'Regent St'])

def selectCity():
    return random.choice([ 'London', 'New York', 'Paris', 'Perth', 'Berlin'])

def selectState():
    return random.choice([ 'Alaska', 'New South Wales', 'Florida', 'California', 'Texas'])

def selectCountry():
    return random.choice([ 'Australia', 'USA', 'England', 'India'])

def selectZipCode():
    return random.randint(1000,9999)

def setAddress(a):
    a.Number = random.randint(1,50)
    a.Street = selectStreet()
    a.City = selectCity()
    a.ZipPostCode = selectZipCode()
    a.StateProvinceCounty = selectState()
    a.Country = selectCountry()

def selectFirstName():
    return random.choice([ 'John', 'Janet', 'Kate', 'Rihanna', 'Peter', 'Greg'])

def selectLastName():
    return random.choice([ 'Smith', 'Matthews', 'Gates', 'Howard', 'Johnson'])

def selectPhoneNumber():
    s = ''
    for i in range(10):
        s += str(random.randint(0,9))
        if i == 3 or i == 6:
            s += ' '
    return s

def setEmployee(e):
    setAddress(e.Address)
    e.FirstName = selectFirstName()
    e.LastName = selectLastName()
    e.PhoneNumber = selectPhoneNumber()

def addEmployee(pdd):
    i = len(pdd.Employees)
    setEmployee(pdd.Employees[i])

def selectCircle():
    return pizza.TCircle(Radius=random.choice([100, 150, 250, 300]))

def selectRectangle():
    return pizza.TRectangle(Width=random.choice([100, 200]), Height=random.choice([200, 300]))

def setShape(s):
    if random.randint(0,2) == 0:
        s.Circle = selectCircle()
    else:
        s.Rectangle = selectRectangle()

def selectTopping():
    return random.choice([ pizza.EBaseType.Thin, pizza.EBaseType.DeepPan])

def selectPizza():
    p = pizza.TOrderedPizza()
    setShape(p.Shape)
    p.BaseType = selectTopping()
    for i in range(random.randint(0,5)):
        p.ToppingIds.append(random.randint(0,10))
    return p

def selectDeliveryStatus():
    return random.choice([ pizza.EDeliveryStatus.Cooking, pizza.EDeliveryStatus.Delivering,  pizza.EDeliveryStatus.Completed,  pizza.EDeliveryStatus.Returned])

def createPizzaOrder(id):
    order = pizza.TPizzaOrder(
        Id = id,
        CustomerId = random.randint(1,15),
        TakenByEmployeeId = random.randint(1,9),
        DeliveredByEmployeeId = random.randint(1,9),
        DeliveryStatus = selectDeliveryStatus(),
        VehicleId = random.randint(1,9),
        DateTimeOrderTaken = selectDateTime(),
        DateTimeOrderDelivered = selectDateTime(),
        TotalOrderPrice = random.randint(1000,5000)/100.0,
        Pizzas = [])
    for i in range(random.randint(0,3)):
        order.Pizzas.insert(i,selectPizza())
    return order

def insertSomeOrders(pdd, count):
    for i in range(count):
        pdd.Orders.insert(0, createPizzaOrder())

def appendSomeOrders(pdd, count):
    for i in range(count):
        pdd.Orders.append(createPizzaOrder())

def addOrder(pdd):
    id = len(pdd.Orders)
    pdd.Orders.append(createPizzaOrder(id))

def ReplaceLastPizzaInOrder(pdd,i):
    if pdd.Orders[i].Pizzas:
        pdd.Orders[i].Pizzas.pop()
        pdd.Orders[i].Pizzas.append(selectPizza())

def printOrders(pdd):
    print('Num orders = {}'.format(len(pdd.Orders)))
    for i in range(len(pdd.Orders)):
        order = pdd.Orders[i]
        print(''.format(order))

def printOrdersInTable(pdd):
    print(' Id  CustomerId        Name       Status')
    print('------------------------------------------')
    for i in range(len(pdd.Orders)):
        order = pdd.Orders[i]
        if order.CustomerId in pdd.Customers:
            c = pdd.Customers[order.CustomerId]
            print('{0:>4} {1:>10} {2:>17} {3:>6}'.format(order.Id, order.CustomerId, (str(c.FirstName) + ' ' + str(c.LastName)), order.DeliveryStatus))

def selectEmail():
    return selectFirstName() + '.' + selectLastName() + '@gmail.com'

def selectPaymentMethod():
    return random.choice([ pizza.EPaymentMethod.Cash, pizza.EPaymentMethod.EftPos,  pizza.EPaymentMethod.CreditCard])

def setCustomer(c):
    setAddress(c.Address)
    c.FirstName = selectFirstName()
    c.LastName = selectLastName()
    c.PhoneNumber = selectPhoneNumber()
    c.Email = selectEmail()
    setDateTime(c.DateOfFirstOrder)
    c.PaymentMethod = selectPaymentMethod()

def addCustomer(pdd):
    id = len(pdd.Customers)
    setCustomer(pdd.Customers[id])

def selectToppingPrice():
    return random.randint(100,200)/100.0

def selectToppingDescription():
    return random.choice([ 'Ham', 'Pineapple', 'Chicken', 'Jalapenos', 'Mushrooms', 'Zucchini', 'Garlic', 'Red peppers'])

def setTopping(t):
    t.Price = selectToppingPrice()
    t.Description = selectToppingDescription()

def addTopping(pdd):
    id = len(pdd.Toppings)
    setTopping(pdd.Toppings[id])

def getToppings(pdd):
    d = {}
    for id,topping in pdd.Toppings.iteritems():
        d[id] = (topping.Price, topping.Description)
    return d

def createPizzaDeliveryDatabase():
    pdd = pizza.TPizzaDeliveryDatabase()
    addVehicleTypes(pdd)
    for i in range(10):
        setVehicle(pdd.Vehicles[i+1])
    for i in range(10):
        addCustomer(pdd)
    return pdd

def printPizzaDeliveryDatabase(pdd):
    print(str(pdd))

utRootKey = 'pizzadatabaseroot'

class PizzaDeliveryDatabase(Database):

    def __init__(self, path, createNew):
        Database.__init__(self)
        self.path = path
        self.createNew = createNew

    def __enter__(self):
        Database.open(self, self.path, self.createNew)
        self.bootstrapRootObject(utRootKey, lambda : createPizzaDeliveryDatabase())
        return self

    def __exit__(self, etype, value, tb):
        self.close()

for repeat in range(3):
    createNew = True if repeat==0 else False
    with PizzaDeliveryDatabase(testDirectory + '/mypizzadatabase', createNew) as db:
        pdd = db.rootObj

        if db.justCreated:
            print('Created new database')
        else:
            print('Opened existing database')

        with Txn(db):
            addCustomer(pdd)

        with Txn(db):
            addEmployee(pdd)

        with Txn(db):
            addTopping(pdd)

        with Txn(db):
            for i in range(10):
                addOrder(pdd)

        with Txn(db):
            ReplaceLastPizzaInOrder(pdd,0)

        with Txn(db):
            printOrdersInTable(pdd)

        with Txn(db):
            d = getToppings(pdd)
        print('toppings: {}'.format(d))

Output


Environment variable CEDA_TEST_DIR = R:
Opening R:/mypizzadatabase
Creating IoContextPool with 2 threads
Opening PSpace
Opening working set
Created new database
 Id  CustomerId        Name       Status
------------------------------------------
   1          1   Rihanna Johnson      2
   2          6        Kate Gates      2
   3          9       Kate Howard      3
   4          3       Janet Smith      3
   5          5      Janet Howard      3
   7          2      Kate Johnson      2
   9          8        Kate Gates      1
toppings: {0: (1.36, 'Mushrooms')}
Closing WorkingSet
Closing PSpace
Closing PersistStore
Opening R:/mypizzadatabase
Opening PSpace
Opening working set
Opened existing database
 Id  CustomerId        Name       Status
------------------------------------------
   0         11       John Howard      0
   1          1   Rihanna Johnson      2
   2          6        Kate Gates      2
   3          9       Kate Howard      3
   4          3       Janet Smith      3
   5          5      Janet Howard      3
   7          2      Kate Johnson      2
   9          8        Kate Gates      1
  11          4    Janet Matthews      3
  12          8        Kate Gates      3
  13          8        Kate Gates      2
  14          2      Kate Johnson      1
  15          6        Kate Gates      1
  17         10     Peter Johnson      0
toppings: {0: (1.36, 'Mushrooms'), 1: (1.83, 'Red peppers')}
Closing WorkingSet
Closing PSpace
Closing PersistStore
Opening R:/mypizzadatabase
Opening PSpace
Opening working set
Opened existing database
 Id  CustomerId        Name       Status
------------------------------------------
   0         11       John Howard      0
   1          1   Rihanna Johnson      2
   2          6        Kate Gates      2
   3          9       Kate Howard      3
   4          3       Janet Smith      3
   5          5      Janet Howard      3
   7          2      Kate Johnson      2
   9          8        Kate Gates      1
  11          4    Janet Matthews      3
  12          8        Kate Gates      3
  13          8        Kate Gates      2
  14          2      Kate Johnson      1
  15          6        Kate Gates      1
  16         12     Janet Johnson      0
  17         10     Peter Johnson      0
  18         12     Janet Johnson      1
  20          5      Janet Howard      2
  21          4    Janet Matthews      3
  22         10     Peter Johnson      1
  23          6        Kate Gates      2
  24          1   Rihanna Johnson      2
  26          6        Kate Gates      2
  27          1   Rihanna Johnson      3
  28          8        Kate Gates      3
  29          1   Rihanna Johnson      1
toppings: {0: (1.36, 'Mushrooms'), 1: (1.83, 'Red peppers'), 2: (1.42, 'Zucchini')}
Closing WorkingSet
Closing PSpace
Closing PersistStore

Replication test R:/mypizzadatabase to R:/myreplicatedpizzadatabase
Opening R:/mypizzadatabase
Opening PSpace
Opening working set
Creating IoContextPool with 24 threads
Creating server listening on port 3000
num server operations = 16
Opening R:/myreplicatedpizzadatabase
Opening PSpace
Opening working set
Creating IoContextPool with 24 threads
Creating client connecting to 127.0.0.1:3000
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 0
num client operations = 16
time to sync databases = 0.0160000324249 seconds
TPizzaDeliveryDatabase
{
    Vehicles =
    {
        1 : TVehicle(6,QFR.742)
        2 : TVehicle(4,TYV.421)
        3 : TVehicle(3,QRG.817)
        4 : TVehicle(6,LTI.084)
        5 : TVehicle(3,FFV.342)
        6 : TVehicle(1,MBM.465)
        7 : TVehicle(2,CYX.609)
        8 : TVehicle(2,JNO.075)
        9 : TVehicle(5,SWF.107)
        10 : TVehicle(6,LGR.585)
    }
    VehicleTypes =
    {
        1 : TVehicleType(Ford Fiesta)
        2 : TVehicleType(Mazda3)
        3 : TVehicleType(Kia Rio)
        4 : TVehicleType(Toyota Yaris)
        5 : TVehicleType(Honda Civic)
        6 : TVehicleType(Mitsubishi Lancer)
        7 : TVehicleType(Subaru Impreza)
        8 : TVehicleType(Volkswagen Passat)
    }
    Employees =
    {
        0 : TEmployee
        {
            Address = TAddress
            {
                Number = 32
                Street = Regent St
                City = London
                ZipPostCode = 5687
                StateProvinceCounty = California
                Country = Australia
            }
            FirstName = Kate
            LastName = Matthews
            PhoneNumber = 5822 544 305
        }
        1 : TEmployee
        {
            Address = TAddress
            {
                Number = 11
                Street = Oxford St
                City = Perth
                ZipPostCode = 4747
                StateProvinceCounty = Texas
                Country = England
            }
            FirstName = Peter
            LastName = Matthews
            PhoneNumber = 9847 678 876
        }
        2 : TEmployee
        {
            Address = TAddress
            {
                Number = 43
                Street = Regent St
                City = Perth
                ZipPostCode = 3686
                StateProvinceCounty = California
                Country = USA
            }
            FirstName = Kate
            LastName = Matthews
            PhoneNumber = 0832 970 267
        }
    }
    Toppings =
    {
        0 : TTopping
        {
            Price = 1.36
            Description = Mushrooms
        }
        1 : TTopping
        {
            Price = 1.83
            Description = Red peppers
        }
        2 : TTopping
        {
            Price = 1.42
            Description = Zucchini
        }
    }
    Customers =
    {
        0 : TCustomer
        {
            Address = TAddress
            {
                Number = 19
                Street = Mayfair St
                City = Perth
                ZipPostCode = 8193
                StateProvinceCounty = New South Wales
                Country = USA
            }
            FirstName = Peter
            LastName = Smith
            PhoneNumber = 5020 734 466
            Email = John.Smith@gmail.com
            DateOfFirstOrder = Jul 16 2017 13:12
            PaymentMethod = Cash
        }
        1 : TCustomer
        {
            Address = TAddress
            {
                Number = 36
                Street = Mayfair St
                City = London
                ZipPostCode = 1957
                StateProvinceCounty = Florida
                Country = USA
            }
            FirstName = Rihanna
            LastName = Johnson
            PhoneNumber = 2366 045 956
            Email = Janet.Matthews@gmail.com
            DateOfFirstOrder = May 04 2017 12:16
            PaymentMethod = EftPos
        }
        2 : TCustomer
        {
            Address = TAddress
            {
                Number = 4
                Street = Old Kent Road
                City = New York
                ZipPostCode = 6818
                StateProvinceCounty = Florida
                Country = England
            }
            FirstName = Kate
            LastName = Johnson
            PhoneNumber = 5866 261 752
            Email = Peter.Matthews@gmail.com
            DateOfFirstOrder = Jun 22 2017 09:33
            PaymentMethod = Cash
        }
        3 : TCustomer
        {
            Address = TAddress
            {
                Number = 38
                Street = Oxford St
                City = New York
                ZipPostCode = 1829
                StateProvinceCounty = Florida
                Country = India
            }
            FirstName = Janet
            LastName = Smith
            PhoneNumber = 1185 578 985
            Email = Greg.Smith@gmail.com
            DateOfFirstOrder = Apr 26 2016 15:13
            PaymentMethod = EftPos
        }
        4 : TCustomer
        {
            Address = TAddress
            {
                Number = 15
                Street = Regent St
                City = Berlin
                ZipPostCode = 9889
                StateProvinceCounty = California
                Country = USA
            }
            FirstName = Janet
            LastName = Matthews
            PhoneNumber = 0638 167 937
            Email = Greg.Smith@gmail.com
            DateOfFirstOrder = Mar 26 2016 23:46
            PaymentMethod = Cash
        }
        5 : TCustomer
        {
            Address = TAddress
            {
                Number = 35
                Street = Regent St
                City = Berlin
                ZipPostCode = 1005
                StateProvinceCounty = Alaska
                Country = USA
            }
            FirstName = Janet
            LastName = Howard
            PhoneNumber = 8876 120 774
            Email = Rihanna.Johnson@gmail.com
            DateOfFirstOrder = Mar 26 2016 06:18
            PaymentMethod = Cash
        }
        6 : TCustomer
        {
            Address = TAddress
            {
                Number = 9
                Street = Mayfair St
                City = New York
                ZipPostCode = 7457
                StateProvinceCounty = Florida
                Country = England
            }
            FirstName = Kate
            LastName = Gates
            PhoneNumber = 8041 672 332
            Email = Greg.Smith@gmail.com
            DateOfFirstOrder = Feb 20 2016 04:15
            PaymentMethod = EftPos
        }
        7 : TCustomer
        {
            Address = TAddress
            {
                Number = 38
                Street = Regent St
                City = Perth
                ZipPostCode = 7858
                StateProvinceCounty = California
                Country = India
            }
            FirstName = Kate
            LastName = Gates
            PhoneNumber = 7963 566 331
            Email = Janet.Johnson@gmail.com
            DateOfFirstOrder = Apr 15 2017 12:05
            PaymentMethod = Cash
        }
        8 : TCustomer
        {
            Address = TAddress
            {
                Number = 31
                Street = Oxford St
                City = Perth
                ZipPostCode = 5720
                StateProvinceCounty = Alaska
                Country = India
            }
            FirstName = Kate
            LastName = Gates
            PhoneNumber = 7711 776 264
            Email = Greg.Gates@gmail.com
            DateOfFirstOrder = Aug 08 2016 18:48
            PaymentMethod = Cash
        }
        9 : TCustomer
        {
            Address = TAddress
            {
                Number = 45
                Street = Mayfair St
                City = Perth
                ZipPostCode = 7123
                StateProvinceCounty = Florida
                Country = USA
            }
            FirstName = Kate
            LastName = Howard
            PhoneNumber = 0960 100 868
            Email = Peter.Howard@gmail.com
            DateOfFirstOrder = Sep 04 2016 12:02
            PaymentMethod = CreditCard
        }
        10 : TCustomer
        {
            Address = TAddress
            {
                Number = 29
                Street = Oxford St
                City = Perth
                ZipPostCode = 2514
                StateProvinceCounty = Texas
                Country = England
            }
            FirstName = Peter
            LastName = Johnson
            PhoneNumber = 8452 208 942
            Email = Peter.Smith@gmail.com
            DateOfFirstOrder = Oct 10 2017 11:17
            PaymentMethod = Cash
        }
        11 : TCustomer
        {
            Address = TAddress
            {
                Number = 42
                Street = Regent St
                City = New York
                ZipPostCode = 5825
                StateProvinceCounty = California
                Country = Australia
            }
            FirstName = John
            LastName = Howard
            PhoneNumber = 2515 199 848
            Email = John.Johnson@gmail.com
            DateOfFirstOrder = Aug 11 2016 15:19
            PaymentMethod = EftPos
        }
        12 : TCustomer
        {
            Address = TAddress
            {
                Number = 49
                Street = Old Kent Road
                City = Berlin
                ZipPostCode = 3927
                StateProvinceCounty = California
                Country = Australia
            }
            FirstName = Janet
            LastName = Johnson
            PhoneNumber = 8071 049 421
            Email = Kate.Smith@gmail.com
            DateOfFirstOrder = Aug 11 2017 01:33
            PaymentMethod = EftPos
        }
    }
    Orders = [00000004.0000000b,00000004.0000000c,00000004.0000000d,00000004.0000000e,00000004.0000000f,
              00000004.00000010,00000004.00000011,00000004.00000012,00000004.00000013,00000004.00000014,
              00000004.00000015,00000004.00000016,00000004.00000017,00000004.00000018,00000004.00000019,
              00000004.0000001a,00000004.0000001b,00000004.0000001c,00000004.0000001d,00000004.0000001e,
              00000004.0000001f,00000004.00000020,00000004.00000021,00000004.00000022,00000004.00000023,
              00000004.00000024,00000004.00000025,00000004.00000026,00000004.00000027,00000004.00000028]
}
Closing client
Closing IoContextPool
Destroyed IoContextPool
Closing WorkingSet
Closing PSpace
Closing PersistStore
Closing server
Closing IoContextPool
Destroyed IoContextPool
Closing WorkingSet
Closing PSpace
Closing PersistStore
Destroyed IoContextPool