What's new in pgx v5: CollectRows, RowToStructByName, CollectOneRow, RowToStructByPos and ForEachRow
This is the third part of the pgx v5 series. Let’s discuss the new features from the title. CollectRows and RowToStructByName CollectRows allow us to fetch an array of rows and set them into a slice of structs. Further, RowToStructByName is a long awaited feature which allows to store a row into a struct. sqlx module became very popular in Go community exactly for this reason, but pgx now supports something similar. RowToStructByName is a generic function of the func(row CollectableRow) (T, error) and it’s not the only one of this type, there are also RowTo, RowToStructByPos and RowToStructByNameLax. Under the hood, RowToStructByName is using reflection so it may be slightly slower than classic way of scanning the rows, but if you don’t mind this, it is very easy to use. All field names are going to be mapped to lowercased public struct field names and you may also use db struct tags if some field name differs from the struct field name. This explanation may sound difficult, but the following example will actually show that it is actually very easy to use. ...
What's new in pgx v5: QueryRewriter and NamedArgs
In this second part of the pgx v5 series, we are going to discuss the QueryRewriter interface and NamedArgs. Let’s first check out the signature of the Exec method of the pgxpool.Pool struct. 1 2 3 4 5 // Exec acquires a connection from the Pool and executes the given SQL. // SQL can be either a prepared statement name or an SQL string. // Arguments should be referenced positionally from the SQL string as $1, $2, etc. // The acquired connection is returned to the pool when the Exec function returns. func (p *Pool) Exec(ctx context.Context, sql string, arguments ...any) (pgconn.CommandTag, error) According to this, we can execute some SQL query by providing the context, SQL query string and arguments to the Exec. But is this the only option? Let’s look at this example: ...
How to install Docker and kubectl on Ubuntu 22.04 desktop
Since some time apt-key is deprecated and lot of Ubuntu 22.04 based systems throws the following warning: 1 Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details You can easily fix this by properly installing Docker and Kubernetes apt archives public keys: 1 2 3 4 5 6 7 wget -qO - https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor | sudo dd of=/usr/share/keyrings/docker-archive-keyring.gpg echo 'deb [ arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg ] https://download.docker.com/linux/ubuntu jammy stable' | sudo tee /etc/apt/sources.list.d/docker.list wget -qO - https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor | sudo dd of=/usr/share/keyrings/kubernetes-archive-keyring.gpg echo 'deb [ arch=amd64 signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg ] http://apt.kubernetes.io/ kubernetes-xenial main' | sudo tee /etc/apt/sources.list.d/kubernetes.list Take a look at /etc/apt/sources.list.d and find out if there is also an old source definition and if you find it, just delete it, the new one will suffice. You can also find out if there are duplicates if you run sudo apt-get update. Just delete the old version which doesn’t contain signed-by inside. ...
What's new in pgx v5: Introduction
Go has very rich standard library which also contains database/sql module with generic interface over SQL databases. Further, lib/pq PostgreSQL driver is fully compatible with database/sql and provides all basic database operations. However, since this is generic implementation over all supported databases, using it is a trade-off not supporting some PostgreSQL specific features. Fans of PostgreSQL (in further text pg) may want more and here comes pgx in help. pgx is a very rich pg driver supporting LISTEN / NOTIFY, COPY, type mapping between pg and Go, all specific pg types, wire protocol and much more. ...
Check type of generic parameter in Go
Go is over ten years old language but generics (type parameters) are introduced just in the March this year. Hence, still lot of developers avoid using them or have certain problems once decided to give it a try. One of the common problems is how to check the concrete type of a generic parameter, specially of non constrained parameters. So, if you try to do the following, it won’t work: ...
How to write complex HTTP middlewares in Go
Lot of the tutorials on the Web show different ways of writing Go HTTP middlewares, but most of them use functional approach meaning using functions that get dependencies as parameters and return HTTP handler function or handler. There is nothing wrong about this, but it can be quite messy to write a complex middlewares like database based authentication and authorization or simply middlewares which have lot of dependencies. In this article I am going to explain how to use more object oriented way of writing such middlewares. Let’s start with the basic object oriented middleware example: ...
Build Rust container images faster using layer caching
In the previous blog post I described how to define GitHub Actions pipeline to benefit from caching Rust dependencies and container images’ layers. But the final result may also depend on your Dockerfile. Namely, Docker Buildx Action supports BuildKit and buildx and in order to benefit from this, your Dockerfile has to explicitly cache layers. Actually, this is quite easy to achieve, let’s see the example: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # syntax=docker/dockerfile:1.3 FROM rust:1.61.0 AS builder ARG TARGETPLATFORM WORKDIR /root RUN --mount=type=cache,target=/usr/local/cargo/registry,id=${TARGETPLATFORM} \ cargo install cargo-strip COPY . . RUN --mount=type=cache,target=/usr/local/cargo/registry,id=${TARGETPLATFORM} --mount=type=cache,target=/root/target,id=${TARGETPLATFORM} \ cargo build --release && \ cargo strip && \ mv /root/target/release/<your-crate-name> /root FROM gcr.io/distroless/cc-debian11 COPY --from=builder /root/<your-crate-name> / ENTRYPOINT ["./<your-crate-name>"] EXPOSE 3000 The crucial part here is the annotation # syntax=docker/dockerfile:1.4, this will turn on the advanced features. ARG TARGETPLATFORM is optional and will be used just if you have matrix build with different platforms. If you build for single platform, you can remove this line and also ,id=${TARGETPLATFORM} from the remaining lines of the Dockerfile. The next important point is --mount=type=cache,target=/usr/local/cargo/registry. This defines which path should be actually cached as container image layer. Replace <your-crate-name> placeholder with your real crate name and you are ready to go. If you expose your service on a different port than 3000, please modify the final line EXPOSE 3000 to the correct port, or if there are no exposed ports, just delete the line. ...
How I speeded up my Rust builds on GitHub ~30 times
Rust is a great programming language, but it’s compiler is known to be slow. The main reason is that it checks so many things during the compilation in order to provides memory and concurrency safety. Like in many other cases, pipelines may be speeded up by caching, but it is very important to set the caching properly, otherwise it won’t help. Besides compiling your code may be slow, you also may want to use some cargo tools to lint and check your code and this will require to be compiled as well, if you don’t want to download binaries. Some popular tools are: ...
How to fix possible missing firmware warning during kernel update on Linux Mint
If you are running default kernel with your Ubuntu or Linux Mint installation, you probably won’t face this problem during kernel updates because all packages are coming from the official distribution sources. However, if you like to run the newest Linux kernels and update them using mainline kernel installer, you may get warning possible missing firmware during the installation. Few days ago I got this warning on my Linux Mint 20.3 Una while installing kernel 5.17.7. In most of the cases this warning won’t affect normal functionality of your Linux machine, but if you hate warnings, like I do, here is what you can do. I guess you regularly update your apt packages, but still new kernels may complain, which further means you may need even newer package. In my case I had to install linux-firmware package from Jammy Jellyfish , the newest LTS Ubuntu, Ubuntu 22.04 LTS. ...
Custom Go HTTP handlers using generics
Few days ago Go 1.18beta1 was released and with it the first official generics support. I was embarrassed with standard Go’s HTTP handler functions for quite a while. If you are not familiar with Go, you probably wonder why, but if you are familiar, I believe you know. For example, implementing a RESTful API using idiomatic Go requires lot of code repetition in order to JSON decode request bodies and JSON encode response bodies. This problem was possible to solve in some way but never in such elegant way like using generics. ...