Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@datalens-tech/datalens-us",
"description": "United Storage",
"version": "0.0.0",
"version": "0.360.0",
"private": true,
"author": "DataLens Team <https://github.com/datalens-tech>",
"license": "Apache-2.0",
Expand Down
25 changes: 25 additions & 0 deletions src/controllers/test-graph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Request, Response} from '@gravity-ui/expresskit';

import {DEFAULT_QUERY_TIMEOUT} from '../const';
import {Order} from '../db/models-graph/order';

export default async function testGraphController(_: Request, res: Response) {
const result = await Order.query(Order.replica)
.withGraphJoined('[customer]')
.timeout(DEFAULT_QUERY_TIMEOUT);

res.status(200).send(result);

// const result = await Order.query(Order.replica)
// .withGraphJoined('[customer, shipments.[product]]')
// .timeout(DEFAULT_QUERY_TIMEOUT);

// res.status(200).send(result);

// const result = await Order.query(Order.replica)
// .withGraphJoined('[customer, shipments.[product.[orders]], products.[orders]]')
// .first()
// .timeout(DEFAULT_QUERY_TIMEOUT);

res.status(200).send(result);
}
22 changes: 22 additions & 0 deletions src/controllers/test-presentations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {Request, Response} from '@gravity-ui/expresskit';

import {DEFAULT_QUERY_TIMEOUT} from '../const';
import {Order, OrderColumn} from '../db/models-presentations/order';
import {JoinedOrderCustomer} from '../db/models-presentations/order/presentations/joined-order-customer';
// import {JoinedOrderCustomerShipments} from '../db/models-presentations/order/presentations/joined-order-customer-shipments';
// import {JoinedOrderCustomerShipmentsProducts} from '../db/models-presentations/order/presentations/joined-order-customer-shipments-products';
// import {PartialOrder} from '../db/models-presentations/order/presentations/partial-order';

export default async function testPresentationsController(_: Request, res: Response) {
const result = await JoinedOrderCustomer.query(Order.replica)
.where({
[`${Order.tableName}.${OrderColumn.OrderId}`]: '1988457138476811343',
})
// .findOne({
// orderId: '1988457138476811343',
// })
.first()
.timeout(DEFAULT_QUERY_TIMEOUT);

res.status(200).send(result);
}
37 changes: 37 additions & 0 deletions src/db/SCHEMA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
```sql
CREATE TABLE orders (
order_id BIGINT DEFAULT get_id() PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
customer_id BIGINT NOT NULL,

CONSTRAINT fk_customer
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
ON DELETE CASCADE
);

CREATE TABLE shipments (
shipment_id BIGINT DEFAULT get_id() PRIMARY KEY,
order_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,

CONSTRAINT fk_order
FOREIGN KEY (order_id)
REFERENCES orders(order_id)
ON DELETE CASCADE,
CONSTRAINT fk_product
FOREIGN KEY (product_id)
REFERENCES products(product_id)
ON DELETE RESTRICT
);

CREATE TABLE customers (
customer_id BIGINT DEFAULT get_id() PRIMARY KEY,
name TEXT NOT NULL
);

CREATE TABLE products (
product_id BIGINT DEFAULT get_id() PRIMARY KEY,
name TEXT NOT NULL
);
```
30 changes: 30 additions & 0 deletions src/db/models-graph/customer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {Model} from '../..';
import {Order} from '../order';

export class Customer extends Model {
static get tableName() {
return 'customers';
}

static get idColumn() {
return 'customerId';
}

static get relationMappings() {
return {
orders: {
relation: Model.HasManyRelation,
modelClass: Order,
join: {
from: `${Customer.tableName}.customerId`,
to: `${Order.tableName}.customerId`,
},
},
};
}

customerId!: string;
name!: string;

orders?: Order[];
}
57 changes: 57 additions & 0 deletions src/db/models-graph/order/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {Model} from '../..';
import {Customer} from '../customer';
import {Product} from '../product';
import {Shipment} from '../shipment';

