Skip to content

Commit

Permalink
feature: post_avif_img shortcode
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandrehtrb committed Sep 6, 2024
1 parent 6e1436b commit 4346db1
Show file tree
Hide file tree
Showing 18 changed files with 50 additions and 81 deletions.
9 changes: 7 additions & 2 deletions .eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,16 @@ module.exports = function(eleventyConfig) {
});
eleventyConfig.setLibrary('md', md);

// asset_img shortcode
eleventyConfig.addLiquidShortcode('asset_img', (filename, alt) => {
// post_img shortcode
eleventyConfig.addLiquidShortcode('post_img', (filename, alt) => {
return `<img class="my-4" src="/assets/img/posts/${filename}" alt="${alt}" />`
})

// post_avif_img shortcode
eleventyConfig.addLiquidShortcode('post_avif_img', (avif_filename, fallback_filename, alt) => {
return `<picture class="my-4"><source type="image/avif" srcset="/assets/img/posts/${avif_filename}" alt="${alt}"/><img src="/assets/img/posts/${fallback_filename}" alt="${alt}"/></picture>`
})

eleventyConfig.addTransform("htmlmin", do_minifyhtml);

return {
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ A blog that still runs without javascript. Hence, no bundlers.

+ Shortcode to handle images
- Add image under `src/assets/img/posts` and use the asset_img short code
- `{% asset_img 'filename' 'alt_text' %}` eg. `{% asset_img 'mailbox.jpg' 'mailbox' %}`
- `{% post_img 'filename' 'alt_text' %}` eg. `{% post_img 'mailbox.jpg' 'mailbox' %}`

- Draft posts using the `published` frontmatter

Expand Down
14 changes: 4 additions & 10 deletions src/posts/2024/01/formatos-de-imagem-modernos-jxl-avif.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ A visualização de imagens é fundamental em vários setores, como artes plást

Em uma tela de computador, uma imagem é representada por milhares de *pixels* (**pic**ture **el**ement), cada *pixel* correspondendo a uma cor e sua intensidade. Considere uma imagem de tamanho 1.024px x 768px = 786.432 *pixels*; se cada pixel for RGBA e tiver 4 *bytes*, 1 para vermelho, 1 para verde, 1 para azul e 1 para transparência, essa imagem terá um tamanho de 3,1MB, o que é bastante alto. Contudo, escolhendo técnicas de compressão e um formato de arquivo adequados, podemos ter essa imagem com a mesma qualidade e ocupando muito menos espaço em memória.

{% asset_img '2024_01_hires_images_examples.jpg' 'Exemplos de imagens de alta resolução' %}
{% post_img '2024_01_hires_images_examples.jpg' 'Exemplos de imagens de alta resolução' %}

## Novos formatos

Expand Down Expand Up @@ -62,14 +62,11 @@ Exemplos:

A imagem original abaixo é um JPG de dimensões 8192x5464, com tamanho de 11MB. Em formato JXL (q=90), o tamanho ficou em 7,3MB. Em AVIF (q=90), ficou em 8,3MB.

{% asset_img '2024_01_subway_escalators.jpg' 'Escadas-rolantes de uma estação de metrô' %}
{% post_img '2024_01_subway_escalators.jpg' 'Escadas-rolantes de uma estação de metrô' %}

O GIF original abaixo tem tamanho de 3,1MB. Em formato JXL (q=90), o tamanho ficou em 2,5MB. Em AVIF (q=90), ficou em 79kB. Impressionante!

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_01_emilia_clarke.avif" alt="Emilia Clarke" />
<img src="/assets/img/posts/2024_01_emilia_clarke.gif" alt="Emilia Clarke" />
</picture>
{% post_avif_img '2024_01_emilia_clarke.avif' '2024_01_emilia_clarke.gif' 'Emilia Clarke' %}

Este repositório no GitHub ([link](https://github.com/alexandrehtrb/jxl-avif-simple-benchmark)) executa testes para comparar as velocidades e taxas de compressão do JXL e do AVIF. A comparação não é qualitativa, nem científica. Como imagens de entrada, estão:

Expand Down Expand Up @@ -136,10 +133,7 @@ Se você quer usar esses novos formatos, mas quer garantir compatibilidade com n

Se o navegador tiver suporte, tentará primeiro carregar a imagem em formato AVIF; senão, carregará a imagem em formato GIF. A animação abaixo está dentro de uma tag `<picture>` - você pode conferir o formato ao salvar o arquivo.

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_01_curtains.avif" alt="Cortinas balançando com o vento" />
<img src="/assets/img/posts/2024_01_curtains.gif" alt="Cortinas balançando com o vento" />
</picture>
{% post_avif_img '2024_01_curtains.avif' '2024_01_curtains.gif' 'Cortinas balançando com o vento' %}

Devido ao tamanho menor das imagens, as páginas carregam mais rápido.

Expand Down
8 changes: 4 additions & 4 deletions src/posts/2024/01/links-simbolicos-em-multi-repos.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ C:\MeusProjetos\

No VS Code, *symlinks* têm uma setinha ao lado direito do nome do arquivo.

{% asset_img '2024_01_vscode_symlinks.png' 'Symlinks no VS Code' %}
{% post_img '2024_01_vscode_symlinks.png' 'Symlinks no VS Code' %}

O comando para criar links simbólicos no Linux e no Mac OSX é:

Expand Down Expand Up @@ -157,11 +157,11 @@ O Git suporta ter arquivos *symlink* commitados nos repositórios.

No GitHub, eles aparecem com uma setinha e nome em azul.

{% asset_img '2024_01_github_symlink_repo.png' 'Symlinks repo' %}
{% post_img '2024_01_github_symlink_repo.png' 'Symlinks repo' %}

Na navegação online e em pull requests, o conteúdo do arquivo aparece como um texto do caminho, absoluto ou relativo.

{% asset_img '2024_01_github_symlink_file.png' 'Symlinks repo file' %}
{% post_img '2024_01_github_symlink_file.png' 'Symlinks repo file' %}

## Quando devo usar essa abordagem?

Expand All @@ -177,7 +177,7 @@ Diretórios simbólicos podem ser uma boa alternativa a submódulos do Git.

1) Se você estiver usando Windows, é necessário habilitar links simbólicos durante a instalação do Git:

{% asset_img '2024_01_git_windows_setup_symlinks.png' 'Git for Windows setup Symlinks' %}
{% post_img '2024_01_git_windows_setup_symlinks.png' 'Git for Windows setup Symlinks' %}

2) Alguns sistemas de arquivos não suportam links simbólicos, por exemplo, FAT32 e exFAT. Esses sistemas de arquivos são comuns em pen-drives e cartões SD.

Expand Down
14 changes: 4 additions & 10 deletions src/posts/2024/01/modern-image-formats-jxl-and-avif.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The visualization of images is fundamental in many areas, such as arts, professi

On a computer screen, an image is represented by thousands of *pixels* (**pic**ture **el**ement), each *pixel* corresponding to a colour and its intensity. Consider an image of 1,024px x 768px = 768,432 *pixels*; if each pixel is RGBA and has 4 *bytes*, 1 for red, 1 for green, 1 for blue and 1 for transparency, this image will have a size of 3.1MB, which is quite large. However, by choosing proper compression techniques and file formats, we can have this image with the same quality and with a much lower file size.

{% asset_img '2024_01_hires_images_examples.jpg' 'Examples of high-resolution images' %}
{% post_img '2024_01_hires_images_examples.jpg' 'Examples of high-resolution images' %}

## Newer formats

Expand Down Expand Up @@ -62,14 +62,11 @@ Examples:

The original image below is a JPEG of 8192x5464, file size 11MB. In JXL format (q=90), the size is 7.3MB. In AVIF (q=90), is 8.3MB.

{% asset_img '2024_01_subway_escalators.jpg' 'Escalators in a subway station' %}
{% post_img '2024_01_subway_escalators.jpg' 'Escalators in a subway station' %}

The original GIF below has a file size of 3.1MB. In JXL format (q=90), the size is 2.5MB. In AVIF (q=90), is 79kB. Impressive!

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_01_emilia_clarke.avif" alt="Emilia Clarke" />
<img src="/assets/img/posts/2024_01_emilia_clarke.gif" alt="Emilia Clarke" />
</picture>
{% post_avif_img '2024_01_emilia_clarke.avif' '2024_01_emilia_clarke.gif' 'Emilia Clarke' %}

This [GitHub repo](https://github.com/alexandrehtrb/jxl-avif-simple-benchmark) executes tests to compare compression rates and speeds of JXL and AVIF. The comparison is not qualitative, nor scientific. The input images include:

Expand Down Expand Up @@ -136,10 +133,7 @@ If you want to use these new formats, but also want to guarantee compatibility w

If the browser supports, it will first try to load the picture in AVIF format; else, a GIF will be loaded. The animation below is inside a `<picture>` tag - you can verify which format is it by saving the picture.

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_01_curtains.avif" alt="Curtains moving with the wind" />
<img src="/assets/img/posts/2024_01_curtains.gif" alt="Curtains moving with the wind" />
</picture>
{% post_avif_img '2024_01_curtains.avif' '2024_01_curtains.gif' 'Curtains moving with the wind' %}

Due to the reduced file size of the images, the web pages will load faster.

Expand Down
8 changes: 4 additions & 4 deletions src/posts/2024/01/symlinks-for-multi-repos.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ C:\MyProjects\

On VS Code, symlinks have an arrow icon to the right of the file name.

{% asset_img '2024_01_vscode_symlinks.png' 'Symlinks on VS Code' %}
{% post_img '2024_01_vscode_symlinks.png' 'Symlinks on VS Code' %}

The command to create symlinks on Linux and Mac OSX is:

Expand Down Expand Up @@ -157,11 +157,11 @@ Git supports symlink files committed in repositories.

On GitHub, they appear with an arrow and name coloured in blue.

{% asset_img '2024_01_github_symlink_repo.png' 'Symlinks repo' %}
{% post_img '2024_01_github_symlink_repo.png' 'Symlinks repo' %}

On online navigation and in pull requests, the file content appears as the symlink's path, either absolute or relative.

{% asset_img '2024_01_github_symlink_file.png' 'Symlinks repo file' %}
{% post_img '2024_01_github_symlink_file.png' 'Symlinks repo file' %}

## When should I use this approach?

Expand All @@ -177,7 +177,7 @@ Symbolic directories can be a good alternative to Git submodules, in some cases.

1) If you are using Windows, you need to enable symbolic links during the Git installation:

{% asset_img '2024_01_git_windows_setup_symlinks.png' 'Git for Windows setup Symlinks' %}
{% post_img '2024_01_git_windows_setup_symlinks.png' 'Git for Windows setup Symlinks' %}

2) Some file systems do not support symlinks, such as FAT32 and exFAT. These two are commonly found in pen-drives and SD cards.

Expand Down
8 changes: 4 additions & 4 deletions src/posts/2024/03/http2-and-http3-explained.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ In the beginning of the 1990s, Tim Berners-Lee and his team at [CERN](https://ho

HTTP reused for data transport the existing TCP/IP protocols, with HTTP message bytes residing in the [application layer](https://en.wikipedia.org/wiki/Application_layer), light blue in the image below.

{% asset_img '2024_03_osi_model_tcp_ip.png' 'OSI model' %}
{% post_img '2024_03_osi_model_tcp_ip.png' 'OSI model' %}

## HTTP/0.9

Expand Down Expand Up @@ -103,7 +103,7 @@ Expires: 0
{"name":"Orange","id":2,"family":"Rutaceae","order":"Sapindales","genus":"Citrus","nutritions":{"calories":43,"fat":0.2,"sugar":8.2,"carbohydrates":8.3,"protein":1.0}}
```

{% asset_img '2024_03_http1_tcp_packets.png' 'HTTP1 in TCP packets' %}
{% post_img '2024_03_http1_tcp_packets.png' 'HTTP1 in TCP packets' %}

## HTTP/2

Expand Down Expand Up @@ -140,7 +140,7 @@ sequenceDiagram

The image below shows how frames go inside a TCP packet. Stream 1 carries a HTTP response for a JavaScript file and stream 2 carries a HTTP response for a CSS file.

{% asset_img '2024_03_http2_tcp_packets.png' 'HTTP2 frames in TCP packets' %}
{% post_img '2024_03_http2_tcp_packets.png' 'HTTP2 frames in TCP packets' %}

## HTTP/3

Expand Down Expand Up @@ -191,7 +191,7 @@ sequenceDiagram
end
```

{% asset_img '2024_03_http3_quic_packets.png' 'HTTP3 QUIC packets' %}
{% post_img '2024_03_http3_quic_packets.png' 'HTTP3 QUIC packets' %}

The head-of-line blocking related to TLS (SSL) happens on TCP because the cryptography is usually applied over the entire message content, meaning that all data (all packets) needs to be received for the decryption to happen. With QUIC, the cryptography is individual for each QUIC packet, that is decrypted on arrival, without having to receive all packets beforehand.

Expand Down
8 changes: 4 additions & 4 deletions src/posts/2024/03/http2-e-http3-explicados.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ No início da década de 1990, Tim Berners-Lee e sua equipe no [CERN](https://ho

O HTTP, em questão, aproveitou os protocolos TCP/IP já existentes como meio de transporte de dados. Os bytes de uma mensagem HTTP ficam na [camada de aplicação](https://pt.wikipedia.org/wiki/Camada_de_aplica%C3%A7%C3%A3o), em azul claro na imagem abaixo.

{% asset_img '2024_03_osi_model_tcp_ip.png' 'Modelo OSI' %}
{% post_img '2024_03_osi_model_tcp_ip.png' 'Modelo OSI' %}

## HTTP/0.9

Expand Down Expand Up @@ -103,7 +103,7 @@ Expires: 0
{"name":"Orange","id":2,"family":"Rutaceae","order":"Sapindales","genus":"Citrus","nutritions":{"calories":43,"fat":0.2,"sugar":8.2,"carbohydrates":8.3,"protein":1.0}}
```

{% asset_img '2024_03_http1_tcp_packets.png' 'HTTP1 em pacotes TCP' %}
{% post_img '2024_03_http1_tcp_packets.png' 'HTTP1 em pacotes TCP' %}

## HTTP/2

Expand Down Expand Up @@ -140,7 +140,7 @@ sequenceDiagram

A imagem abaixo mostra como os *frames* entram em pacotes TCP. O *stream* 1 representa uma resposta HTTP de um arquivo JavaScript e o *stream* 2 representa uma resposta HTTP de um arquivo CSS, transmitidos via HTTP/2.

{% asset_img '2024_03_http2_tcp_packets.png' 'Frames HTTP2 em pacotes TCP' %}
{% post_img '2024_03_http2_tcp_packets.png' 'Frames HTTP2 em pacotes TCP' %}

## HTTP/3

Expand Down Expand Up @@ -191,7 +191,7 @@ sequenceDiagram
end
```

{% asset_img '2024_03_http3_quic_packets.png' 'Pacotes QUIC HTTP3' %}
{% post_img '2024_03_http3_quic_packets.png' 'Pacotes QUIC HTTP3' %}

O bloqueio de cabeça de fila relacionado ao TLS (criptografia SSL) ocorre no TCP porque a criptografia é geralmente aplicada sobre a mensagem inteira, de modo que todos os seus pacotes precisam chegar ao destino para então ocorrer a decriptação. No caso do QUIC, a criptografia é individual para cada pacote QUIC, que é decriptado na chegada, sem haver a necessidade de receber todos os pacotes primeiro.

Expand Down
5 changes: 1 addition & 4 deletions src/posts/2024/04/pipelines-for-dotnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ Pipelines are sequences of commands that are executed to ensure the integrity of

Having a pipeline means having a consistent process that mitigates the risk of human errors in the final product and saves the programmer's time, because he/she can take care of other tasks while the code is compiled, verified and packed.

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_04_conveyor_belt.avif" alt="Conveyor belt" />
<img src="/assets/img/posts/2024_04_conveyor_belt.jpg" alt="Conveyor belt" />
</picture>
{% post_avif_img '2024_04_conveyor_belt.avif' '2024_04_conveyor_belt.jpg' 'Conveyor belt' %}

## Steps

Expand Down
5 changes: 1 addition & 4 deletions src/posts/2024/04/pipelines-para-dotnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ As esteiras automatizadas, também conhecidas como *pipelines*, são seqüência

Ter uma *pipeline* significa ter um processo consistente que minimiza o risco de erros humanos no produto final e economiza tempo do programador, pois ele pode se ocupar de outras tarefas enquanto o código é compilado, verificado e empacotado.

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_04_conveyor_belt.avif" alt="Esteira de produção" />
<img src="/assets/img/posts/2024_04_conveyor_belt.jpg" alt="Esteira de produção" />
</picture>
{% post_avif_img '2024_04_conveyor_belt.avif' '2024_04_conveyor_belt.jpg' 'Esteira de produção' %}

## Etapas

Expand Down
2 changes: 1 addition & 1 deletion src/posts/2024/06/arquitetura-assincrona-sem-filas.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ tags:
- dotnet
---

{% asset_img '2024_06_fila_ingressos_paul_mccartney.jpg' 'Fila de pessoas para comprar ingresso para show do Paul McCartney' %}
{% post_img '2024_06_fila_ingressos_paul_mccartney.jpg' 'Fila de pessoas para comprar ingresso para show do Paul McCartney' %}

## Arquitetura assíncrona

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ tags:
- dotnet
---

{% asset_img '2024_06_fila_ingressos_paul_mccartney.jpg' 'People in a queue to buy tickets for Paul McCartney concert' %}
{% post_img '2024_06_fila_ingressos_paul_mccartney.jpg' 'People in a queue to buy tickets for Paul McCartney concert' %}

## Asynchronous architecture

Expand Down
5 changes: 1 addition & 4 deletions src/posts/2024/06/introducao-a-programacao-funcional.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ tags:
- dotnet
---

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_06_cassino_royale_le_chiffre.avif" alt="Le Chiffre, 007 Casino Royale" />
<img src="/assets/img/posts/2024_06_cassino_royale_le_chiffre.jpg" alt="Le Chiffre, 007 Casino Royale" />
</picture>
{% post_avif_img '2024_06_cassino_royale_le_chiffre.avif' '2024_06_cassino_royale_le_chiffre.jpg' 'Le Chiffre, 007 Casino Royale' %}

## Paradigmas

Expand Down
5 changes: 1 addition & 4 deletions src/posts/2024/06/introduction-to-functional-programming.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ tags:
- dotnet
---

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_06_cassino_royale_le_chiffre.avif" alt="Le Chiffre, 007 Casino Royale" />
<img src="/assets/img/posts/2024_06_cassino_royale_le_chiffre.jpg" alt="Le Chiffre, 007 Casino Royale" />
</picture>
{% post_avif_img '2024_06_cassino_royale_le_chiffre.avif' '2024_06_cassino_royale_le_chiffre.jpg' 'Le Chiffre, 007 Casino Royale' %}

## Paradigms

Expand Down
2 changes: 1 addition & 1 deletion src/posts/2024/08/collation-and-encoding-in-databases.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ But what about texts? A text is a sequence of characters, a character being a le

The table below is for Windows-1252 encoding, which addresses 255 possible characters, each represented by one byte. You can see this table on Windows Character Map (Win+R, `charmap`).

{% asset_img '2024_08_windows_1252_table.gif' 'Windows-1252 encoding table' %}
{% post_img '2024_08_windows_1252_table.gif' 'Windows-1252 encoding table' %}

The **collation** is the ordering and comparison rule for texts. It also determines which encoding is used.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Mas e os textos? Um texto é uma seqüência de caractéres, um caractér sendo

A tabela abaixo é do encoding Windows-1252, que contempla 255 caractéres possíveis, cada um representado por um *byte*. Você pode ver essa tabela com o Mapa de Caractéres do Windows (Win+R, `charmap`).

{% asset_img '2024_08_windows_1252_table.gif' 'Tabela do encoding Windows-1252' %}
{% post_img '2024_08_windows_1252_table.gif' 'Tabela do encoding Windows-1252' %}

A **collation**, por sua vez, é a regra de ordenação usada para comparar textos. Ela também determina, junto consigo, qual é o encoding utilizado.

Expand Down
16 changes: 5 additions & 11 deletions src/posts/2024/08/iceberg-sql.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Os exemplos aqui são em Microsoft SQL Server, porém, a maioria deles existe de

<br>

{% asset_img '2024_08_sql_iceberg.jpg' 'Iceberg de comandos SQL' %}
{% post_img '2024_08_sql_iceberg.jpg' 'Iceberg de comandos SQL' %}

<br>

Expand Down Expand Up @@ -191,10 +191,7 @@ Entrelaça duas ou mais tabelas com base em colunas de referência; esse entrela

Aqui vamos focar apenas no INNER JOIN e no LEFT JOIN.

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_08_sql_joins.avif" alt="Diferentes tipos de JOINs no SQL" />
<img src="/assets/img/posts/2024_08_sql_joins.png" alt="Diferentes tipos de JOINs no SQL" />
</picture>
{% post_avif_img '2024_08_sql_joins.avif' '2024_08_sql_joins.png' 'Diferentes tipos de JOINs no SQL' %}

### INNER JOIN

Expand Down Expand Up @@ -444,10 +441,7 @@ ORDER BY s.[Id] ASC, c.[Id] ASC

## PIVOT

<picture class="my-4">
<source type="image/avif" srcset="/assets/img/posts/2024_08_friends_pivot.avif" alt="Ross pedindo para girar o sofá - Friends" />
<img src="/assets/img/posts/2024_08_friends_pivot.jpg" alt="Ross pedindo para girar o sofá - Friends" />
</picture>
{% post_avif_img '2024_08_friends_pivot.avif' '2024_08_friends_pivot.jpg' 'Ross pedindo para girar o sofá - Friends' %}

A instrução PIVOT é muito interessante. Ela transforma linhas em colunas, ou seja, rotaciona em 90º uma parte da tabela. Ela é muito boa para cruzar duas ou mais colunas de uma mesma tabela.

Expand Down Expand Up @@ -1095,13 +1089,13 @@ No SSMS, basta habilitar a opção *Incluir plano de execução* no menu superio

Ao analisar o custo de cada etapa, você pode entender quais são os gargalos de performance e a partir daí implementar melhorias, tais como criar índices, refazer os critérios de WHERE e JOIN nas consultas, entre outras.

{% asset_img '2024_08_sql_execution_plan.jpg' 'Plano de execução SQL' %}
{% post_img '2024_08_sql_execution_plan.jpg' 'Plano de execução SQL' %}

<br>

# Conclusões finais

{% asset_img '2024_08_titanic.jpg' 'Jack e Rose no Titanic' %}
{% post_img '2024_08_titanic.jpg' 'Jack e Rose no Titanic' %}

O SQL é uma ferramenta extremamente poderosa e completa, e adquiriu novas capacidades ao longo dos anos. Não é à toa que é o *mainstream* de banco de dados até hoje - ele é a base de desenvolvimento de sistemas complexos.

Expand Down
Loading

0 comments on commit 4346db1

Please sign in to comment.