“Custom column types” in SQLDelight: Android

Image for post
Image for post
Photo by Kelly Sikkema on Unsplash

SQLDelight is a multi-platform library to generate typesafe Kotlin APIs from your SQL statements. It has its special schema file (.sq) where we write the supporting SQL statements which are compile-time safe & its integration with powerful IDE like Android Studio you will get all the benefits like autocomplete, refactoring, etc.

One of my favorite thing about SQLDelight is its support for multiplatform. Anyway, this is not a typical guide on how to use the library their official docs are way better in terms of it.

What is the purpose of this article?

Well, I am going to talk about a specific thing that is types. As we know custom column types for SQLite is always a crucial thing because they are not built-in so developers tend to find a technique to map their custom object type to mostly TEXT which is something SQL understands.

In SQLDelight, this same thing can be achieved by writing a ColumnAdapter. A typical example of an adapter is given below.

You can then define the logic that goes into encode & decode function respectively. For more complex data it seems best to serialize them to JSON using one of the famous libraries like Gson, Moshi, kotlinx-serialization.

I prefer kotlinx-serialization because it understands the Kotlin structure & of course the multiplatform support. There is actually a great talk by Leonid Startsev about its latest 1.0 release on JetBrainsTV.

Okay now what? Halfway through the article still I haven’t clear about the purpose of this guide!

Let’s understand the problem

Consider the following schema & their respective data classes.

Kotlin types which are used in the schema

As you can see from the schema file (first snippet) we will need a lot of adapters to map those data.

As expected we need 3 of them & we need to write them manually (as shown in the intro part). This seems like a lot of repetitive code.

Can we optimize this? Luckily we can, there is a library that can auto-generate this boilerplate code for us.

Automating the work

  • Add the following code to your module’s build.gradle file.
  • Now my favorite part, writing the code that will generate all the adapters for us.
  • By annotating an interface with @AutoGenerateSQLDelightAdapters you can create functions with the return type ColumnAdapter<*,String> to create the resulting adapters (as shown above).
  • Now compile the project. This will create all the required adapters in the class SQLDelightAdaptersImpl.java which we can then use as shown below (for more information refer docs).
  • That’s it, instead of writing 3 separate adapters all we have to do is create an interface with supporting functions.

We just saved a lot of boilerplate code! Cheers :)

Conclusion

The library comes with lint-check which will highlight some errors that result in failure compilation.

Image for post
Image for post
Lint checks for detecting “wrong return type”

If you want to know more about the library check the Github page at the end of the post. The library also supports more such annotation processing to eliminate boilerplate codes.

I am actively working on it to add more like such. Anyway, if you have any idea let me know.

Scheduling my day tasks with "WorkManager"

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store