Skip to content

Commit

Permalink
database table sql queries
Browse files Browse the repository at this point in the history
  • Loading branch information
juancastillo0 committed Dec 6, 2023
1 parent 36d2ae7 commit 3fe6648
Show file tree
Hide file tree
Showing 4 changed files with 2,527 additions and 0 deletions.
6 changes: 6 additions & 0 deletions backend_server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ This sample code handles HTTP GET requests to `/` and `/echo/<message>`

# Running the sample

## Code Generation

```
fvm dart pub run build_runner watch --delete-conflicting-outputs
```

## Running with the Dart SDK

You can run the example with the [Dart SDK](https://dart.dev/get-dart)
Expand Down
187 changes: 187 additions & 0 deletions backend_server/lib/database.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import 'dart:convert';

import 'package:typesql/sqlite.dart';
import 'package:typesql/typesql.dart';

import 'table_queries.sql.dart';

Future<void> main() async {
return testDatabase();
}

void _defaultExpect(Object? a, Object? b) {
if (a != b) throw Exception('$a != $b');
}

Future<void> testDatabase({
void Function(Object? a, Object? b) expect = _defaultExpect,
}) async {
final sqlite = await loadSqlite();
final db = sqlite.openInMemory();
final executor = SqliteExecutor(db);
final queries = TableQueriesQueries(executor);

await queries.defineDatabaseObjects();
// await example.createTableUsers();
final execution = await queries.insertUsers1(InsertUsers1Args(c: 'name'));
expect(execution.updaterRows, 2);
expect(execution.lastInsertId, '2');

final users = await queries.querySelectUsers1();
expect(users.length, 2);
expect(users[0], QuerySelectUsers1(usersId: 1, usersName: 'name1'));
expect(users[1], QuerySelectUsers1(usersId: 2, usersName: 'name'));

{
final toInsert = [
UsersInsert(id: 3, name: 'name3'),
UsersInsert(id: 4, name: 'name4'),
];
final usersQueries = queries.usersController;
final inserted = await usersQueries.insertManyReturning(toInsert);
expect(jsonEncode(toInsert), jsonEncode(inserted));

final deleted = await usersQueries.deleteManyReturning([UsersKeyId(id: 3)]);
expect(jsonEncode([toInsert.first]), jsonEncode(deleted));

final updated3 = await usersQueries.updateReturning(
UsersKeyId(id: 3),
UsersUpdate(name: 'nameUpdated3'),
);
expect(updated3, null);

final updated4 = await usersQueries.updateReturning(
UsersKeyId(id: 4),
UsersUpdate(name: 'nameUpdated4'),
);
expect(updated4, Users(id: 4, name: 'nameUpdated4'));

final selected4 = await usersQueries.selectUnique(UsersKeyId(id: 4));
expect(selected4, updated4);
}

{
final toInsert = [
PollInsert(id: 3, userId: 4, title: 'title', body: 'body'),
PollInsert(
id: 4,
userId: 4,
title: 'title4',
body: 'body4',
subtitle: 'subtitle4',
createdAt: DateTime(2024),
),
];
final pollQueries = queries.pollController;
final inserted = await pollQueries.insertManyReturning(toInsert);
expect(
jsonEncode([
PollInsert(
id: 3,
userId: 4,
title: 'title',
body: 'body',
createdAt: inserted.first.createdAt,
),
toInsert.last,
]),
jsonEncode(inserted),
);

final deleted = await pollQueries.deleteManyReturning([PollKeyId(id: 3)]);
expect(jsonEncode([inserted.first]), jsonEncode(deleted));

final updated3 = await pollQueries.updateReturning(
PollKeyId(id: 3),
PollUpdate(subtitle: Some('subtitleUpdated')),
);
expect(updated3, null);

final updated4 = await pollQueries.updateReturning(
PollKeyId(id: 4),
PollUpdate(subtitle: Some('subtitleUpdated')),
);
expect(
updated4,
Poll(
id: 4,
userId: 4,
title: 'title4',
body: 'body4',
subtitle: 'subtitleUpdated',
createdAt: DateTime(2024),
),
);

final selected4 = await pollQueries.selectUnique(PollKeyId(id: 4));
expect(selected4, updated4);
}

// final values =
// await example.typedExecutor.selectMany(FilterEq(UsersUpdate()));

// final d = await example.typedExecutor.selectUnique(UsersKeyId(id: 3));
}

class SqliteExecutor extends SqlExecutor {
final CommonDatabase db;

SqliteExecutor(this.db);

@override
SqlDialect get dialect => SqlDialect.sqlite;

@override
Future<T?> transaction<T>(Future<T> Function() transact) async {
bool started = false;
try {
db.execute('START TRANSACTION');
started = true;
final result = await transact();
db.execute('COMMIT');
return result;
} catch (e) {
if (started) {
try {
db.execute('ROLLBACK');
} catch (_) {}
}
return null;
}
}

@override
Future<SqlExecution> execute(String sql, [List<Object?>? params]) async {
db.execute(sql, params ?? const []);
return SqlExecution(
lastInsertId: db.lastInsertRowId.toString(),
updaterRows: db.updatedRows,
);
}

@override
Future<List<List<Object?>>> query(String sql, [List<Object?>? params]) {
final rows = db.select(sql, params ?? const []);
return Future.value(rows.rows);
}

@override
Future<SqlPreparedStatement> prepare(String sql) async {
final statement = db.prepare(sql, persistent: true);
return SqlPreparedStatement.value(
sql,
statement.parameterCount,
dispose: statement.dispose,
execute: ([p]) async {
statement.execute(p ?? const []);
return SqlExecution(
lastInsertId: db.lastInsertRowId.toString(),
updaterRows: db.updatedRows,
);
},
select: ([p]) async {
return statement.select(p ?? const []).rows;
},
);
}
}
132 changes: 132 additions & 0 deletions backend_server/lib/table_queries.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
--
CREATE TABLE users (id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL);
--
SELECT *
FROM users;
--
SELECT *
FROM users
WHERE users.id >= :minId;
--
INSERT INTO users(id, name)
VALUES (1, 'name1'),
(2, :c);
-- {"name":"updateUserName"}
UPDATE user
SET name = :name
WHERE :id = id
RETURNING *;
-- {"name":"deleteUsersById"}
DELETE FROM user
WHERE id IN (:ids);
--
CREATE TABLE poll (
id INTEGER NOT NULL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id),
title TEXT NOT NULL,
subtitle TEXT NULL,
body TEXT NOT NULL,
poll_kind VARCHAR(512) NULL,
form_json_schema JSON NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
--
CREATE TABLE poll_option (
id INTEGER NOT NULL PRIMARY KEY,
poll_id INTEGER NOT NULL REFERENCES poll(id),
priority INT default 0,
description TEXT NULL,
url TEXT NULL,
from_json_schema JSON NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- --
-- CREATE TABLE form (
-- id INTEGER PRIMARY KEY,
-- json_schema JSON NOT NULL,
-- );
--
CREATE TABLE poll_vote (
poll_id INTEGER NOT NULL REFERENCES poll(id),
user_id INTEGER NOT NULL REFERENCES users(id),
form_response JSON NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(poll_id, user_id)
);
--
CREATE TABLE poll_option_vote (
poll_option_id INTEGER NOT NULL REFERENCES poll_option(id),
user_id INTEGER NOT NULL REFERENCES users(id),
value INTEGER NOT NULL,
form_response JSON NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(poll_option_id, user_id)
);
--
SELECT users.id,
users.name user_name,
po.id,
poll.*
FROM user
INNER JOIN poll ON poll.user_id = users.id
LEFT JOIN poll_option po ON po.poll_id = poll.id
WHERE users.id = 1
and poll.subtitle is not null;
-- {"name":"userWithPosts"}
SELECT users.id,
users.name user_name,
json_group_array(
json_object(
'id',
poll.id,
'user_id',
poll.user_id,
'title',
poll.title,
'subtitle',
poll.subtitle,
'body',
poll.body,
'created_at',
poll.created_at,
'options',
json_array(po.id)
)
) poll
FROM user
INNER JOIN poll ON poll.user_id = users.id
LEFT JOIN poll_option po ON po.poll_id = poll.id
WHERE poll.subtitle is not null
GROUP BY users.id;
-- {"name":"userWithPostsJSON"}
SELECT users.id,
users.name user_name,
json_group_array(p.json_value) poll
FROM user
INNER JOIN poll_with_options_json p ON p.user_id = users.id
GROUP BY users.id;
--
CREATE VIEW poll_with_options_json AS
SELECT poll.id,
poll.user_id,
json_object(
'id',
poll.id,
'user_id',
poll.user_id,
'title',
poll.title,
'subtitle',
poll.subtitle,
'body',
poll.body,
'created_at',
poll.created_at,
'options',
json_group_array(po.id)
) json_value
FROM poll
LEFT JOIN poll_option po ON po.poll_id = poll.id
GROUP BY poll.id;
--
DELETE FROM users WHERE (id = ?) RETURNING id,name;
Loading

0 comments on commit 3fe6648

Please sign in to comment.