Open sourced a website, blog and more. Merry Christmas!
I decided to make it open source because someone else might benefit from the work i have done over the years even though, at times, some functionality might not have the perfect implementation, so take it as it is if you want :)
Most features have an equivalent admin space where things can be configured…
Conditional guard for structs of an explicit type
Blogged on how to conditionally define a guard to check if the argument is a particular struct, so that it works with previous versions of Elixir / OTP.
→ https://rocket-science.ru/hacking/2021/02/12/conditional-defguard
Elixir Wizards S5E11 Yair Flicker on SmartLogic’s Origin, Evolution, and Elixir Adoption Process
Latest episode of Elixir Wizards is out today! Check it out here: https://smartlogic.io/podcast/elixir-wizards/s5e11-flicker/
IntellIJ Elixir v11.10.0
Changelog
Enhancements
-
Simplify
onlyTemplateDateFileType
-
Add missing opcodes to
Code
disassembler-
OTP 23 opcode
bs_start_match4
-
Current (in-development) OTP 24 opcodes
-
make_fun3
-
init_yregs
-
recv_marker_bind
-
recv_marker_clear
-
recv_marker_clear
-
recv_marker_user
-
-
OTP 23 opcode
-
Log
PsiElement
ifCall#finalArguments
contain anull
. -
Suggest ASDF directories as
homepath
s for both Elixir and Erlang for Elixir SDKs. -
Run ‘Dialyzer based inspections (Elixir)’ using Elixir SDK running
mix dialyzer
or any customizedmix
command.
Bug Fixes
-
Use
VirtualFile#fileType
instead of EEx Type::INSTANCE when looking up extensions. Since LEEx fileType
is a subclass of EEx’s fileType
, it callstemplateDataFileTypeSet
in EEx’sType
, buttemplateDataFileTypeSet
usesINSTANCE
from EEx. By using theVirtualFile#fileType
instead, it will properly be EEx or LEEx based on the actual file extension and then it can be used to strip that off and find the DataTemplateLanguage, such asHTMLLanguage
for.html.leex
. -
Compare max opcode in to file to max opcode number, not ordinal.
Opcodes are 1-based, but the ordinal of the Kotlin
Enum
s are 0-based, so the comparison was off-by-1 when a file had the max opcode and would be incorrectly marked as too new. -
Don’t return null left or right infix operands in
primaryArguments
operation.infix.Normalized.leftOperand
and.rightOperand
ensures thatPsiErrorElement
is not returned: they can returnnull
when there is no left or right operand.Infix.primaryArguments
was not taking this into account and so could return anull
as one of theprimaryArguments
, which brokeCall.finalArguments
. -
Don’t attempt to execute
elixir -e “System.version |> IO.puts”
to get the version number as it requires too much of a full SDK to be built and from the Erlang paths to be correct too, which was rarely the case for ASDF. Since for Homebrew and ASDF, the directory name is the version name, this shouldn’t be a loss in naming ability. If the directory name is not a parseable version it will be of the formatElixir at <path>
. This is probably more correct for installs directories that aren’t versioned as SDK versions aren’t updated if the version installed at the path changes, such as/usr/local/elixir
or/opt/elixir
, etc.
Elixir Wizards Livestream: Brewing a Love Potion 2/12
This Friday! Another Elixir Wizards live stream, with many special guests. Join us from 11AM-1PM EST at https://www.twitch.tv/smartlogictv
ThinkingElixir 034: José Valim reveals Project Nx
In episode 34 of Thinking Elixir, José Valim visits and finally publicly reveals what Project Nx is. He and others have been working on it for 3 months and he’s finally ready to unveil it. José will speak more about it at the LambdaDays conference, demonstrating it with code and announcing the release and availability of the OpenSource code. This is an exciting development that brings Elixir into areas it hasn’t been used before. We also talk about what this means for Elixir and the community going forward. A must listen!
Still: A Composable Elixir Static Site Generator
Use Elixir everywhere and anywhere. Presenting Still, a composable Elixir Static Site Generator. https://stillstatic.io
PKCS#5 algorithms in Erlang
https://github.com/exograd/erl-pkcs5
Erlang implementation of PBKDF2 algorithm defined by the RFC 8018.
Practical Concurrency Cookbook
https://functional.works-hub.com/learn/elixir-practical-concurrency-3794f
A small collection of concurrency patterns that keep emerging when working on Elixir applications.
Monitoring Phoenix LiveView Performance
Our Monitoring Phoenix LiveView Performance blog post is out! Covers Live Dashboard and Observer. Find it here: https://alembic.com.au/blog/2021-02-05-monitoring-phoenix-liveview-performance
2nd alpha release of "Create a cryptocurrency trading bot in Elixir" is out
2nd alpha release of my book is out! 3 new chapters. @ 50% finished, it’s about 145 pages long and has 12 chapters. Early bird access, pay what you want (although some $$$ would be totally cool with me :D)
https://leanpub.com/create-a-cryptocurrency-trading-bot-in-elixir
Feel free to reach out if you found any issue / drop a comment / say hi :)
Have a wonderful Sunday,
Kamil
Phoenix UI testing with Cypress, Part 1
Adding Cypress UI testing/end-to-end testing to a Phoenix project. In Part 1, it’s all about setup and getting a first test to run. Find the article at https://sgoettschkes.me/p/phoenix-testing-with-cypress.html
Elixir Wizards S5E10 Alexandra Chakeres on Moving Towards an Inclusive Elixir Community
Latest episode of Elixir Wizards is out today! Check it out here: https://smartlogic.io/podcast/elixir-wizards/s5e10-chakeres/
TimescaleDB support in Elixir using Ecto
Most of the projects collect a lot of data. It usually means a heavy loads on the database. What can we do to provide better request handling and lower access times? See how to integrate Elixir and Ecto with one, very popular extension for PostgreSQL database which is TimescaleDB.
https://bartoszgorka.com/timescaledb-support-in-elixir-using-ecto
Fat Fingered Input
I made a simple LIveview form to reduce data input errors https://andrewbarr.io/posts/fat-finger-input
How to use String UUID in Hibernate with MySQL
Article originally posted on my personal website at How to use String UUID in Hibernate with MySQL - Petre Popescu
When creating the database structure it is important to make sure that each row in a table has a unique ID so that it can be easily indexed, retrieved, and manipulated when needed. The most common methods are to use an auto-incremented column or a generated UUID.
I won’t be covering the auto-incremented method since it poses no real problems and can be mapped to an Integer in the Java domain class. When using an UUID, this can pose some tricks, depending on the configuration and MySQL version. The good news is that there is an easy way of mapping the Java UUID column to MySQL using Hibernate and no additional libraries are needed.
First, let’s look at the a sample table. I will be using a simplified version of a USERS table that stores login information for each registered user to a site. We will need the following information:
- ID
- Name
- Password Hash*
*This is a simplified structure and only has a minimum number of columns. Storing an unsalted password hash is not recommended. Look up best practices of storing passwords in the database when creating the final structure. We want the ID to be unique so we will be using the Java UUID in our domain object. Because we want all the information to be human readable as well, the ID should be stored as a String. Since we know the format of the UUID when represented as a String, we know that it has a length of 36 characters, so we can define the column as VARCHAR(36). The rest of the table structure can be similar to the image.
Now, we create our domain class using Hibernate annotations to map it to our existing MySQL table.
@Entity
@Table(name = "users")
public class UserDO {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(36)")
private UUID id;
@Column
private String username;
@Column
private String email;
@Column(name = "password_hash")
private String passwordHash;
}
We expect that everything works as intended and that Hibernate knows how to map the UUID to the VARCHAR(36) column, but this is only partially true. When executing the code and trying to do an insert, an java.sql.SQLException will be thrown:
java.sql.SQLException: Incorrect string value: '\xE3\xAF\xF7d\x0CG…' for column 'id' at row 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1040)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1347)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1025)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
This is because Hibernate tries to insert it as Binary data instead of String. There are two options at the moment. First, we can change the column of the ID in the database to be of type BINARY. This will solve the problem and inserting a new user will be successful. However, in doing so, the ID is no longer human-readable and it can be difficult in the future to debug, analyze logs, or manually manipulate the entries.
What we want is to have a String UUID column using Hibernate without the need to do any further manipulation in the code. This is where a new annotation comes into play: @Type
@Entity
@Table(name = "users")
public class UserDO {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(36)")
@Type(type = "uuid-char")
private UUID id;
@Column
private String username;
@Column
private String email;
@Column(name = "password_hash")
private String passwordHash;
}
This annotation defines the Hibernate type mapping. Using “uuid-char” instructs Hibernate to store the UUID as a String, instead of the binary value. This way, it can be written to and read from a VARCHAR(36) column without the need for any pre-processing on our side.
ThinkingElixir 033: Postgres PubSub and Elixir with Allen Wyma
In episode 33 of Thinking Elixir, we talk with Allen Wyma about a Postgres PubSub feature and how it plays nice with Elixir. We dispel the idea that you should always use Phoenix PubSub just because it’s there and we cover the value of learning what’s built-in to tools like the postgrex library. Allen shares how Postgres PubSub elegantly solved a problem for him and he gives tips for using it. We also talk about teaching Elixir through Allen’s YouTube videos and teaching in person with his Teach Me Code efforts.
UUID Primary Key in Elixir Phoenix with PostgreSQL and Ecto
https://pawelurbanek.com/elixir-phoenix-uuid
UUID also known as GUID is an alternative primary key type for SQL databases. It offers some non-obvious advantages compared to standard integer-based keys. Phoenix provides reliable support for working with UUID using its Ecto PostgreSQL adapter. In this tutorial, we will dive deep into UUIDs with all their cons and pros.
Top 3 Tough Elixir Fights |Debugging in Production | 2020
The top 3 challenges faced in production runtime & debugging them.
https://medium.com/blackode/top-3-tough-elixir-fights-debugging-in-production-2020-6ab712a2c8f4
This article isn’t about how to code. It talks about some experiences with Elixir
TQ Happy Coding :)
Connecting to a FTP server with Elixir
I recently had to connect to FTP servers with Elixir, here are my findings: https://thibautbarrere.com/2020/12/13/connecting-to-ftp-with-elixir