Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minimal support for 4.x #733

Merged
merged 18 commits into from
Oct 27, 2023
Merged
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
2 changes: 1 addition & 1 deletion integration-tests/lts/primitives.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe("primitives", () => {
);
assert.equal(
e.std.range(upperRange).toEdgeQL(),
`std::range(<std::int64>{}, 8, inc_lower := true, inc_upper := false)`
`std::range(<std::int64>{}, 8, inc_lower := false, inc_upper := false)`
);
assert.equal(
e.std.range(dateRange).toEdgeQL(),
Expand Down
3 changes: 2 additions & 1 deletion integration-tests/lts/select.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,15 @@ describe("select", () => {
test("* in polymorphic", async () => {
const q = e.select(e.Person, () => ({
...e.is(e.Hero, e.Hero["*"]),
name: true,
Copy link
Collaborator Author

@scotttrinh scotttrinh Oct 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change reflects the new behavior of 4.x where the parent type's cardinality is considered when using polymorphic queries. In this case, Person has a required name, but the query can return Person records that are not Heros, which would return a empty set name, which is invalid for Person.

}));

// 'id' is filtered out since it is not valid in a polymorphic expr
tc.assert<
tc.IsExact<
$infer<typeof q>,
{
name: string | null;
name: string;
height: string | null;
number_of_movies: number | null;
secret_identity: string | null;
Expand Down
4 changes: 3 additions & 1 deletion integration-tests/nightly/dbschema/default.esdl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module default {

type WithMultiRange {
required ranges: multirange<std::int32>;
};
}
7 changes: 7 additions & 0 deletions integration-tests/nightly/dbschema/migrations/00001.edgeql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE MIGRATION m1rlwpc5ikrkb7cvylhbcntglvnanm524yb6si5xlcjk6gd2lczugq
ONTO initial
{
CREATE TYPE default::WithMultiRange {
CREATE REQUIRED PROPERTY ranges: multirange<std::int32>;
};
};
45 changes: 45 additions & 0 deletions integration-tests/nightly/multirange.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { Client, MultiRange } from "edgedb";
import e from "./dbschema/edgeql-js";
import { setupTests, tc, teardownTests } from "./setupTeardown";

import type { WithMultiRange } from "./dbschema/interfaces";

interface BaseObject {
id: string;
}
interface test_WithMultiRange extends BaseObject {
ranges: MultiRange<number>;
}

describe("multirange", () => {
let client: Client;
beforeAll(async () => {
const setup = await setupTests();
({ client } = setup);
});

afterAll(async () => {
await teardownTests(client);
}, 10_000);

test("check generated interfaces", () => {
tc.assert<tc.IsExact<WithMultiRange, test_WithMultiRange>>(true);
});

test("inferred return type + literal encoding", async () => {
const query = e.select(e.WithMultiRange, () => ({
ranges: true,
}));

const result = await query.run(client);

tc.assert<
tc.IsExact<
typeof result,
{
ranges: MultiRange<number>;
}[]
>
>(true);
});
});
1 change: 1 addition & 0 deletions integration-tests/nightly/setupTeardown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export async function setupTests() {
async function cleanupData(client: Client) {
await client.execute(`
# Delete any user-defined objects here
delete WithMultiRange;
`);
}

Expand Down
12 changes: 7 additions & 5 deletions packages/driver/genErrors.js → packages/driver/genErrors.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
* limitations under the License.
*/

const fs = require("fs");
const path = require("path");

const getStdin = require("get-stdin");
const prettier = require("prettier");
import { fileURLToPath, URL } from "url";
import fs from "node:fs";
import path from "node:path";
import getStdin from "get-stdin";
import prettier from "prettier";

class Buffer {
constructor() {
Expand All @@ -39,6 +39,8 @@ class Buffer {
return this.buf.join("\n");
}
}
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const __filename = new URL("", import.meta.url).pathname;

(async () => {
const prettierOptions = (await prettier.resolveConfig(__dirname)) ?? {};
Expand Down
2 changes: 1 addition & 1 deletion packages/driver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"test": "npx --node-options='--experimental-fetch' jest --detectOpenHandles",
"lint": "tslint 'packages/*/src/**/*.ts'",
"format": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
"gen-errors": "edb gen-errors-json --client | node genErrors.js",
"gen-errors": "edb gen-errors-json --client | node genErrors.mjs",
"watch": "nodemon -e js,ts,tsx --ignore dist -x ",
"dev": "yarn tsc --project tsconfig.json --incremental && yarn build:deno"
}
Expand Down
12 changes: 8 additions & 4 deletions packages/driver/src/codecs/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
* limitations under the License.
*/

import { ICodec, Codec, ScalarCodec, uuid, CodecKind } from "./ifaces";
import type { ICodec, uuid, CodecKind } from "./ifaces";
import { Codec, ScalarCodec } from "./ifaces";
import { WriteBuffer, ReadBuffer } from "../primitives/buffer";
import { TupleCodec } from "./tuple";
import { RangeCodec } from "./range";
import { MultiRangeCodec, RangeCodec } from "./range";
import { InvalidArgumentError, ProtocolError } from "../errors";
import { NamedTupleCodec } from "./namedtuple";

Expand All @@ -39,7 +40,8 @@ export class ArrayCodec extends Codec implements ICodec {
this.subCodec instanceof ScalarCodec ||
this.subCodec instanceof TupleCodec ||
this.subCodec instanceof NamedTupleCodec ||
this.subCodec instanceof RangeCodec
this.subCodec instanceof RangeCodec ||
this.subCodec instanceof MultiRangeCodec
)
) {
throw new InvalidArgumentError(
Expand All @@ -48,7 +50,9 @@ export class ArrayCodec extends Codec implements ICodec {
}

if (!Array.isArray(obj) && !isTypedArray(obj)) {
throw new InvalidArgumentError("an array was expected");
throw new InvalidArgumentError(
`an array was expected (got type ${obj.constructor.name})`
);
}

const subCodec = this.subCodec;
Expand Down
1 change: 1 addition & 0 deletions packages/driver/src/codecs/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const INVALID_CODEC_ID = "ffffffffffffffffffffffffffffffff";
export const KNOWN_TYPES = new Map<uuid, string>([
["00000000000000000000000000000001", "anytype"],
["00000000000000000000000000000002", "anytuple"],
["00000000000000000000000000000003", "anyobject"],
["000000000000000000000000000000f0", "std"],
["000000000000000000000000000000ff", "empty-tuple"],
["00000000000000000000000000000100", "std::uuid"],
Expand Down
3 changes: 2 additions & 1 deletion packages/driver/src/codecs/ifaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export type CodecKind =
| "set"
| "scalar"
| "sparse_object"
| "range";
| "range"
| "multirange";

export interface ICodec {
readonly tid: uuid;
Expand Down
Loading
Loading