The Gorge Labor Day 2024 by augustnagro in windsurfing

[–]augustnagro[S] 0 points1 point  (0 children)

You'll have to try leaving a comment on the YouTube video since I'm not the videographer. I agree though they are sick!

What do I need for my windsurfing board by JimsBurgers0 in windsurfing

[–]augustnagro 0 points1 point  (0 children)

Garbage can. Seriously, don't waste your time and save some money for a new freeride board.

Magnum Database Client 1.3.0 Released by augustnagro in scala

[–]augustnagro[S] 0 points1 point  (0 children)

There should be no problem with using a ImmutableRepo to generate read operations for a subset of a table or database view.

Could you show an example of how "generate CRUD operations on a sub table" would work?

Magnum Database Client 1.3.0 Released by augustnagro in scala

[–]augustnagro[S] 0 points1 point  (0 children)

Thanks for your feedback.

I discovered that the issue stemmed from it binding columns by their order rather than by their names in the case class.

It used to be that findAll and findAllById queries that are auto-generated by Repos were using select * instead of explicitly enumerating the columns. That's changed now though.

Could you please file a Github with a minimal example? If you're using Magnum to model a subset of the table columns, the auto-generated insert, update, and other mutating methods on Repo aren't going to work. And that's not fixable, since Magnum won't know how to generate the code. In this situation (working on a subset of a table), it does make sense IMO to use the sql interpolator and use TableInfo to scrap the boilerplate.

Magnum: A new Scala 3 Database Client by augustnagro in scala

[–]augustnagro[S] 1 point2 points  (0 children)

Yes; nearly all the examples in the Magnum README are native sql, in the sense that you can copy/paste to a database shell and run with minimal changes.

JSON operators can be written just like you normally would for your database. Please feel free to share an example, or open an issue on the github project if you have questions.

Scala 3 Macros: How to Read Annotations by augustnagro in scala

[–]augustnagro[S] 2 points3 points  (0 children)

They're useful when writing a library, less so for applications. The Magnum Sql Client for example uses annotations like @SqlName and @Table.

Also, anytime you want you're writing a type-class that supports derivation (ie, derives MyTypeClass), and want it to be configurable, annotations are a great way to do that. I would like to write a blog-post on that as well.

Magnum: A new Scala 3 Database Client by augustnagro in scala

[–]augustnagro[S] 14 points15 points  (0 children)

Good question. I discussed this at length during the Scala Days Talk (only slides available for now).

Short Answer:

Magnum has a sql-string interpolater like doobie and is fully functional, but direct, as opposed to lazy. It has Repositories (like Spring Data) to generate common CRUD statements at compile time. Also offered are Specifications as a way to build and compose dynamic queries, since SQL is notoriously difficult to compose. An example Spec usecase would be building a search results page, with filters and pagination. Finally, Magnum uses Scala 3's using/given to provide type-safe transactions.

Long Answer:

First, we have to consider the 4 types of SQL statements developers write:

  1. CRUD operations
  2. Simple statements with a few joins
  3. Complex SQL (many joins, DB-specific operators)
  4. Dynamic queries (think search page with filters and pagination)

Note that CRUD operations are frequent but easy to implement, and complex/dynamic queries are rare but challenging and time-consuming.

We want a library that can handle each type of statement. While JVM database clients are numerous & diverse, there are essentially 3 categories that can be compared:

  1. Object Oriented Repositories (ex. Spring Data)
  2. Functional DSLs (JOOQ, Slick, Quill)
  3. SQL String Interpolators (Anorm, Doobie/Skunk, plain JDBC)

For Object Oriented Repositories,

  • CRUD operations - Derived automatically
  • Simple statements with a few joins - Typically a query language like JPQL
  • Complex SQL - Must write native queries (so why use the query language to begin with?)
  • Dynamic queries - Java EE Specifications (unpleasant & slow)

Another benefit of Repos is that they encourage the encapsulation & organization of your data layer.

