@@ -0,0 +1,43 @@
<?hh // strict

class FetchOrderPricePolicyQuery {

public function __construct(
private FetchQuery<OrderPricePolicy> $fetchQuery,
private OrderPricePolicyTable $orderPricePolicyTable,
private TimestampSerializer $timestampSerializer
) {}

public async function fetch(Timestamp $timestamp): Awaitable<OrderPricePolicy> {
$fetch_params_builder = new FetchParamsBuilder();

// Build where clause: select all records
$where_clause_vector_builder = new WhereClauseVectorBuilder();
$fetch_params_builder->setWhereClause(
$where_clause_vector_builder->setFirstClause(
new LessThanWhereClause(
$this->orderPricePolicyTable->getTimeEnactedKey(),
$this->timestampSerializer->serialize($timestamp)
)
)
->build()
);

// Build order-by clause: sort by 'time-enacted'
$order_by_clause_builder = new OrderByClauseBuilder();
$fetch_params_builder->setOrderByClause(
$order_by_clause_builder->asc(
$this->orderPricePolicyTable->getTimeEnactedKey()
)
->build()
);

$policy_list = await $this->fetchQuery->fetch(
$fetch_params_builder
->setTable($this->orderPricePolicyTable)
->build()
);

return $policy_list[0];
}
}
@@ -0,0 +1,43 @@
<?hh // strict

class FetchVideoEditingPricePolicyQuery {

public function __construct(
private FetchQuery<VideoEditingPricePolicy> $fetchQuery,
private VideoEditingPricePolicyTable $videoEditingPricePolicyTable,
private TimestampSerializer $timestampSerializer
) {}

public async function fetch(Timestamp $timestamp): Awaitable<VideoEditingPricePolicy> {
$fetch_params_builder = new FetchParamsBuilder();

// Build where clause: select all records
$where_clause_vector_builder = new WhereClauseVectorBuilder();
$fetch_params_builder->setWhereClause(
$where_clause_vector_builder->setFirstClause(
new LessThanWhereClause(
$this->videoEditingPricePolicyTable->getTimeEnactedKey(),
$this->timestampSerializer->serialize($timestamp)
)
)
->build()
);

// Build order-by clause: sort by 'time-enacted'
$order_by_clause_builder = new OrderByClauseBuilder();
$fetch_params_builder->setOrderByClause(
$order_by_clause_builder->asc(
$this->videoEditingPricePolicyTable->getTimeEnactedKey()
)
->build()
);

$policy_list = await $this->fetchQuery->fetch(
$fetch_params_builder
->setTable($this->videoEditingPricePolicyTable)
->build()
);

return $policy_list[0];
}
}
@@ -0,0 +1,43 @@
<?hh // strict