export class Order extends Model {
static get tableName() {
return 'orders';
}

static get idColumn() {
return 'orderId';
}

static get relationMappings() {
return {
customer: {
relation: Model.BelongsToOneRelation,
modelClass: Customer,
join: {
from: `${Order.tableName}.customerId`,
to: `${Customer.tableName}.customerId`,
},
},

shipments: {
relation: Model.HasManyRelation,
modelClass: Shipment,
join: {
from: `${Order.tableName}.orderId`,
to: `${Shipment.tableName}.orderId`,
},
},

products: {
relation: Model.ManyToManyRelation,
modelClass: Product,
join: {
from: `${Order.tableName}.orderId`,
through: {
from: `${Shipment.tableName}.orderId`,
to: `${Shipment.tableName}.productId`,
},
to: `${Product.tableName}.productId`,
},
},
};
}

orderId!: string;
createdAt!: string;
customerId!: string;

customer?: Customer;
shipments?: Shipment[];
products?: Product[];
}
45 changes: 45 additions & 0 deletions src/db/models-graph/product/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {Model} from '../..';
import {Order} from '../order';
import {Shipment} from '../shipment';

export class Product extends Model {
static get tableName() {
return 'products';
}

static get idColumn() {
return 'productId';
}

static get relationMappings() {
return {
shipments: {
relation: Model.HasManyRelation,
modelClass: Shipment,
join: {
from: `${Product.tableName}.productId`,
to: `${Shipment.tableName}.productId`,
},
},

orders: {
relation: Model.ManyToManyRelation,
modelClass: Order,
join: {
from: `${Product.tableName}.productId`,
through: {
from: `${Shipment.tableName}.productId`,
to: `${Shipment.tableName}.orderId`,
},
to: `${Order.tableName}.orderId`,
},
},
};
}

productId!: string;
name!: string;

shipments?: Shipment[];
orders?: Order[];
}
42 changes: 42 additions & 0 deletions src/db/models-graph/shipment/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {Model} from '../..';
import {Order} from '../order';
import {Product} from '../product';

export class Shipment extends Model {
static get tableName() {
return 'shipments';
}

static get idColumn() {
return 'shipmentId';
}

static get relationMappings() {
return {
order: {
relation: Model.BelongsToOneRelation,
modelClass: Order,
join: {
from: `${Shipment.tableName}.orderId`,
to: `${Order.tableName}.orderId`,
},
},

product: {
relation: Model.BelongsToOneRelation,
modelClass: Product,
join: {
from: `${Shipment.tableName}.productId`,
to: `${Product.tableName}.productId`,
},
},
};
}

shipmentId!: string;
orderId!: string;
productId!: string;

order?: Order;
product?: Product;
}
19 changes: 19 additions & 0 deletions src/db/models-presentations/customer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {Model} from '../..';

export const CustomerColumn = {
CustomerId: 'customerId',
Name: 'name',
} as const;

export class Customer extends Model {
static get tableName() {
return 'customers';
}

static get idColumn() {
return CustomerColumn.CustomerId;
}

[CustomerColumn.CustomerId]!: string;
[CustomerColumn.Name]!: string;
}
21 changes: 21 additions & 0 deletions src/db/models-presentations/order/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {Model} from '../..';

export const OrderColumn = {
OrderId: 'orderId',
CreatedAt: 'createdAt',
CustomerId: 'customerId',
} as const;

export class Order extends Model {
static get tableName() {
return 'orders';
}

static get idColumn() {
return OrderColumn.OrderId;
}

[OrderColumn.OrderId]!: string;
[OrderColumn.CreatedAt]!: string;
[OrderColumn.CustomerId]!: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type {Knex} from 'knex';
import {QueryBuilder, TransactionOrKnex, raw} from 'objection';

import {Customer} from '../../customer';
import {Product, ProductColumn} from '../../product';
import {Shipment, ShipmentColumn} from '../../shipment';
import {Order} from '../index';

import {JoinedOrderCustomerShipments} from './joined-order-customer-shipments';

export class JoinedOrderCustomerShipmentsProducts extends JoinedOrderCustomerShipments {
static _joinProducts(builder: Knex.JoinClause) {
builder.on(
`${Shipment.tableName}.${ShipmentColumn.ProductId}`,
`${Product.tableName}.${ProductColumn.ProductId}`,
);
}

static get _selectedColumns() {
return [
...super._selectedColumns,
raw(`${Product.tableName}.${ProductColumn.Name} AS product_name`),
];
}

static query(trx: TransactionOrKnex) {
const query = Order.query(trx)
.select(this._selectedColumns)
.join(Customer.tableName, this._joinCustomer)
.rightJoin(Shipment.tableName, this._rightJoinShipments)
.join(Product.tableName, this._joinProducts);

return query as QueryBuilder<
JoinedOrderCustomerShipmentsProducts,
JoinedOrderCustomerShipmentsProducts[]
>;
}

productName!: Product[typeof ProductColumn.Name];
}
Loading
Loading