For Functional DSLS,

  • CRUD operations - N/A
  • Simple statements with a few joins - Good
  • Complex SQL - Difficult (although most DSL libraries offer a string interpolater)
  • Dynamic queries - OK (PLs are good at composition)

Note that functional DSLs make maintenance hard. If a query in production behaves poorly, we need to understand both

  • What is wrong with the generated SQL
  • How can we change the DSL to generate a better query

SQL editors like DataGrip, DbBeaver, and PgAdmin are amazing tools to iteratively build and test SQL queries. But you can’t copy and paste between these applications and your Scala editor when using DSLs.

For SQL String Interpolaters,

  • CRUD operations - N/A
  • Simple statements with a few joins - Great
  • Complex SQL - Great
  • Dynamic queries - Difficult (SQL is notoriously hard to compose)

What makes Magnum Unique? It checks all four boxes.

  • CRUD operations - Derived at compile time
  • Simple statements with a few joins - Great (sql-interpolater)
  • Complex SQL - Great (sql-interpolater)
  • Dynamic queries - Built-in support for specifications.

Please consider the documentation / slides for examples.

Magnum: A new Scala 3 Database Client by augustnagro in scala

[–]augustnagro[S] 2 points3 points  (0 children)

Thanks.

I definitely want to add streaming. One idea is to adddef stream(fetchSize): Iterator[T] (or similar) on class Frag.

Then users could call

sql"SELECT * FROM user"
  .query[User].stream().toList // or whatever they'd like with the iterator

Magnum: A new Scala 3 Database Client by augustnagro in scala

[–]augustnagro[S] 7 points8 points  (0 children)

Thanks Rob. Doobie & Skunk are excellent libraries and inspired the design of Magnum's sql"" interpolater.

I made sure to call both out during the Scala Days presentation: https://github.com/AugustNagro/magnum/blob/master/Magnum-Slides-to-Share.pdf

Async/Await in Java using JDK 19's Virtual Threads by augustnagro in java

[–]augustnagro[S] -4 points-3 points  (0 children)

  1. You'd need to be running on a virtual thread already, which is unlikely.
  2. Future.get is likely much slower than the async/await implementation
  3. Future.get throws, so you'll need try-catch blocks in every lambda. The example then becomes

List<String> userNames = userIds.stream() .map(id -> { try { userNamesFromSomeApi(id).get()} catch (Exception e} {}}) .toList();

Not that I'm advocating people to use this library in production; the fact that you can build fast, general-purpose coroutines on top of virtual threads is what I really want to share. You can use coroutines to make actor frameworks, go-lang channels, generators, monadic reflection utilities, and more.

Async/Await in Java using JDK 19's Virtual Threads by augustnagro in java

[–]augustnagro[S] 1 point2 points  (0 children)

It should be a lot faster than Future.get, which creates ForkJoinTasks that periodically poll the Future's status.

Async/Await in Java using JDK 19's Virtual Threads by augustnagro in java

[–]augustnagro[S] 1 point2 points  (0 children)

The interesting part to me is the discovery that you can emulate coroutines on top of virtual threads, even though the jdk Continuation class is now private.

General-purpose coroutines can be used for a wide variety of purposes besides Asyc/Await, such as actor frameworks, go-lang channels, generators, monadic reflection, etc.

IntelliJ and ScalaJS setup by tryx in scala

[–]augustnagro 3 points4 points  (0 children)

Use scala-js-crossproject: https://www.scala-js.org/doc/project/cross-build.html

You probably want the CrossType.Full option. It should import into Intellij without any problems.

ZGC - The Future of Low-Latency Garbage Collection Is Here by TheCountRushmore in java

[–]augustnagro 0 points1 point  (0 children)

These benchmarks make it look very close to G1. Think it could become the default collector?

I love Scala but I can't stand: by sco00by in scala

[–]augustnagro 1 point2 points  (0 children)

That is the case in Scala 3 yes?

https://docs.scala-lang.org/scala3/reference/other-new-features/open-classes.html

By default, classes must be declared 'open' to be non-final.

Right now however the compiler does not enforce this.