Closed timvandam closed 10 months ago
I'd love to see support for log tables & row locking.
A LogPlugin to log table changes (insert, update, delete) has been added in https://github.com/deepkit/deepkit-framework/commit/d306ac5c88f74ee6436f6f69bf29c42e766cee7b
To have a better overview of this issue:
[Open, unlikely] Breaking up large queries
[Open] Adding aggregate columns to SELECT inside of a join (useJoin/useInnerJoin)
[Done] Locking reads
[Done] A way to find one entity (instead of one row)
[Done] Log Tables
I think that we should not anything to the query API that SQL is capable of, that would be way too much. We can surely add here and there new features to make slightly more complex query working, but I also thought about adding better raw SQL query supported. Maybe something like
const rows = await database.sqlQuery<MyInterface[]>(`SELECT * FROM my_table`)
so that the result is automatically deserialised to MyInterface, even if MyInterface
is not even an entity class. This would allow having type safety with arbitrary complex SQL queries.
this is implemented, see https://deepkit.io/documentation/orm/raw-access
Some things are hard to do in the orm
1. Breaking up large queries In raw SQL, I would use
WITH
to break up large queries. I don't necessarily think that a way to be able to useWITH
is crucial. Instead, being able to re-use queries would allow for identical functionality (as far as I know, except forWITH RECURSIVE
)A practical example where we want to find employees that get paid above average, but perform below average:
In SQL you could do this:
Proposed solution
2. Adding aggregate columns to SELECT inside of a join (
useJoin
/useInnerJoin
) See the 2nd query (averageJobPerformance
) of the previous example. ThewithAverage('performance', 'performance')
line does not actually add aAVG(performance) AS performance
to the query yet3. Locking reads E.g.
SELECT FOR UPDATE
andSELECT FOR SHARE
in postgres, mysql4. Create queries on subqueries Take the
WITH
query from before, say we very often use the table resulting from theaverage_job_salary
query. In the database we could create a view to make it reuseable.In code, almost the same functionality can be achieved by allowing queries to created on subqueries
Which would result in the query:
This is of course a very simple example where you might as well just have used a query lift, but for more complex subqueries which you often use as if they are entities I think this would be valuable
5. A way to find one entity (instead of one row) Currently,
findOne
will find at most one row. This is troublesome in situation where you want to load one instance of some entity, and load all its references.E.g:
Now observe how
findOne
worksSince at most one row is fetched, at most one joined row is returned. This makes it troublesome to get at most one entity, and all entities related to that entity.
A new
findOneEntity
method that limits the amount of instances of the queried entity to 1, instead of limiting the amount of rows would resolve this:6. Log Tables A log table is a table that tracks the changes happening to some data. Each row will descibe some action: eg an insert/delete/update
7. Enums in database Currently enums only live in the code, not in the database. It could be nice to create these enums in the database too: https://www.postgresql.org/docs/9.1/datatype-enum.html
I will add more things to this issue if I think of more things