Skip to content

Commit

Permalink
use join for 2-way connection + we get the edges returned correctly w…
Browse files Browse the repository at this point in the history
…ith the right id2
  • Loading branch information
lolopinto committed Sep 5, 2023
1 parent 5132fb7 commit 576418d
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 61 deletions.
9 changes: 9 additions & 0 deletions ts/src/core/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,22 @@ export interface QueryableDataOptions
extends SelectBaseDataOptions,
QueryDataOptions {}

// for now, no complicated joins or no need to support multiple joins
// just one simple join
interface JoinOptions<T2 extends Data = Data, K2 = keyof T2> {
tableName: string;
alias?: string;
clause: clause.Clause<T2,K2>;
}

export interface QueryDataOptions<T extends Data = Data, K = keyof T> {
distinct?: boolean;
clause: clause.Clause<T, K>;
orderby?: OrderBy; // this technically doesn't make sense when querying just one row but whatevs
groupby?: K;
limit?: number;
disableTransformations?: boolean;
join?:JoinOptions;
}

// For loading data from database
Expand Down
51 changes: 32 additions & 19 deletions ts/src/core/clause.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class simpleClause<T extends Data, K = keyof T> implements Clause<T, K> {
}
}

// NB: we're not using alias in this class in clause method
// if we end up with a subclass that does, we need to handle it
class queryClause<T extends Data, K = keyof T> implements Clause<T, K> {
constructor(
protected dependentQueryOptions: QueryableDataOptions, // private value: any, // private op: string, // private handleNull?: Clause<T, K>,
Expand Down Expand Up @@ -143,18 +145,6 @@ class existsQueryClause<T extends Data, K = keyof T> extends queryClause<T, K> {
}
}

class columnInQueryClause<T extends Data, K = keyof T> extends queryClause<
T,
K
> {
constructor(
protected dependentQueryOptions: QueryableDataOptions,
protected col: K,
) {
super(dependentQueryOptions, `${col} IN`);
}
}

class isNullClause<T extends Data, K = keyof T> implements Clause<T, K> {
constructor(protected col: K) {}

Expand Down Expand Up @@ -203,6 +193,30 @@ class isNotNullClause<T extends Data, K = keyof T> implements Clause<T, K> {
}
}

class simpleExpression<T extends Data, K = keyof T> implements Clause<T, K> {
constructor(protected expression: string) {}

clause(idx: number, alias?: string): string {
return this.expression;
}

columns(): K[] {
return [];
}

values(): any[] {
return [];
}

logValues(): any[] {
return [];
}

instanceKey(): string {
return `${this.expression}`;
}
}

class arraySimpleClause<T extends Data, K = keyof T> implements Clause<T, K> {
constructor(protected col: K, private value: any, private op: string) {}

Expand Down Expand Up @@ -833,13 +847,6 @@ export function DBTypeNotIn<T extends Data, K = keyof T>(
return new notInClause(col, values, typ);
}

export function ColInQuery<T extends Data, K = keyof T>(
col: K,
queryOptions: QueryableDataOptions,
): Clause<T, K> {
return new columnInQueryClause(queryOptions, col);
}

interface TsQuery {
// todo lang ::reconfig
language: "english" | "french" | "german" | "simple";
Expand Down Expand Up @@ -1210,3 +1217,9 @@ export function getCombinedClause<V extends Data = Data, K = keyof V>(
}
return cls;
}

export function Expression<T extends Data, K = keyof T>(
expression: string,
): Clause<T, K> {
return new simpleExpression(expression);
}
47 changes: 13 additions & 34 deletions ts/src/core/ent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1370,17 +1370,11 @@ export function getDefaultLimit() {
}

function defaultEdgeQueryOptions(
edgeData: AssocEdgeData,
id1: ID,
edgeType: string,
id2?: ID,
id1Clause?: (edgeData: AssocEdgeData) => clause.Clause,
): Required<Omit<EdgeQueryableDataOptions, "disableTransformations">> {
let id1cls: clause.Clause = clause.Eq("id1", id1);
if (id1Clause) {
id1cls = id1Clause(edgeData);
}
let cls = clause.And(id1cls, clause.Eq("edge_type", edgeType));
let cls = clause.And(clause.Eq("id1", id1), clause.Eq("edge_type", edgeType));
if (id2) {
cls = clause.And(cls, clause.Eq("id2", id2));
}
Expand Down Expand Up @@ -1448,21 +1442,14 @@ export async function loadCustomEdges<T extends AssocEdge>(
async function loadEdgesInfo<T extends AssocEdge>(
options: loadCustomEdgesOptions<T>,
id2?: ID,
id1Clause?: (edgeData: AssocEdgeData) => clause.Clause,
) {
const { id1, edgeType } = options;
const edgeData = await loadEdgeData(edgeType);
if (!edgeData) {
throw new Error(`error loading edge data for ${edgeType}`);
}

const defaultOptions = defaultEdgeQueryOptions(
edgeData,
id1,
edgeType,
id2,
id1Clause,
);
const defaultOptions = defaultEdgeQueryOptions(id1, edgeType, id2);
let cls = defaultOptions.clause;
if (options.queryOptions?.clause) {
cls = clause.And(cls, options.queryOptions.clause);
Expand Down Expand Up @@ -1572,31 +1559,23 @@ export async function loadEdgeForID2<T extends AssocEdge>(
export async function loadTwoWayEdges<T extends AssocEdge>(
opts: loadCustomEdgesOptions<T>,
): Promise<T[]> {
const {
cls: actualClause,
fields,
tableName,
} = await loadEdgesInfo(opts, undefined, (edgeData: AssocEdgeData) => {
const { clause: subClause } = defaultEdgeQueryOptions(
edgeData,
opts.id1,
opts.edgeType,
);

const { cls } = getEdgeClauseAndFields(subClause, opts);
const subquery: QueryableDataOptions = {
tableName: edgeData.edgeTable,
fields: ["id2"],
clause: cls,
};
return clause.ColInQuery("id1", subquery);
});
const { cls: actualClause, fields, tableName } = await loadEdgesInfo(opts);

const rows = await loadRows({
tableName,
alias: "t1",
fields,
clause: actualClause,
context: opts.context,
join: {
tableName,
alias: "t2",
clause: clause.And(
// these are not values so need this to not think they're values...
clause.Expression("t1.id1 = t2.id2"),
clause.Expression("t1.id2 = t2.id1"),
),
},
});
return rows as T[];
}
Expand Down
10 changes: 4 additions & 6 deletions ts/src/core/loaders/assoc_edge_loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,7 @@ function commonTests() {
}
const edges = await loader.load(user.id);
const twoWay = await loader.loadTwoWay(user.id);
// TODO need to flip the edges probably. shouldn't have the source id always be id2 here...
expect(twowayIds.sort()).toEqual(twoWay.map((e) => e.id1).sort());
expect(twowayIds.sort()).toEqual(twoWay.map((e) => e.id2).sort());
expect(edges.length).toBe(10);
expect(twoWay.length).toBe(5);

Expand All @@ -497,10 +496,10 @@ function commonTests() {
twowayIds = [];
for await (const edge of twoWay) {
if (i % 2 === 0) {
twowayIds.push(edge.id1);
twowayIds.push(edge.id2);
} else {
action.builder.orchestrator.removeOutboundEdge(
edge.id1,
edge.id2,
EdgeType.UserToFollowing,
);
}
Expand All @@ -514,8 +513,7 @@ function commonTests() {
const edges2 = await loader.load(user.id);
const twoWay2 = await loader.loadTwoWay(user.id);

// TODO need to flip the edges probably. shouldn't have the source id always be id2 here...
expect(twowayIds.sort()).toEqual(twoWay2.map((e) => e.id1).sort());
expect(twowayIds.sort()).toEqual(twoWay2.map((e) => e.id2).sort());

// deleted some things here which shouldn't show up here
expect(edges2.length).toBe(8);
Expand Down
12 changes: 10 additions & 2 deletions ts/src/core/query_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,20 @@ export function buildQuery(options: QueryableDataOptions): string {
: options.fields.join(", ");

// always start at 1
const whereClause = options.clause.clause(1, options.alias);
const parts: string[] = [];
const tableName = options.alias
? `${options.tableName} AS ${options.alias}`
: options.tableName;
parts.push(`SELECT ${fields} FROM ${tableName} WHERE ${whereClause}`);
parts.push(`SELECT ${fields} FROM ${tableName}`);

let whereStart = 1;
if (options.join) {
const joinTable = options.join.alias ? `${options.join.tableName} ${options.join.alias}` : options.join.tableName;
parts.push(`JOIN ${joinTable} ON ${options.join.clause.clause(1)}`);
whereStart += options.join.clause.values().length;
}

parts.push(`WHERE ${options.clause.clause(whereStart, options.alias)}`);
if (options.groupby) {
parts.push(`GROUP BY ${options.groupby}`);
}
Expand Down

0 comments on commit 576418d

Please sign in to comment.