Using pypizza

This example illustrates how Python code can access data types written in the Xc++ language. See also the documentation of the cxPython library.

Prerequisites

This example assumes you have installed the pyceda module and installed the pypizza module.

Models defined in Xc++

The pypizza module defines some data types in the Xc++ language associated with a pizza delivery database:


// PizzaDeliveries.h

@import "Pizza.h"
@import "DateTime.h"
@import "Shapes.h"

namespace pizza
{
    $typedef+ int32 TToppingId;
    $typedef+ int32 TEmployeeId;
    $typedef+ int32 TVehicleTypeId;
    $typedef+ int32 TVehicleId;
    $typedef+ int64 TCustomerId;
    $typedef+ int64 TOrderId;
    $typedef+ float64 TCurrency;
    $typedef+ string8 TEmail;
    $typedef+ string8 TPhoneNumber;
    
    $model+ TAddress <<multiline>>
    {
        int32 Number;
        string8 Street;
        string8 City;
        int32 ZipPostCode;
        string8 StateProvinceCounty;
        string8 Country;
    };
    
    $model+ TEmployee <<multiline>>
    {
        TAddress Address;
        string8 FirstName;
        string8 LastName;
        TPhoneNumber PhoneNumber;
    };
    
    $model+ TVehicleType
    {
        string8 Description;
    };
    
    $model+ TVehicle
    {
        TVehicleTypeId VehicleTypeId;
        string8 LicensePlateNumber;
    };
    
    $enum+ class EPaymentMethod
    {
        Cash,
        EftPos,
        CreditCard
    };
    
    $model+ TCustomer <<multiline>>
    {
        TAddress Address;
        string8 FirstName;
        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 <<multiline>>
    {
        TCurrency Price;
        string8 Description;
    };
    
    $model+ TOrderedPizza <<multiline>>
    {
        TShape Shape;
        EBaseType BaseType;
        xvector<TToppingId> ToppingIds;
    };
    
    $struct+ TPizzaOrder <<multiline>> 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 <<multiline>> 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;
        }
    {
    };
} // namespace pizza

Example creating/opening database using Python

First create a general utility class to open/close ceda databases.

Using your favorite text editor, write a file named pizza-example.py as follows:


# pizza-example.py
# This is python

import random
import string
import pyceda
import pypizza
from cedadatabase import *

ceda = pyceda.cns.ceda
dt = pyceda.cns.dt
shapes = pyceda.cns.shapes
pizza = pyceda.cns.pizza

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

####################### DateTime

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)

####################### TVehicleType

# Add all vehicle types to the given TPizzaDeliveryDatabase pdd
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

####################### TVehicle

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()

####################### Address

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()

####################### Employee

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()

# Add an employee to the given TPizzaDeliveryDatabase pdd
def addEmployee(pdd):
    i = len(pdd.Employees)
    setEmployee(pdd.Employees[i])

####################### Shape

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]))

# Assign to s which is a variable of type TShape
def setShape(s):
    if random.randint(0,2) == 0:
        s.Circle = selectCircle()
    else:
        s.Rectangle = selectRectangle()

####################### Pizza

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

####################### TPizzaOrder

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

# Must be called by a thread that has opened a transaction on the database.
# Create an object of type TPizzaOrder.
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())

# Add an order to the given TPizzaDeliveryDatabase pdd
def addOrder(pdd):
    id = len(pdd.Orders)
    pdd.Orders.append(createPizzaOrder(id))

# Replace last pizza in the ith order in the given TPizzaDeliveryDatabase pdd
def ReplaceLastPizzaInOrder(pdd,i):
    if pdd.Orders[i].Pizzas:
        pdd.Orders[i].Pizzas.pop()
        pdd.Orders[i].Pizzas.append(selectPizza())

