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 computed fields to SQL #92

Merged
merged 5 commits into from
Dec 15, 2023
Merged

Add computed fields to SQL #92

merged 5 commits into from
Dec 15, 2023

Conversation

mohamedsalem401
Copy link
Contributor

No description provided.

Copy link

changeset-bot bot commented Dec 14, 2023

⚠️ No Changeset found

Latest commit: d97a9a6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Member

@olayway olayway left a comment

Choose a reason for hiding this comment

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

Good start but can be improved ;)

Comment on lines +71 to +83
export function getUniqueProperties(objects: any[]): string[] {
const uniqueProperties: string[] = [];

for (const object of objects) {
for (const key of Object.keys(object)) {
if (!uniqueProperties.includes(key)) {
uniqueProperties.push(key);
}
}
}

return uniqueProperties;
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export function getUniqueProperties(objects: any[]): string[] {
const uniqueProperties: string[] = [];
for (const object of objects) {
for (const key of Object.keys(object)) {
if (!uniqueProperties.includes(key)) {
uniqueProperties.push(key);
}
}
}
return uniqueProperties;
}
export function getUniqueProperties(objects: any[]): string[] {
const uniqueProperties = new Set<string>();
for (const object of objects) {
Object.keys(object).forEach(key => uniqueProperties.add(key));
}
return Array.from(uniqueProperties);
}

src/lib/schema.ts Outdated Show resolved Hide resolved
Comment on lines 35 to 42
file: File = {
_id: "",
file_path: "",
extension: "",
url_path: null,
filetype: null,
metadata: null,
};
Copy link
Member

@olayway olayway Dec 14, 2023

Choose a reason for hiding this comment

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

Don't do this... It's not necessary at all. If you want to be able to assign dynamic properties I think you can just add this to the class:

  [key: string]: any

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But this way we lose tract of all fields, it's like using any as a type. resulting in a loss of type safety.

Copy link
Member

@olayway olayway Dec 14, 2023

Choose a reason for hiding this comment

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

That's not what I meant. Use original properties + this one for dynamic ones (aka computed fields)

Comment on lines 46 to 65
this.file._id = file._id;
this.file.file_path = file.file_path;
this.file.extension = file.extension;
this.file.url_path = file.url_path;
this.file.filetype = file.filetype;
this.file.metadata = file.metadata ? JSON.parse(file.metadata) : null;

// Assign dynamic properties using index signature to this.file
for (const key in file) {
if (
key !== "_id" &&
key !== "file_path" &&
key !== "extension" &&
key !== "url_path" &&
key !== "filetype" &&
key !== "metadata"
) {
this.file[key] = file[key];
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I think this could be much simpler:

Suggested change
this.file._id = file._id;
this.file.file_path = file.file_path;
this.file.extension = file.extension;
this.file.url_path = file.url_path;
this.file.filetype = file.filetype;
this.file.metadata = file.metadata ? JSON.parse(file.metadata) : null;
// Assign dynamic properties using index signature to this.file
for (const key in file) {
if (
key !== "_id" &&
key !== "file_path" &&
key !== "extension" &&
key !== "url_path" &&
key !== "filetype" &&
key !== "metadata"
) {
this.file[key] = file[key];
}
}
Object.keys(file).forEach(key => {
if (key === "metadata") {
this[key] = file[key] ? JSON.parse(file[key]) : null;
} else {
this[key] = file[key];
}
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree

Comment on lines 80 to 82
for (let index = 0; index < properties.length; index++) {
table.string(properties[index]);
}
Copy link
Member

Choose a reason for hiding this comment

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

What happens if a computed property returns an array or a boolean? Shouldn't it be table.<some type>? Also, were the comments incorrect?

Suggested change
for (let index = 0; index < properties.length; index++) {
table.string(properties[index]);
}
properties.forEach((property) => {
table.string(property);
})

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see what you are saying, I thought about a couple of scenarios:

  • a field is array => there's no way to store arrays in SQL
  • a field is a number => what type of number? float, double, ...
  • what if a field is an object => there's no way to store objects in SQL
  • what if a field has a different type ( number/string ) across two files, should it be defaulted to string?

Copy link
Member

@olayway olayway Dec 14, 2023

Choose a reason for hiding this comment

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

Well, use any SQL types that are most suited for each JS/TS type. But it's not like everything needs to be stringified 😅 If it's an object/array, stringify to JSON.

what if a field has a different type ( number/string ) across two files, should it be defaulted to string?

You could type the computed field function signature in a way that it always should return a single type defined by the user. But for now, ok, just stringify everything. We'll properly implement it when we move computed fields definitions to their final destination = document types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, but the issue is currently computedFields don't return any thing.

the current implementation of ComputedField is unpredictable as the user changes the fileObject directly...

src/lib/schema.ts Outdated Show resolved Hide resolved
src/lib/markdowndb.ts Outdated Show resolved Hide resolved
src/lib/markdowndb.ts Outdated Show resolved Hide resolved
src/lib/markdowndb.ts Outdated Show resolved Hide resolved
@@ -25,50 +25,61 @@ interface File {
url_path: string | null;
filetype: string | null;
metadata: MetaData | null;
[key: string]: string | null | MetaData | undefined;
Copy link
Member

Choose a reason for hiding this comment

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

Rather:

Suggested change
[key: string]: string | null | MetaData | undefined;
[key: string]: unknown;

@mohamedsalem401 mohamedsalem401 merged commit d0b8d8a into main Dec 15, 2023
2 of 3 checks passed
@mohamedsalem401 mohamedsalem401 deleted the custom-sql branch December 15, 2023 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants