8000 Sqlite loader by rhazn · Pull Request #67 · jvalue/jayvee · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Sqlite loader #67

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

Merged
merged 7 commits into from
Dec 5, 2022
Merged

Sqlite loader #67

merged 7 commits into from
Dec 5, 2022

Conversation

rhazn
Copy link
Contributor
@rhazn rhazn commented Dec 2, 2022

Summary

This PR adds support for a SQLiteLoader.

Known issues

If the order of attributes in the SQLiteLoader is not fixed, the following errors are shown when running npm run generate. I noticed the order of attributes in the CSVFileExtractor is also fixed. I am not sure how to fix this, maybe we can spin that out into an extra task.

Error: Parser definition errors detected:
-------------------------------
../..:6 - Ambiguous Alternatives Detected: <3 ,4> in <OR1> inside <BlockType> Rule,
<> may appears as a prefix path in all these alternatives.
See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
For Further details.
-------------------------------
../..:6 - Ambiguous alternatives: <3 ,4> due to common lookahead prefix
in <OR1> inside <BlockType> Rule,
<> may appears as a prefix path in all these alternatives.
See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX
For Further details.
-------------------------------
../..:6 - Ambiguous alternatives: <3 ,4> due to common lookahead prefix
in <OR1> inside <BlockType> Rule,
<> may appears as a prefix path in all these alternatives.
See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX
For Further details.
-------------------------------
../..:6 - Ambiguous alternatives: <3 ,4> due to common lookahead prefix
in <OR1> inside <BlockType> Rule,
<> may appears as a prefix path in all these alternatives.
See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX
For Further details.
-------------------------------
../..:6 - Ambiguous alternatives: <3 ,4> due to common lookahead prefix
in <OR1> inside <BlockType> Rule,
<> may appears as a prefix path in all these alternatives.
See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX
For Further details.
-------------------------------
../..:6 - Ambiguous alternatives: <3 ,4> due to common lookahead prefix
in <OR1> inside <BlockType> Rule,
<> may appears as a prefix path in all these alternatives.
See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX
For Further details.
-------------------------------
../..:6 - Ambiguous alternatives: <3 ,4> due to common lookahead prefix
in <OR1> inside <BlockType> Rule,
<> may appears as a prefix path in all these alternatives.
See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX
For Further details.

Screenshot

Screenshot 2022-12-02 at 20 39 13

rhazn added 4 commits December 2, 2022 20:01
SQLiteLoader can load data into a local SQLite database file.

Currently the table name is called "Todo" and not set by the block due
to errors with the grammar.
Adds a table attribute to SQLiteLoader so that the table name can be
defined.

The ordering of attributes is intentially fixed as introducing unordered
attributes with '&' seems to lead to a lot of COMMON_PREFIX and
AMBIGUOUS_ALTERNATIVES errors with PostgresLoader.
With the addition of surrounding delimiters around column names with
a recent patch, the EMPTY fallback is no longer necessary as empty
column names actually work.
@rhazn rhazn requested a review from felix-oq December 2, 2022 19:43
rhazn added 2 commits December 2, 2022 20:46
Cars example now uses SQLite instead of Postgres. This means it also
does not need to start a local Postgres DB anymore.
@felix-oq
Copy link
Contributor
felix-oq commented Dec 2, 2022

Copy link
Contributor
@felix-oq felix-oq left a comment

Choose a reason for hiding this comment

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

Awesome that we support SQLite as a sink now. This really helps users to get started with less setup. I'm also glad to see that you were able to add the new loader block to the grammar by yourself :)

I left some comments but LGTM otherwise.

An additional comment:
We should add .db and .sqlite files to gitignore, so they are not committed accidentally.

See #61 regarding the problem with the attribute ordering.

@@ -59,7 +59,7 @@ export class PostgresLoaderExecutor extends BlockExecutor<
const columnTypeVisitor = new PostgresColumnTypeVisitor();

const columnPostgresStatements = input.columnNames
.map((columnName) => columnName || 'EMPTYNAME')
.map((columnName) => columnName)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
.map((columnName) => columnName)

Can be omitted as it does not do anything.

@@ -88,7 +88,7 @@ export class PostgresLoaderExecutor extends BlockExecutor<
.join(',');

return `INSERT INTO "${tableName}" (${input.columnNames
.map((columnName) => columnName || 'EMPTYNAME')
.map((columnName) => columnName)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
.map((columnName) => columnName)

Again, can be omitted.

table: "Cars";
file: "./cars.db";
Copy link
Contributor

Choose a reason for hiding this comment

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

You could add a custom validator for checking the file ending and e.g. show a warning if it is not .sqlite or .db.

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 am not actually sure there has to be a specific file extension, I don't know sqlite enough :D. In any case I'll have to leave that as a future exercise for me because it is a new system I have not worked with yet (the custom validations). I'll get to it though.

Copy link
Contributor

Choose a reason for hiding this comment

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

We can also pair program this if you want to :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, good idea. I'll have to keep it in mind for the future though, not sure I can get to it this week. But I'll ping you :).

Comment on lines 35 to 37

TableAttribute returns StringAttribute:
'table' StringAttributeFragment;
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe move this into the blocks folder in a file called shared-attributes.langium? That way attributes.langium file does not contain any block-specific attributes.

@@ -0,0 +1,16 @@
import { DataTypeVisitor } from '@jayvee/language-server';

export class SQLColumnTypeVisitor extends DataTypeVisitor<string> {
Copy link
Contributor

Choose a reason for hiding this comment

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

We could omit the subclasses PostgresColumnTypeVisitor and SQLiteColumnTypeVisitor because they don't add any behavior. Instead we could go with SQLColumnTypeVisitor and add subclasses in the future when required.

Same for SQLValueRepresentationVisitor, PostgresValueRepresentationVisitor and SQLiteValueRepresentationVisitor.

Comment on lines 66 to 102
private buildCreateTableStatement(tableName: string, input: Table): string {
const columnTypeVisitor = new SQLiteColumnTypeVisitor();

const columnStatements = input.columnNames
.map((columnName) => columnName)
.map((columnName) => `"${columnName}"`)
.map((name, index) => {
return `${name} ${(
input.columnTypes[index] as AbstractDataType
).acceptVisitor(columnTypeVisitor)}`;
});

return `CREATE TABLE IF NOT EXISTS "${tableName}" (${columnStatements.join(
',',
)});`;
}

private buildInsertValuesStatement(tableName: string, input: Table): string {
const valueRepresenationVisitor = new SQLiteValueRepresentationVisitor();

const valueRepresentationFormatters = input.columnTypes.map((type) => {
return type?.acceptVisitor(valueRepresenationVisitor);
});

const valuesStatement = input.data
.map((row) => {
return `(${row
.map((value, index) => valueRepresentationFormatters[index]?.(value))
.join(',')})`;
})
.join(',');

return `INSERT INTO "${tableName}" (${input.columnNames
.map((columnName) => columnName)
.map((columnName) => `"${columnName}"`)
.join(',')}) VALUES ${valuesStatement}`;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

All of this is pretty much duplicate code (compared to postgres-loader-executor). Consider a refactoring.

}),
);
} finally {
db && db.close();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
db && db.close();
db?.close();

< 859E /details-collapsible>
@rhazn rhazn merged commit 825e2d4 into main Dec 5, 2022
@rhazn rhazn deleted the sqlite-loader branch December 5, 2022 10:45
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
0