# Print all the orders in the given TPizzaDeliveryDatabase pdd
def printOrders(pdd):
    print 'Num orders = ' + `len(pdd.Orders)`
    for i in range(len(pdd.Orders)):
        order = pdd.Orders[i]
        print `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, (c.FirstName + ' ' + c.LastName), order.DeliveryStatus)


####################### Customers

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()

# Add a customer to the given TPizzaDeliveryDatabase pdd
def addCustomer(pdd):
    id = len(pdd.Customers)
    setCustomer(pdd.Customers[id])

####################### Toppings

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()

# Add a topping to the given TPizzaDeliveryDatabase pdd
def addTopping(pdd):
    id = len(pdd.Toppings)
    setTopping(pdd.Toppings[id])

# Returns a dictionary representation of the toppings
def getToppings(pdd):
    d = {}
    for id,topping in pdd.Toppings.iteritems():
        # The types of the topping fields are native python value types, so as required we are not
        # returning references to objects in the database (which can be an issue when done across a
        # transaction boundary).
        assert type(topping.Price) is float
        assert type(topping.Description) is str
        d[id] = (topping.Price, topping.Description)
    return d

####################### TPizzaDeliveryDatabase

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)
    #printOrders(pdd)
    #printMap('pdd.Employees', pdd.Employees)

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('mypizzadatabase', createNew) as db:
        pdd = db.rootObj       # The TPizzaDeliveryDatabase in the database

        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)
            #printPizzaDeliveryDatabase(pdd)

        with Txn(db):
            d = getToppings(pdd)
        print 'toppings: ' + str(d)

        # Cannot assign attribute FirstName of read-only pizza::TEmployee
        #with Txn(db):
        #    for id,e in pdd.Employees.iteritems():
        #        e.FirstName = 'Burt'

DataReplicationTest('mypizzadatabase', 'myreplicatedpizzadatabase', utRootKey, printPizzaDeliveryDatabase)

Running the python example

In a bash terminal run pizza-example.py as follows:


# bash
python pizza-example.py

Output

The following output is generated:

Opening mypizzadatabase
Opening PSpace
Opening working set
Created new database
 Id  CustomerId        Name       Status
------------------------------------------
   1          2       Peter Smith      1
   2          5       Janet Gates      1
   3          2       Peter Smith      1
   4          1     Janet Johnson      0
   6          9      Peter Howard      2
   8          1     Janet Johnson      1
   9          1     Janet Johnson      2
toppings: {0: (1.58, 'Jalapenos')}
Closing WorkingSet
Closing PSpace
Closing PersistStore
Opening mypizzadatabase
Opening PSpace
Opening working set
Opened existing database
 Id  CustomerId        Name       Status
------------------------------------------
   1          2       Peter Smith      1
   2          5       Janet Gates      1
   3          2       Peter Smith      1
   4          1     Janet Johnson      0
   6          9      Peter Howard      2
   8          1     Janet Johnson      1
   9          1     Janet Johnson      2
  10         10      Peter Howard      3
  11          1     Janet Johnson      2
  12          2       Peter Smith      3
  15          2       Peter Smith      1
  16          9      Peter Howard      1
  17          2       Peter Smith      1
  18          4   Rihanna Johnson      2
  19          6      Kate Johnson      2
toppings: {0: (1.58, 'Jalapenos'), 1: (1.42, 'Jalapenos')}
Closing WorkingSet
Closing PSpace
Closing PersistStore
Opening mypizzadatabase
Opening PSpace
Opening working set
Opened existing database
 Id  CustomerId        Name       Status
------------------------------------------
   1          2       Peter Smith      1
   2          5       Janet Gates      1
   3          2       Peter Smith      1
   4          1     Janet Johnson      0
   5         12       Peter Gates      3
   6          9      Peter Howard      2
   8          1     Janet Johnson      1
   9          1     Janet Johnson      2
  10         10      Peter Howard      3
  11          1     Janet Johnson      2
  12          2       Peter Smith      3
  15          2       Peter Smith      1
  16          9      Peter Howard      1
  17          2       Peter Smith      1
  18          4   Rihanna Johnson      2
  19          6      Kate Johnson      2
  20          8       Kate Howard      0
  22          1     Janet Johnson      1
  23         10      Peter Howard      3
  25          3      Greg Johnson      0
  26         11     Rihanna Gates      2
  27          7      John Johnson      1
  28         10      Peter Howard      0
  29          4   Rihanna Johnson      3
toppings: {0: (1.58, 'Jalapenos'), 1: (1.42, 'Jalapenos'), 2: (1.99, 'Mushrooms')}
Closing WorkingSet
Closing PSpace
Closing PersistStore

Replication test mypizzadatabase to myreplicatedpizzadatabase
Opening mypizzadatabase
Opening PSpace
Opening working set
Creating server listening on port 3000
num server operations = 16
Opening myreplicatedpizzadatabase
Opening PSpace
Opening working set
Creating client connecting to '127.0.0.1':3000
num client operations = 0
num client operations = 0
Peer : WsipcHostInfo(,,,,,MGuid({00000000-0000-0000-0000-000000000000}))
Peer : WsipcHostInfo(127.0.0.1,,,,,MGuid({00000000-0000-0000-0000-000000000000}))
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.05200004577636719 seconds
TPizzaDeliveryDatabase
{
    Vehicles =
    {
        1 : TVehicle(8,YXS.839)
        2 : TVehicle(2,FFU.635)
        3 : TVehicle(7,QFX.635)
        4 : TVehicle(4,BHP.238)
        5 : TVehicle(1,MCI.265)
        6 : TVehicle(5,CSD.871)
        7 : TVehicle(8,HUB.274)
        8 : TVehicle(8,VUG.192)
        9 : TVehicle(4,NVF.156)
        10 : TVehicle(7,TDQ.610)
    }
    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 = 27
                Street = Old Kent Road
                City = Perth
                ZipPostCode = 2571
                StateProvinceCounty = Alaska
                Country = England
            }
            FirstName = Rihanna
            LastName = Gates
            PhoneNumber = 5106 963 004
        }
        1 : TEmployee
        {
            Address = TAddress
            {
                Number = 16
                Street = Oxford St
                City = Perth
                ZipPostCode = 1603
                StateProvinceCounty = Alaska
                Country = England
            }
            FirstName = Greg
            LastName = Howard
            PhoneNumber = 6043 167 801
        }
        2 : TEmployee
        {
            Address = TAddress
            {
                Number = 16
                Street = Mayfair St
                City = Perth
                ZipPostCode = 5426
                StateProvinceCounty = California
                Country = Australia
            }
            FirstName = Greg
            LastName = Johnson
            PhoneNumber = 4875 255 681
        }
    }
    Toppings =
    {
        0 : TTopping
        {
            Price = 1.58
            Description = Jalapenos
        }
        1 : TTopping
        {
            Price = 1.42
            Description = Jalapenos
        }
        2 : TTopping
        {
            Price = 1.99
            Description = Mushrooms
        }
    }
    Customers =
    {
        0 : TCustomer
        {
            Address = TAddress
            {
                Number = 14
                Street = Oxford St
                City = Perth
                ZipPostCode = 1025
                StateProvinceCounty = California
                Country = USA
            }
            FirstName = Kate
            LastName = Smith
            PhoneNumber = 8216 122 701
            Email = Rihanna.Johnson@gmail.com
            DateOfFirstOrder = Feb 15 2016 23:04
            PaymentMethod = Cash
        }
        1 : TCustomer
        {
            Address = TAddress
            {
                Number = 49
                Street = Regent St
                City = Paris
                ZipPostCode = 1669
                StateProvinceCounty = California
                Country = Australia
            }
            FirstName = Janet
            LastName = Johnson
            PhoneNumber = 0117 164 824
            Email = Rihanna.Matthews@gmail.com
            DateOfFirstOrder = Aug 20 2016 03:46
            PaymentMethod = Cash
        }
        2 : TCustomer
        {
            Address = TAddress
            {
                Number = 3
                Street = Oxford St
                City = Perth
                ZipPostCode = 7708
                StateProvinceCounty = California
                Country = Australia
            }
            FirstName = Peter
            LastName = Smith
            PhoneNumber = 3054 223 635
            Email = Kate.Howard@gmail.com
            DateOfFirstOrder = Sep 04 2017 05:36
            PaymentMethod = CreditCard
        }
        3 : TCustomer
        {
            Address = TAddress
            {
                Number = 26
                Street = Oxford St
                City = Berlin
                ZipPostCode = 3073
                StateProvinceCounty = California
                Country = Australia
            }
            FirstName = Greg
            LastName = Johnson
            PhoneNumber = 8776 922 547
            Email = Kate.Howard@gmail.com
            DateOfFirstOrder = Dec 01 2016 00:51
            PaymentMethod = CreditCard
        }
        4 : TCustomer
        {
            Address = TAddress
            {
                Number = 27
                Street = Regent St
                City = Paris
                ZipPostCode = 7270
                StateProvinceCounty = Texas
                Country = Australia
            }
            FirstName = Rihanna
            LastName = Johnson
            PhoneNumber = 0588 381 744
            Email = John.Matthews@gmail.com
            DateOfFirstOrder = Apr 06 2017 21:15
            PaymentMethod = CreditCard
        }
        5 : TCustomer
        {
            Address = TAddress
            {
                Number = 4
                Street = Regent St
                City = New York
                ZipPostCode = 9025
                StateProvinceCounty = New South Wales
                Country = USA
            }
            FirstName = Janet
            LastName = Gates
            PhoneNumber = 8528 389 151
            Email = Kate.Johnson@gmail.com
            DateOfFirstOrder = Mar 09 2016 18:56
            PaymentMethod = CreditCard
        }
        6 : TCustomer
        {
            Address = TAddress
            {
                Number = 42
                Street = Regent St
                City = Perth
                ZipPostCode = 6959
                StateProvinceCounty = Texas
                Country = England
            }
            FirstName = Kate
            LastName = Johnson
            PhoneNumber = 0472 139 741
            Email = Greg.Smith@gmail.com
            DateOfFirstOrder = Oct 27 2016 02:41
            PaymentMethod = CreditCard
        }
        7 : TCustomer
        {
            Address = TAddress
            {
                Number = 40
                Street = Regent St
                City = New York
                ZipPostCode = 2573
                StateProvinceCounty = Texas
                Country = England
            }
            FirstName = John
            LastName = Johnson
            PhoneNumber = 5523 452 183
            Email = Peter.Howard@gmail.com
            DateOfFirstOrder = Apr 27 2016 02:14
            PaymentMethod = Cash
        }
        8 : TCustomer
        {
            Address = TAddress
            {
                Number = 41
                Street = Old Kent Road
                City = Perth
                ZipPostCode = 3850
                StateProvinceCounty = Texas
                Country = USA
            }
            FirstName = Kate
            LastName = Howard
            PhoneNumber = 3514 973 228
            Email = Peter.Matthews@gmail.com
            DateOfFirstOrder = Dec 18 2017 01:30
            PaymentMethod = EftPos
        }
        9 : TCustomer
        {
            Address = TAddress
            {
                Number = 9
                Street = Regent St
                City = London
                ZipPostCode = 5896
                StateProvinceCounty = Alaska
                Country = India
            }
            FirstName = Peter
            LastName = Howard
            PhoneNumber = 2656 601 423
            Email = Kate.Matthews@gmail.com
            DateOfFirstOrder = Dec 16 2016 05:56
            PaymentMethod = CreditCard
        }
        10 : TCustomer
        {
            Address = TAddress
            {
                Number = 8
                Street = Oxford St
                City = Berlin
                ZipPostCode = 9674
                StateProvinceCounty = New South Wales
                Country = Australia
            }
            FirstName = Peter
            LastName = Howard
            PhoneNumber = 8485 417 068
            Email = Greg.Smith@gmail.com
            DateOfFirstOrder = Feb 07 2017 02:00
            PaymentMethod = CreditCard
        }
        11 : TCustomer
        {
            Address = TAddress
            {
                Number = 29
                Street = Mayfair St
                City = New York
                ZipPostCode = 1162
                StateProvinceCounty = Texas
                Country = Australia
            }
            FirstName = Rihanna
            LastName = Gates
            PhoneNumber = 3218 554 983
            Email = Peter.Matthews@gmail.com
            DateOfFirstOrder = Aug 03 2016 21:13
            PaymentMethod = CreditCard
        }
        12 : TCustomer
        {
            Address = TAddress
            {
                Number = 3
                Street = Mayfair St
                City = New York
                ZipPostCode = 6800
                StateProvinceCounty = California
                Country = USA
            }
            FirstName = Peter
            LastName = Gates
            PhoneNumber = 6864 440 503
            Email = Janet.Smith@gmail.com
            DateOfFirstOrder = May 14 2016 15:29
            PaymentMethod = CreditCard
        }
    }
    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
Failure : mcsf = 1 ec = connection has been closed
Failure : mcsf = 1 ec = An existing connection was forcibly closed by the remote host
Closing Iocp
Closing WorkingSet
Closing PSpace
Closing PersistStore
Closing server
Closing Iocp
Closing WorkingSet
Closing PSpace
Closing PersistStore