class FetchVideoStoragePricePolicyQuery {

public function __construct(
private FetchQuery<VideoStoragePricePolicy> $fetchQuery,
private VideoStoragePricePolicyTable $videoStoragePricePolicyTable,
private TimestampSerializer $timestampSerializer
) {}

public async function fetch(Timestamp $timestamp): Awaitable<VideoStoragePricePolicy> {
$fetch_params_builder = new FetchParamsBuilder();

// Build where clause: select all records
$where_clause_vector_builder = new WhereClauseVectorBuilder();
$fetch_params_builder->setWhereClause(
$where_clause_vector_builder->setFirstClause(
new LessThanWhereClause(
$this->videoStoragePricePolicyTable->getTimeEnactedKey(),
$this->timestampSerializer->serialize($timestamp)
)
)
->build()
);

// Build order-by clause: sort by 'time-enacted'
$order_by_clause_builder = new OrderByClauseBuilder();
$fetch_params_builder->setOrderByClause(
$order_by_clause_builder->asc(
$this->videoStoragePricePolicyTable->getTimeEnactedKey()
)
->build()
);

$policy_list = await $this->fetchQuery->fetch(
$fetch_params_builder
->setTable($this->videoStoragePricePolicyTable)
->build()
);

return $policy_list[0];
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -8,13 +8,13 @@ class InsertCellLabelQuery {
) {}

public async function insert(
UnsignedInt $confirmed_order_id,
UnsignedInt $edited_video_order_id,
UnsignedInt $cell_number,
string $label
): Awaitable<CellLabel> {
return await $this->insertQuery->insert(
ImmMap{
$this->cellLabelsTable->getConfirmedOrderIdKey() => $confirmed_order_id->getNumber(),
$this->cellLabelsTable->getEditedVideoOrderIdKey() => $edited_video_order_id->getNumber(),
$this->cellLabelsTable->getCellNumberKey() => $cell_number->getNumber(),
$this->cellLabelsTable->getLabelKey() => $label,
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -16,7 +16,7 @@ class InsertConfirmedOrderQuery {
string $title,
string $description,
UnsignedInt $short_code_id,
UnsignedInt $recording_duration
UnsignedFloat $price
): Awaitable<ConfirmedOrder> {
return await $this->insertQuery->insert(
ImmMap{
@@ -27,7 +27,7 @@ class InsertConfirmedOrderQuery {
$this->confirmedOrdersTable->getTitleKey() => $title,
$this->confirmedOrdersTable->getDescriptionKey() => $description,
$this->confirmedOrdersTable->getShortCodeIdKey() => $short_code_id->getNumber(),
$this->confirmedOrdersTable->getRecordingDurationKey() => $recording_duration->getNumber(),
$this->confirmedOrdersTable->getShortCodeIdKey() => $price->getNumber(),
}
);
}
@@ -0,0 +1,21 @@
<?hh // strict

class InsertEditedVideoOrderQuery {

public function __construct(
private InsertQuery<EditedVideoOrder> $insertQuery,
private EditedVideoOrderTable $editedVideoOrdersTable
) {}

public async function insert(
UnsignedInt $confirmed_order,
UnsignedInt $recording_duration_minutes
): Awaitable<EditedVideoOrder> {
return await $this->insertQuery->insert(
ImmMap{
$this->editedVideoOrdersTable->getConfirmedOrderIdKey() => $confirmed_order->getNumber(),
$this->editedVideoOrdersTable->getRecordingDurationMinutesKey() => $recording_duration_minutes->getNumber(),
}
);
}
}
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,22 @@
<?hh // strict

class InsertOrderPricePolicyQuery {

public function __construct(
private InsertQuery<OrderPricePolicy> $insertQuery,
private OrderPricePolicyTable $orderPricePolicyTable,
private HRTimestampSerializer $hrTimestampSerializer
) {}

public async function insert(
UnsignedFloat $price,
Timestamp $time_enacted
): Awaitable<OrderPricePolicy> {
return await $this->insertQuery->insert(
ImmMap{
$this->orderPricePolicyTable->getPriceKey() => $price->getNumber(),
$this->orderPricePolicyTable->getTimeEnactedKey() => $this->hrTimestampSerializer->serialize($time_enacted),
}
);
}
}
File renamed without changes.
@@ -0,0 +1,25 @@
<?hh // strict

class BasicVideosTable extends Table {

const string TABLE_NAME = "BasicVideos";
const string CONFIRMED_ORDER_ID_KEY = "confirmedOrderId";
const string SCOPE_INDEX_KEY = "scopeIndex";
const string EXPIRATION_TIME_KEY = "expirationTime";

public function getName(): string {
return self::TABLE_NAME;
}

public function getConfirmedOrderIdKey(): string {
return self::CONFIRMED_ORDER_ID_KEY;
}

public function getScopeIndexKey(): string {
return self::SCOPE_INDEX_KEY;
}

public function getExpirationTimeKey(): string {
return self::EXPIRATION_TIME_KEY;
}
}
@@ -10,7 +10,7 @@ class ConfirmedOrdersTable extends Table {
const string TITLE_KEY = "title";
const string DESCRIPTION_KEY = "description";
const string SHORT_CODE_ID_KEY = "shortCodeId";
const string RECORDING_DURATION_KEY = "recordingDurationMinutes";
const string PRICE_KEY = "price";

public function getName(): string {
return self::TABLE_NAME;
@@ -44,7 +44,7 @@ class ConfirmedOrdersTable extends Table {
return self::SHORT_CODE_ID_KEY;
}

public function getRecordingDurationKey(): string {
return self::RECORDING_DURATION_KEY;
public function getPriceKey(): string {
return self::PRICE_KEY;
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -3,16 +3,16 @@
class CellLabelsTable extends Table {

const string TABLE_NAME = "CellLabels";
const string CONFIRMED_ORDER_ID_KEY = "confirmedOrderId";
const string EDITED_VIDEO_ORDER_ID_KEY = "editedVideoOrderId";
const string CELL_NUMBER_KEY = "cellNumber";
const string LABEL_KEY = "label";

public function getName(): string {
return self::TABLE_NAME;
}

public function getConfirmedOrderIdKey(): string {
return self::CONFIRMED_ORDER_ID_KEY;
public function getEditedVideoOrderIdKey(): string {
return self::EDITED_VIDEO_ORDER_ID_KEY;
}

public function getCellNumberKey(): string {
@@ -0,0 +1,20 @@
<?hh // strict

class CompositeVideoTable extends Table {

const string TABLE_NAME = "CompositeVideos";
const string CONFIRMED_ORDER_ID_KEY = "confirmedOrderId";
const string EXPIRATION_TIME_KEY = "expirationTime";

public function getName(): string {
return self::TABLE_NAME;
}

public function getConfirmedOrderIdKey(): string {
return self::CONFIRMED_ORDER_ID_KEY;
}

public function getExpirationTimeKey(): string {
return self::EXPIRATION_TIME_KEY;
}
}
@@ -0,0 +1,20 @@
<?hh // strict

class EditedVideoOrderTable extends Table {

const string TABLE_NAME = "EditedVideoOrders";
const string CONFIRMED_ORDER_ID_KEY = "confirmedOrderId";
const string RECORDING_DURATION_MINUTES_KEY = "recordingDurationMinutes";

public function getName(): string {
return self::TABLE_NAME;
}

public function getConfirmedOrderIdKey(): string {
return self::CONFIRMED_ORDER_ID_KEY;
}

public function getRecordingDurationMinutesKey(): string {
return self::RECORDING_DURATION_MINUTES_KEY;
}
}
@@ -0,0 +1,20 @@
<?hh // strict

class OrderPricePolicyTable extends Table {

const string TABLE_NAME = "OrderPricePolicy";
const string PRICE_KEY = "price";
const string TIME_ENACTED_KEY = "timeEnacted";

public function getName(): string {
return self::TABLE_NAME;
}

public function getPriceKey(): string {
return self::PRICE_KEY;
}

public function getTimeEnactedKey(): string {
return self::TIME_ENACTED_KEY;
}
}
@@ -0,0 +1,20 @@
<?hh // strict

class VideoEditingPricePolicyTable extends Table {

const string TABLE_NAME = "VideoEditingPricePolicy";
const string PRICE_KEY = "price";
const string TIME_ENACTED_KEY = "timeEnacted";

public function getName(): string {
return self::TABLE_NAME;
}

public function getPriceKey(): string {
return self::PRICE_KEY;
}

public function getTimeEnactedKey(): string {
return self::TIME_ENACTED_KEY;
}
}
@@ -0,0 +1,25 @@
<?hh // strict

class VideoStoragePricePolicyTable extends Table {

const string TABLE_NAME = "VideoStoragePricePolicy";
const string PRICE_KEY = "price";
const string NUMBER_FREE_DAYS_KEY = "numberFreeDays";
const string TIME_ENACTED_KEY = "timeEnacted";

public function getName(): string {
return self::TABLE_NAME;
}

public function getPriceKey(): string {
return self::PRICE_KEY;
}

public function getNumberFreeDaysKey(): string {
return self::NUMBER_FREE_DAYS_KEY;
}

public function getTimeEnactedKey(): string {
return self::TIME_ENACTED_KEY;
}
}
File renamed without changes.
@@ -1,9 +1,10 @@
<?hh // strict

class ConfirmOrderApi extends Api<ConfirmOrderRequest> {
class ConfirmOrderApi extends Api<ConfirmOrderApiRequest> {

public function __construct(
RequestFactory<ConfirmOrderRequest> $request_factory,
RequestFactory<ConfirmOrderApiRequest> $request_factory,
private TimestampBuilder $timestampBuilder,
private ConfirmOrderMethod $confirmOrderMethod,
private Logger $logger
) {
@@ -14,19 +15,49 @@ class ConfirmOrderApi extends Api<ConfirmOrderRequest> {
}

protected function processRequestObject(
ConfirmOrderRequest $request
ConfirmOrderApiRequest $request
): ApiResult {
// Log confirm order call
$this->logger->info("Confirm order api call...");

// Unpack api-request into internal request object
$edited_video_order = null;

// Translate edited-video-order api-request to internal request object
$edited_video_order_api_request = $request->getEditedVideoOrderApiRequest();
$create_edited_video_order_request = null;

if ($edited_video_order_api_request !== null) {
// Translate cell-label api-requests to internal request objects
$cell_label_api_requests = $edited_video_order_api_request->getCellLabels()->get();
$create_cell_label_requests = Vector{};

foreach ($cell_label_api_requests as $cell_label) {
$create_cell_label_requests[] = new CreateCellLabelRequest(
$cell_label->getLabel()->get()
);
}

$create_edited_video_order_request = new CreateEditedVideoOrderRequest(
$edited_video_order_api_request->getRecordingDurationMinutes()->get(),
$create_cell_label_requests->toImmVector()
);
}

// Translate create-confirm-order api-request to internal request object
$create_confirm_order_request = new CreateConfirmOrderRequest(
$request->getRsvdOrderId()->get(),
$this->timestampBuilder->now(),
$request->getTitle()->get(),
$request->getDescription()->get(),
$request->getShortCodeId()->get(),
$create_edited_video_order_request
);

try {
// Unpack edited-video-order-request into internal object
$confirmed_order = $this->confirmOrderMethod->confirm(
$request->getRsvdOrderId()->get(),
$request->getTitle()->get(),
$request->getDescription()->get(),
$request->getShortCodeId()->get(),
$request->getRecordingDuration()->get(),
$request->getCellLabelRequests()->get()
$create_confirm_order_request
);

// Log confirm order request completed
@@ -29,6 +29,7 @@ class GetUsersConfirmedOrdersApiResult extends SuccessfulApiResult {

protected function getCustomResultFields(): ImmMap<string, mixed> {
$order_vector = Vector{};
/*
foreach ($this->orders as $order_with_cell_labels) {
// Assemble cell label list payload for this order
@@ -58,7 +59,7 @@ class GetUsersConfirmedOrdersApiResult extends SuccessfulApiResult {
self::CONFIRMED_ORDER_CELL_LABELS_KEY => $cell_label_vector->toImmVector()
};
}

*/
return ImmMap{
self::CONFIRMED_ORDERS_LIST_KEY => $order_vector->toImmVector(),
};
@@ -28,7 +28,7 @@ class ApiInjector {
private LazyLoader<RequestFactory<CreateUserRequest>> $createUserRequestFactoryLoader,
private LazyLoader<RequestFactory<GetUserByEmailRequest>> $getUserRequestFactoryLoader,
private LazyLoader<RequestFactory<ReserveOrderRequest>> $reserveOrderRequestFactoryLoader,
private LazyLoader<RequestFactory<ConfirmOrderRequest>> $confirmOrderRequestFactoryLoader,
private LazyLoader<RequestFactory<ConfirmOrderApiRequest>> $confirmOrderRequestFactoryLoader,
private LazyLoader<RequestFactory<UpdateConfirmedOrderRequest>> $updateConfirmedOrderRequestLoader,
private LazyLoader<RequestFactory<UpdateCellLabelRequest>> $updateCellLabelRequestLoader,
private LazyLoader<RequestFactory<DeleteCellLabelRequest>> $deleteCellLabelRequestLoader,
@@ -33,7 +33,7 @@ class ProductionApiInjectorFactory implements ApiInjectorFactory {
new ReserveOrderRequestFactoryLazyLoader(
$hr_timestamp_serializer
),
new ConfirmOrderRequestFactoryLazyLoader(),
new ConfirmOrderApiRequestFactoryLazyLoader(),
new UpdateConfirmedOrderRequestFactoryLazyLoader(),
new UpdateCellLabelRequestFactoryLazyLoader(),
new DeleteCellLabelRequestFactoryLazyLoader(),
@@ -1,8 +1,8 @@
<?hh // strict

class ConfirmOrderRequestFactoryLazyLoader extends LazyLoader<ConfirmOrderRequestFactory> {
class ConfirmOrderApiRequestFactoryLazyLoader extends LazyLoader<ConfirmOrderApiRequestFactory> {

protected function make(): ConfirmOrderRequestFactory {
return new ConfirmOrderRequestFactory();
protected function make(): ConfirmOrderApiRequestFactory {
return new ConfirmOrderApiRequestFactory();
}
}
@@ -225,6 +225,7 @@ class MethodInjector {
$this->queryInjector->getFetchRsvdOrderByIdQuery(),
$this->queryInjector->getFetchIsUserOwnedShortCodeQuery(),
$this->queryInjector->getConcreteInsertConfirmedOrderQuery(),
$this->queryInjector->getConcreteInsertEditedVideoOrderQuery(),
$this->queryInjector->getBatchInsertCellLabelsQuery(),
$this->queryInjector->getDeleteByIdQuery(),
$this->cellsLabelTableLoader->load(),
@@ -25,6 +25,7 @@ class ProductionQueryInjectorFactory extends SingletonQueryInjectorFactory {
$rsvd_order_policy_table_loader = new ReservedOrderPolicyTableLazyLoader();
$cell_labels_table_loader = new CellLabelsTableLazyLoader();
$short_code_table_loader = new ShortCodesTableLazyLoader();
$edited_video_order_table_loader = new EditedVideoOrderTableLazyLoader();

return new QueryInjector(
new AsyncMysqlConnectionLazyLoader(
@@ -83,6 +84,10 @@ class ProductionQueryInjectorFactory extends SingletonQueryInjectorFactory {
$short_code_table_loader,
new ShortCodeModelFactoryLazyLoader(
$short_code_table_loader
),
$edited_video_order_table_loader,
new EditedVideoOrderModelFactoryLazyLoader(
$edited_video_order_table_loader
)
);
}
@@ -65,6 +65,10 @@ class QueryInjector {
private ?FetchConfirmedOrderCellLabelsQuery $fetchConfirmedOrderCellLabelsQuery;
private ?FetchIsUserOwnedShortCodeQuery $fetchIsUserOwnedShortCodeQuery;
private ?FetchUserShortCodesQuery $fetchUserShortCodesQuery;

// Edited video order queries
private ?InsertQuery<EditedVideoOrder> $insertEditedVideoOrderQuery;
private ?InsertEditedVideoOrderQuery $concreteInsertEditedVideoOrderQuery;

// Short codes
private ?FetchQuery<ShortCode> $fetchShortCodesQuery;
@@ -108,7 +112,9 @@ class QueryInjector {
private LazyLoader<ConcreteModelFactory<CellLabel>> $cellLabelModelFactoryLazyLoader,
private LazyLoader<QueryExceptionFactory> $queryExceptionFactoryLazyLoader,
private LazyLoader<ShortCodeTable> $shortCodeTableLazyLoader,
private LazyLoader<ConcreteModelFactory<ShortCode>> $shortCodeModelFactoryLazyLoader
private LazyLoader<ConcreteModelFactory<ShortCode>> $shortCodeModelFactoryLazyLoader,
private LazyLoader<EditedVideoOrderTable> $editedVideoOrderTableLazyLoader,
private LazyLoader<ConcreteModelFactory<EditedVideoOrder>> $editedVideoOrderModelFactoryLazyLoader
) {}

public function getUpdateQuery(): UpdateQuery {
@@ -616,6 +622,29 @@ class QueryInjector {
return $this->fetchConfirmedOrderCellLabelsQuery;
}

public function getInsertEditedVideoOrderQuery(): InsertQuery<EditedVideoOrder> {
if ($this->insertEditedVideoOrderQuery === null) {
$this->insertEditedVideoOrderQuery = new InsertQuery(
$this->asyncMysqlConnectionLazyLoader->load(),
$this->editedVideoOrderTableLazyLoader->load(),
$this->editedVideoOrderModelFactoryLazyLoader->load(),
$this->insertQueryCreaterLazyLoader->load(),
$this->queryExceptionFactoryLazyLoader->load()
);
}
return $this->insertEditedVideoOrderQuery;
}

public function getConcreteInsertEditedVideoOrderQuery(): InsertEditedVideoOrderQuery {
if ($this->concreteInsertEditedVideoOrderQuery === null) {
$this->concreteInsertEditedVideoOrderQuery = new InsertEditedVideoOrderQuery(
$this->getInsertEditedVideoOrderQuery(),
$this->editedVideoOrderTableLazyLoader->load()
);
}
return $this->concreteInsertEditedVideoOrderQuery;
}

public function getFetchShortCodesQuery(): FetchQuery<ShortCode> {
if ($this->fetchShortCodesQuery === null) {
$this->fetchShortCodesQuery = new FetchQuery(
@@ -0,0 +1,14 @@
<?hh // strict

class EditedVideoOrderModelFactoryLazyLoader extends LazyLoader<ConcreteModelFactory<EditedVideoOrder>> {

public function __construct(
private EditedVideoOrderTableLazyLoader $editedVideoOrderTableLazyLoader,
) {}

protected function make(): ConcreteModelFactory<EditedVideoOrder> {
return new EditedVideoOrderFactory(
$this->editedVideoOrderTableLazyLoader->load()
);
}
}
@@ -0,0 +1,8 @@
<?hh // strict

class EditedVideoOrderTableLazyLoader extends LazyLoader<EditedVideoOrderTable> {

protected function make(): EditedVideoOrderTable {
return new EditedVideoOrderTable();
}
}
@@ -0,0 +1,21 @@
<?hh // strict

class ComputePriceOfConfirmedOrderMethod {

public function __construct(
private FetchOrderPricePolicyQuery $fetchOrderPricePolicyQuery,
private FetchVideoEditingPricePolicyQuery $fetchVideoEditingPricePolicyQuery,
private FetchVideoStoragePricePolicyQuery $fetchVideoStoragePricePolicyQuery
) {}

public function computePrice(
CreateConfirmOrderRequest $create_confirm_order_request
): UnsignedFloat {
$price = 0;

// Fetch policies applicable to all common orders
$fetch_order_policy_handle = $this->fetchOrderPricePolicyQuery->fetch(

);
}
}
@@ -6,23 +6,21 @@ class ConfirmOrderMethod {
private FetchByIdQuery<RsvdOrder> $fetchRsvdOrderQuery,
private FetchIsUserOwnedShortCodeQuery $fetchIsUserOwnedShortCodeQuery,
private InsertConfirmedOrderQuery $confirmedOrderInsertQuery,
private InsertEditedVideoOrderQuery $editedVideoOrderInsertQuery,
private BatchInsertQuery<CellLabel> $cellLabelBatchInsertQuery,
private DeleteByIdQuery $deleteByIdQuery,
private CellLabelsTable $cellLabelsTable,
private RsvdOrdersTable $rsvdOrdersTable
) {}

public function confirm(
UnsignedInt $rsvd_order_id,
string $title,
string $description,
UnsignedInt $short_code_id,
UnsignedInt $recording_duration,
ImmVector<CreateCellLabelRequest> $cell_label_list
CreateConfirmOrderRequest $create_confirm_order_request
): ConfirmedOrder {
try {
// Fetch reserved order
$fetch_result = $this->fetchRsvdOrderQuery->fetch($rsvd_order_id);
$fetch_result = $this->fetchRsvdOrderQuery->fetch(
$create_confirm_order_request->getReserveOrderId()
);

// Block until we fetch the reserved order
$rsvd_order = $fetch_result
@@ -35,6 +33,8 @@ class ConfirmOrderMethod {
}

// Fail if short code does not belong to this user
$short_code_id = $create_confirm_order_request->getShortCodeId();

if (await $this->fetchIsUserOwnedShortCodeQuery->fetch(
$rsvd_order->getUserId(),
$short_code_id)
@@ -45,59 +45,33 @@ class ConfirmOrderMethod {
);
}

// Fail if provided number of cell labels does not equal
// numer of scopes in reserved order
if ($rsvd_order->getScopesCount()->getNumber() !== $cell_label_list->count()) {
throw new InvalidCellLabelCountException(
$rsvd_order->getScopesCount(),
new UnsignedInt($cell_label_list->count())
);
}

// Request passed checks! Insert new confirmed order...
$confirmed_order_insert_result = $this->confirmedOrderInsertQuery->insert(
$rsvd_order->getUserId(),
$rsvd_order->getScopesCount(),
$rsvd_order->getTimestampSegment()->getStart(),
$rsvd_order->getTimestampSegment()->getEnd(),
$title,
$description,
$create_confirm_order_request->getTitle(),
$create_confirm_order_request->getDescription(),
$short_code_id,
$recording_duration
new UnsignedFloat(0.0)
);

// Block until insert completes
$confirmed_order = $confirmed_order_insert_result
->getWaitHandle()
->join();

// Compose insert cell-labels query
$cell_label_field_map_list = Vector{};
$cell_number = 0;

foreach ($cell_label_list as $cell_label_request) {
$cell_label_field_map_list[] = ImmMap{
$this->cellLabelsTable->getConfirmedOrderIdKey() => $confirmed_order->getId()->getNumber(),
$this->cellLabelsTable->getLabelKey() => $cell_label_request->getLabel()->get(),
$this->cellLabelsTable->getCellNumberKey() => $cell_number
};

++$cell_number;
}

// Execute insert cell-labels query
$cell_label_insert_query_handle = $this
->cellLabelBatchInsertQuery->insert(
$cell_label_field_map_list->toImmVector()
);

// Block until cell labels have been inserted
// and rsvd orders have been deleted
$cell_label_insert_query_handle
->getWaitHandle()
->join();
// Handle edited-video-order request, if provided
$edited_video_order_request = $create_confirm_order_request->getCreateEditedVideoOrderRequest();
if ($edited_video_order_request !== null) {
$this->handleCreateEditedVideoOrderRequest(
$confirmed_order,
$edited_video_order_request
);
}

// Delete rsvd order
// Delete reserved order
$delete_rsvd_order_query_handle = $this->deleteByIdQuery->delete(
$this->rsvdOrdersTable,
$rsvd_order->getId()
@@ -113,4 +87,58 @@ class ConfirmOrderMethod {
throw new FailedQueryMethodException($ex);
}
}

private function handleCreateEditedVideoOrderRequest(
ConfirmedOrder $confirmed_order,
CreateEditedVideoOrderRequest $edited_video_order_request
): void {
// Check the number of cell-labels. Fail if cell-label count doesn't match
// scopes count in confirmed-order
$scopes_count = $confirmed_order->getScopesCount();
$create_cell_label_request_list = $edited_video_order_request->getCellLabels();
$cell_labels_count = $create_cell_label_request_list->count();

if ($scopes_count->getNumber() !== $cell_labels_count) {
throw new InvalidCellLabelCountException(
$scopes_count,
new UnsignedInt($cell_labels_count)
);
}

// Insert edited-video-order into db
$edited_video_order_insert_result = $this->editedVideoOrderInsertQuery->insert(
$confirmed_order->getId(),
$edited_video_order_request->getRecordingDurationMinutes()
);

// Block until edited-video-order create query finishes
$edited_video_order = $edited_video_order_insert_result
->getWaitHandle()
->join();

// Insert cell-labels into db
$cell_label_field_map_list = Vector{};
$cell_number = 0;
$edited_video_order_id = $edited_video_order->getId()->getNumber();

foreach ($create_cell_label_request_list as $create_cell_label_request) {
$cell_label_field_map_list[] = ImmMap{
$this->cellLabelsTable->getEditedVideoOrderIdKey() => $edited_video_order_id,
$this->cellLabelsTable->getLabelKey() => $create_cell_label_request->getLabel(),
$this->cellLabelsTable->getCellNumberKey() => $cell_number
};

++$cell_number;
}

// Execute create cell-label query
$cell_label_insert_query_handle = $this->cellLabelBatchInsertQuery->insert(
$cell_label_field_map_list->toImmVector()
);

// Block until create cell-label query finishes
$cell_label_insert_query_handle
->getWaitHandle()
->join();
}
}
@@ -23,7 +23,7 @@ class DeleteConfirmedOrderMethod {
$where_clause_builder
->setFirstClause(
new EqualsWhereClause(
$this->cellLabelsTable->getConfirmedOrderIdKey(),
$this->cellLabelsTable->getEditedVideoOrderIdKey(),
$confirmed_order_id->getNumber()
)
)
@@ -28,11 +28,6 @@ class UpdateConfirmedOrderMethod {
$update_field_map[$this->table->getShortCodeIdKey()] = $short_code_field->get();
}

$recording_duration_field = $request->getRecordingDuration();
if ($recording_duration_field !== null) {
$update_field_map[$this->table->getRecordingDurationKey()] = $recording_duration_field->get();
}

// Update confirmed order object with provided fields
try {
$this->updateQuery
@@ -0,0 +1,12 @@
<?hh // strict

class CreateCellLabelRequest {

public function __construct(
private string $label
) {}

public function getLabel(): string {
return $this->label;
}
}
File renamed without changes.
@@ -0,0 +1,37 @@
<?hh // strict

class CreateConfirmOrderRequest {

public function __construct(
private UnsignedInt $reservedOrderId,
private Timestamp $timeOrderMade,
private string $title,
private string $description,
private UnsignedInt $shortCodeId,
private ?CreateEditedVideoOrderRequest $editedVideoOrder
) {}

public function getReserveOrderId(): UnsignedInt {
return $this->reservedOrderId;
}

public function getTimeOrderMade(): Timestamp {
return $this->timeOrderMade;
}

public function getTitle(): string {
return $this->title;
}

public function getDescription(): string {
return $this->description;
}

public function getShortCodeId(): UnsignedInt {
return $this->shortCodeId;
}

public function getCreateEditedVideoOrderRequest(): ?CreateEditedVideoOrderRequest {
return $this->editedVideoOrder;
}
}
@@ -0,0 +1,17 @@
<?hh // strict

class CreateEditedVideoOrderRequest {

public function __construct(
private UnsignedInt $recordingDurationMinutes,
private ImmVector<CreateCellLabelRequest> $cellLabels
) {}

public function getRecordingDurationMinutes(): UnsignedInt {
return $this->recordingDurationMinutes;
}

public function getCellLabels(): ImmVector<CreateCellLabelRequest> {
return $this->cellLabels;
}
}
@@ -1,6 +1,6 @@
<?hh // strict

class ObjectVectorRequestField<Ttype> {
class ObjectVectorApiRequestField<Ttype> {

public function __construct(
private string $key,
@@ -0,0 +1,8 @@
<?hh // strict

class CellLabelVectorApiRequestFieldFactoryBuilder extends ObjectVectorApiRequestFieldFactoryBuilder<CreateCellLabelApiRequest> {

public function __construct() {
parent::__construct(new CreateCellLabelApiRequestFactory());
}
}

This file was deleted.

@@ -1,8 +1,8 @@
<?hh // strict

class CreateCellLabelVectorRequestFieldFactoryBuilder extends ObjectVectorRequestFieldFactoryBuilder<CreateCellLabelRequest> {
class CreateCellLabelVectorApiRequestFieldFactoryBuilder extends ObjectVectorApiRequestFieldFactoryBuilder<CreateCellLabelApiRequest> {

public function __construct() {
parent::__construct(new CreateCellLabelRequestFactory());
parent::__construct(new CreateCellLabelApiRequestFactory());
}
}
@@ -1,13 +1,13 @@
<?hh // strict

class ObjectVectorRequestFieldFactory<T> {
class ObjectVectorApiRequestFieldFactory<T> {

public function __construct(
private ImmVector<VectorRequestFieldConstraint> $vectorRequestFieldConstraintList,
private RequestFactory<T> $requestFactory
) {}

public function make(string $key, mixed $value): ObjectVectorRequestField<T> {
public function make(string $key, mixed $value): ObjectVectorApiRequestField<T> {
// Ensure that value is array type
if (!is_array($value)) {
throw new RequestFieldTypeConversionException(
@@ -30,7 +30,7 @@ class ObjectVectorRequestFieldFactory<T> {
$vector[] = $this->requestFactory->make(new ImmMap($element));
}

return new ObjectVectorRequestField(
return new ObjectVectorApiRequestField(
$key,
$vector->toImmVector(),
$this->vectorRequestFieldConstraintList
@@ -1,6 +1,6 @@
<?hh // strict

class ObjectVectorRequestFieldFactoryBuilder<T> {
class ObjectVectorApiRequestFieldFactoryBuilder<T> {

private Vector<VectorRequestFieldConstraint> $vectorRequestFieldConstraintList;

@@ -15,8 +15,8 @@ class ObjectVectorRequestFieldFactoryBuilder<T> {
return $this;
}

public function build(): ObjectVectorRequestFieldFactory<T> {
return new ObjectVectorRequestFieldFactory(
public function build(): ObjectVectorApiRequestFieldFactory<T> {
return new ObjectVectorApiRequestFieldFactory(
$this->vectorRequestFieldConstraintList->toImmVector(),
$this->requestFactory
);

This file was deleted.

@@ -1,6 +1,6 @@
<?hh // strict

class CreateCellLabelRequestFactory implements RequestFactory<CreateCellLabelRequest> {
class CreateCellLabelApiRequestFactory implements RequestFactory<CreateCellLabelApiRequest> {

private RequestFieldFactory<UnsignedInt> $cellNumberFieldFactory;
private RequestFieldFactory<string> $labelFieldFactory;
@@ -15,11 +15,11 @@ class CreateCellLabelRequestFactory implements RequestFactory<CreateCellLabelReq
$this->labelFieldFactory = $string_field_factory_builder->build();
}

public function make(ImmMap<string, mixed> $raw_field_map): CreateCellLabelRequest {
$cell_label_request_builder = new CreateCellLabelRequestBuilder();
public function make(ImmMap<string, mixed> $raw_field_map): CreateCellLabelApiRequest {
$cell_label_request_builder = new CreateCellLabelApiRequestBuilder();
foreach ($raw_field_map as $key => $value) {
switch ($key) {
case CreateCellLabelRequest::LABEL_KEY:
case CreateCellLabelApiRequest::LABEL_KEY:
$cell_label_request_builder->setLabel(
$this->labelFieldFactory->make($key, $value)
);
@@ -1,13 +1,12 @@
<?hh // strict

class ConfirmOrderRequestFactory implements RequestFactory<ConfirmOrderRequest> {
class ConfirmOrderApiRequestFactory implements RequestFactory<ConfirmOrderApiRequest> {

private RequestFieldFactory<UnsignedInt> $reserveOrderIdFieldFactory;
private RequestFieldFactory<string> $titleFieldFactory;
private RequestFieldFactory<string> $descriptionFieldFactory;
private RequestFieldFactory<UnsignedInt> $shortCodeIdFieldFactory;
private RequestFieldFactory<UnsignedInt> $recordingDurationFieldFactory;
private ObjectVectorRequestFieldFactory<CreateCellLabelRequest> $cellLabelsRequestFieldFactory;
private EditedVideoOrderApiRequestFactory $editedVideoOrderRequestFactory;

public function __construct() {
$uint_field_factory_builder = new UnsignedIntRequestFieldFactoryBuilder();
@@ -16,9 +15,6 @@ class ConfirmOrderRequestFactory implements RequestFactory<ConfirmOrderRequest>
// Create reserve order id field factory
$this->reserveOrderIdFieldFactory = $uint_field_factory_builder->build();

// Create recording duration field factory
$this->recordingDurationFieldFactory = $uint_field_factory_builder->build();

// Create title field factory
$this->titleFieldFactory = $string_field_factory_builder->build();

@@ -28,45 +24,34 @@ class ConfirmOrderRequestFactory implements RequestFactory<ConfirmOrderRequest>
// Create short coding field factory
$this->shortCodeIdFieldFactory = $uint_field_factory_builder->build();

// Create cell label request
$cell_label_vector_factory_builder = new CreateCellLabelVectorRequestFieldFactoryBuilder();
$this->cellLabelsRequestFieldFactory = $cell_label_vector_factory_builder->build();
// Create edited-video-order-request-factory
$this->editedVideoOrderRequestFactory = new EditedVideoOrderApiRequestFactory();
}

public function make(ImmMap<string, mixed> $raw_field_map): ConfirmOrderRequest {
$confirmed_order_request_builder = new ConfirmOrderRequestBuilder();
public function make(ImmMap<string, mixed> $raw_field_map): ConfirmOrderApiRequest {
$confirmed_order_request_builder = new ConfirmOrderApiRequestBuilder();
foreach ($raw_field_map as $key => $value) {
switch ($key) {
case ConfirmOrderRequest::RSVD_ORDER_ID_KEY:
case ConfirmOrderApiRequest::RSVD_ORDER_ID_KEY:
$confirmed_order_request_builder->setRsvdOrderId(
$this->reserveOrderIdFieldFactory->make($key, $value)
);
break;
case ConfirmOrderRequest::TITLE_KEY:
case ConfirmOrderApiRequest::TITLE_KEY:
$confirmed_order_request_builder->setTitle(
$this->titleFieldFactory->make($key, $value)
);
break;
case ConfirmOrderRequest::DESCRIPTION_KEY:
case ConfirmOrderApiRequest::DESCRIPTION_KEY:
$confirmed_order_request_builder->setDescription(
$this->descriptionFieldFactory->make($key, $value)
);
break;
case ConfirmOrderRequest::SHORT_CODE_KEY:
case ConfirmOrderApiRequest::SHORT_CODE_KEY:
$confirmed_order_request_builder->setShortCodeId(
$this->shortCodeIdFieldFactory->make($key, $value)
);
break;
case ConfirmOrderRequest::RECORDING_DURATION_KEY:
$confirmed_order_request_builder->setRecordingDuration(
$this->recordingDurationFieldFactory->make($key, $value)
);
break;
case ConfirmOrderRequest::CELL_LABEL_REQUESTS_KEY:
$confirmed_order_request_builder->setCellLabels(
$this->cellLabelsRequestFieldFactory->make($key, $value)
);
break;
default:
throw new UnexpectedRequestFieldKeyException(__CLASS__, $key);
break;
@@ -0,0 +1,40 @@
<?hh // strict

class EditedVideoOrderApiRequestFactory implements RequestFactory<EditedVideoOrderApiRequest> {

private RequestFieldFactory<UnsignedInt> $recordingDurationFieldFactory;
private ObjectVectorApiRequestFieldFactory<CreateCellLabelApiRequest> $cellLabelsRequestFieldFactory;

public function __construct() {
$uint_field_factory_builder = new UnsignedIntRequestFieldFactoryBuilder();

// Create recording duration field factory
$this->recordingDurationFieldFactory = $uint_field_factory_builder->build();

// Create cell label request
$cell_label_vector_factory_builder = new CreateCellLabelVectorApiRequestFieldFactoryBuilder();
$this->cellLabelsRequestFieldFactory = $cell_label_vector_factory_builder->build();
}

public function make(ImmMap<string, mixed> $raw_field_map): EditedVideoOrderApiRequest {
$edited_order_request_builder = new EditedVideoOrderApiRequestBuilder();
foreach ($raw_field_map as $key => $value) {
switch ($key) {
case EditedVideoOrderApiRequest::RECORDING_DURATION_KEY:
$edited_order_request_builder->setRecordingDurationMinutes(
$this->recordingDurationFieldFactory->make($key, $value)
);
break;
case EditedVideoOrderApiRequest::CELL_LABEL_KEY:
$edited_order_request_builder->setCellLabels(
$this->cellLabelsRequestFieldFactory->make($key, $value)
);
break;
default:
throw new UnexpectedRequestFieldKeyException(__CLASS__, $key);
break;
}
}
return $edited_order_request_builder->build();
}
}
@@ -1,8 +1,8 @@
<?hh // strict

class CreateCellLabelRequest {
class CreateCellLabelApiRequest {

const string REQUEST_OBJECT_NAME = "CreateCellLabelRequest";
const string REQUEST_OBJECT_NAME = "CreateCellLabelApiRequest";

const string LABEL_KEY = "label";

@@ -15,7 +15,7 @@ class CreateCellLabelRequest {
}
}

class CreateCellLabelRequestBuilder {
class CreateCellLabelApiRequestBuilder {

private ?RequestField<string> $label;

@@ -26,17 +26,17 @@ class CreateCellLabelRequestBuilder {
return $this;
}

public function build(): CreateCellLabelRequest {
public function build(): CreateCellLabelApiRequest {
// Check for missing request keys
if ($this->label === null) {
throw new UnsetRequestFieldException(
CreateCellLabelRequest::REQUEST_OBJECT_NAME,
CreateCellLabelRequest::LABEL_KEY
CreateCellLabelApiRequest::REQUEST_OBJECT_NAME,
CreateCellLabelApiRequest::LABEL_KEY
);
}

// Extrude request object
return new CreateCellLabelRequest(
return new CreateCellLabelApiRequest(
$this->label
);
}
@@ -1,8 +1,8 @@
<?hh // strict

class CellLabelRequest {
class UpdateCellLabelApiRequest {

const string REQUEST_OBJECT_NAME = "CellLabelRequest";
const string REQUEST_OBJECT_NAME = "UpdateCellLabelApiRequest";

const string CONFIRMED_ORDER_ID_KEY = "co-id";
const string CELL_NUMBER_KEY = "cell-num";
@@ -27,7 +27,7 @@ class CellLabelRequest {
}
}

class CellLabelRequestBuilder {
class UpdateCellLabelApiRequestBuilder {

private ?RequestField<UnsignedInt> $confirmedOrderId;
private ?RequestField<UnsignedInt> $cellNumber;
@@ -54,29 +54,29 @@ class CellLabelRequestBuilder {
return $this;
}

public function build(): CellLabelRequest {
public function build(): UpdateCellLabelApiRequest {
// Check for missing request keys
if ($this->confirmedOrderId === null) {
throw new UnsetRequestFieldException(
CellLabelRequest::REQUEST_OBJECT_NAME,
CellLabelRequest::CONFIRMED_ORDER_ID_KEY
UpdateCellLabelApiRequest::REQUEST_OBJECT_NAME,
UpdateCellLabelApiRequest::CONFIRMED_ORDER_ID_KEY
);
}
if ($this->cellNumber === null) {
throw new UnsetRequestFieldException(
CellLabelRequest::REQUEST_OBJECT_NAME,
CellLabelRequest::CELL_NUMBER_KEY
UpdateCellLabelApiRequest::REQUEST_OBJECT_NAME,
UpdateCellLabelApiRequest::CELL_NUMBER_KEY
);
}
if ($this->label === null) {
throw new UnsetRequestFieldException(
CellLabelRequest::REQUEST_OBJECT_NAME,
CellLabelRequest::LABEL_KEY
UpdateCellLabelApiRequest::REQUEST_OBJECT_NAME,
UpdateCellLabelApiRequest::LABEL_KEY
);
}

// Extrude request object
return new CellLabelRequest(
return new UpdateCellLabelApiRequest(
$this->confirmedOrderId,
$this->cellNumber,
$this->label
@@ -0,0 +1,90 @@
<?hh // strict

class ConfirmOrderApiRequest {

const string REQUEST_OBJECT_NAME = "ConfirmOrderApiRequest";

const string RSVD_ORDER_ID_KEY = 'rid';
const string TITLE_KEY = 'title';
const string DESCRIPTION_KEY = 'desc';
const string SHORT_CODE_KEY = 'code-id';
const string EDITED_VIDEO_ORDER_REQUEST = 'edited-video';

public function __construct(
private RequestField<UnsignedInt> $rsvdOrderId,
private RequestField<string> $title,
private RequestField<string> $description,
private RequestField<UnsignedInt> $shortCodeId,
private ?EditedVideoOrderApiRequest $editedVideoOrder
) {}

public function getRsvdOrderId(): RequestField<UnsignedInt> {
return $this->rsvdOrderId;
}

public function getTitle(): RequestField<string> {
return $this->title;
}

public function getDescription(): RequestField<string> {
return $this->description;
}

public function getShortCodeId(): RequestField<UnsignedInt> {
return $this->shortCodeId;
}

public function getEditedVideoOrderApiRequest(): ?EditedVideoOrderApiRequest {
return $this->editedVideoOrder;
}
}

class ConfirmOrderApiRequestBuilder {

private ?RequestField<UnsignedInt> $rsvdOrderId;
private ?RequestField<string> $title;
private ?RequestField<string> $description;
private ?RequestField<UnsignedInt> $shortCodeId;
private ?EditedVideoOrderApiRequest $editedVideoOrder;

public function setRsvdOrderId(RequestField<UnsignedInt> $rsvd_order_id): this {
$this->rsvdOrderId = $rsvd_order_id;
return $this;
}

public function setTitle(RequestField<string> $title): this {
$this->title = $title;
return $this;
}

public function setDescription(RequestField<string> $description): this {
$this->description = $description;
return $this;
}

public function setShortCodeId(RequestField<UnsignedInt> $short_code_id): this {
$this->shortCodeId = $short_code_id;
return $this;
}

private function checkNotNull<T>(?T $field, string $key): T {
if ($field === null) {
throw new UnsetRequestFieldException(
ConfirmOrderApiRequest::REQUEST_OBJECT_NAME,
$key
);
}
return $field;
}

public function build(): ConfirmOrderApiRequest {
// Extrude request object and ensure fields are not null
return new ConfirmOrderApiRequest(
$this->checkNotNull($this->rsvdOrderId, ConfirmOrderApiRequest::RSVD_ORDER_ID_KEY),
$this->checkNotNull($this->title, ConfirmOrderApiRequest::TITLE_KEY),
$this->checkNotNull($this->description, ConfirmOrderApiRequest::DESCRIPTION_KEY),
$this->checkNotNull($this->shortCodeId, ConfirmOrderApiRequest::SHORT_CODE_KEY),
$this->editedVideoOrder
);
}
}

This file was deleted.

@@ -0,0 +1,64 @@
<?hh // strict

class EditedVideoOrderApiRequest {

const string REQUEST_OBJECT_NAME = "EditedVideoOrderApiRequest";
const string RECORDING_DURATION_KEY = "recordingDurationMinutes";
const string CELL_LABEL_KEY = "labels";

public function __construct(
private RequestField<UnsignedInt> $recordingDurationMinutes,
private ObjectVectorApiRequestField<CreateCellLabelApiRequest> $cellLabels
) {}

public function getRecordingDurationMinutes(): RequestField<UnsignedInt> {
return $this->recordingDurationMinutes;
}

public function getCellLabels(): ObjectVectorApiRequestField<CreateCellLabelApiRequest> {
return $this->cellLabels;
}
}

class EditedVideoOrderApiRequestBuilder {

private ?RequestField<UnsignedInt> $recordingDurationMinutes;
private ?ObjectVectorApiRequestField<CreateCellLabelApiRequest> $cellLabels;

public function setRecordingDurationMinutes(
RequestField<UnsignedInt> $recording_duration
): this {
$this->recordingDurationMinutes = $recording_duration;
return $this;
}

public function setCellLabels(
ObjectVectorApiRequestField<CreateCellLabelApiRequest> $cell_labels
): this {
$this->cellLabels = $cell_labels;
return $this;
}

private function checkNotNull<T>(?T $field, string $key): T {
if ($field === null) {
throw new UnsetRequestFieldException(
EditedVideoOrderApiRequest::REQUEST_OBJECT_NAME,
$key
);
}
return $field;
}

public function build(): EditedVideoOrderApiRequest {
return new EditedVideoOrderApiRequest(
$this->checkNotNull(
$this->recordingDurationMinutes,
EditedVideoOrderApiRequest::RECORDING_DURATION_KEY
),
$this->checkNotNull(
$this->cellLabels,
EditedVideoOrderApiRequest::CELL_LABEL_KEY
)
);
}
}
@@ -0,0 +1,14 @@
<?hh // strict

class UnsignedFloat {

public function __construct(
private float $number
) {
invariant($this->number >= 0, "Must be non-negative!");
}

public function getNumber(): float {
return $this->number;
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,6 @@
/**
* Order configuration table creation
*/
CREATE TABLE OrderConfiguration (
scopesCount INT UNSIGNED NOT NULL
);
@@ -0,0 +1,8 @@
/**
* OrderPricePolicy table creation
* - price: price per group of 4 scopes per hour
*/
CREATE TABLE OrderPricePolicy (
price FLOAT UNSIGNED NOT NULL,
timeEnacted TIMESTAMP NOT NULL
);
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -19,4 +19,3 @@ CREATE TABLE BasicVideos (
UNIQUE KEY(confirmedOrderId, scopeIndex),
expirationTime TIMESTAMP NOT NULL
);

File renamed without changes.
@@ -0,0 +1,8 @@
/**
* VideoEditingPricePolicy table creation
* - TODO: decide how to price this...
*/
CREATE TABLE VideoEditingPricePolicy (
price FLOAT UNSIGNED NOT NULL,
timeEnacted TIMESTAMP NOT NULL
);
@@ -0,0 +1,9 @@
/**
* VideoStoragePricePolicy table creation
* - price: price per Gb per day
*/
CREATE TABLE VideoStoragePricePolicy (
price FLOAT UNSIGNED NOT NULL,
numberFreeDays INT UNSIGNED NOT NULL,
timeEnacted TIMESTAMP NOT NULL
);