Skip to content

Commit 255fdd3

Browse files
authored
Fix defaults, add documentation (#13)
* disable doc for internal modules * update defaults, add documentation * add doc about pool_size
1 parent d0d63e0 commit 255fdd3

File tree

7 files changed

+125
-13
lines changed

7 files changed

+125
-13
lines changed

integration_test/test_helper.exs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ alias Ecto.Integration.TestRepo
1313
Application.put_env(:ecto_sqlite3, TestRepo,
1414
adapter: Ecto.Adapters.SQLite3,
1515
database: "/tmp/exqlite_integration_test.db",
16-
journal_mode: :wal,
17-
cache_size: -64000,
18-
temp_store: :memory,
1916
pool: Ecto.Adapters.SQL.Sandbox,
20-
pool_size: 5,
2117
show_sensitive_data_on_connection_error: true
2218
)
2319

@@ -27,10 +23,6 @@ alias Ecto.Integration.PoolRepo
2723
Application.put_env(:ecto_sqlite3, PoolRepo,
2824
adapter: Ecto.Adapters.SQLite3,
2925
database: "/tmp/exqlite_integration_pool_test.db",
30-
journal_mode: :wal,
31-
cache_size: -64000,
32-
temp_store: :memory,
33-
pool_size: 5,
3426
show_sensitive_data_on_connection_error: true
3527
)
3628

lib/ecto/adapters/sqlite3.ex

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,108 @@
11
defmodule Ecto.Adapters.SQLite3 do
2+
@moduledoc """
3+
Adapter module for SQLite3.
4+
5+
It uses `Exqlite` for communicating to the database.
6+
7+
## Options
8+
9+
The adapter supports a superset of the options provided by the
10+
underlying `Exqlite` driver.
11+
12+
### Provided options
13+
14+
* `:database` - The path to the database. In memory is allowed. You can use
15+
`:memory` or `":memory:"` to designate that.
16+
* `:journal_mode` - Sets the journal mode for the sqlite connection. Can be
17+
one of the following `:delete`, `:truncate`, `:persist`, `:memory`,
18+
`:wal`, or `:off`. Defaults to `:wal`.
19+
* `:temp_store` - Sets the storage used for temporary tables. Default is
20+
`:default`. Allowed values are `:default`, `:file`, `:memory`.
21+
* `:synchronous` - Can be `:extra`, `:full`, `:normal`, or `:off`. Defaults
22+
to `:normal`.
23+
* `:foreign_keys` - Sets if foreign key checks should be enforced or not.
24+
Can be `:on` or `:off`. Default is `:on`.
25+
* `:cache_size` - Sets the cache size to be used for the connection. This is
26+
an odd setting as a positive value is the number of pages in memory to use
27+
and a negative value is the size in kilobytes to use. Default is `-64000`.
28+
* `:cache_spill` - The cache_spill pragma enables or disables the ability of
29+
the pager to spill dirty cache pages to the database file in the middle of
30+
a transaction. By default it is `:on`, and for most applications, it
31+
should remain so.
32+
* `:case_sensitive_like` - whether LIKE is case-sensitive or not. Can be
33+
`:off` or `:on`. Defaults to `:off`.
34+
* `:auto_vacuum` - Defaults to `:none`. Can be `:none`, `:full` or
35+
`:incremental`. Depending on the database size, `:incremental` may be
36+
beneficial.
37+
* `:locking_mode` - Defaults to `:normal`. Allowed values are `:normal` or
38+
`:exclusive`. See [sqlite documenation][1] for more information.
39+
* `:secure_delete` - Defaults to `:off`. Can be `:off` or `:on`. If `:on`, it will cause SQLite3
40+
to overwrite records that were deleted with zeros.
41+
* `:wal_auto_check_point` - Sets the write-ahead log auto-checkpoint
42+
interval. Default is `1000`. Setting the auto-checkpoint size to zero or a
43+
negative value turns auto-checkpointing off.
44+
* `:busy_timeout` - Sets the busy timeout in milliseconds for a connection.
45+
Default is `2000`.
46+
* `:pool_size` - the size of the connection pool. Defaults to `5`.
47+
48+
For more information about the options above, see [sqlite documenation][1]
49+
50+
### Differences between SQLite and Ecto SQLite defaults
51+
52+
For the most part, the defaults we provide above match the defaults that SQLite usually
53+
ships with. However, SQLite has conservative defaults due to its need to be strictly backwards
54+
compatible, so some of them do not necessarily match "best practices". Below are the defaults
55+
we provide above that differ from the normal SQLite defaults, along with rationale.
56+
57+
* `:journal_mode` - we use `:wal`, as it is vastly superior
58+
for concurrent access. SQLite usually defaults to `:delete`.
59+
See [SQLite documentation][2] for more info.
60+
* `:temp_store` - we use `:memory`, which increases performance a bit.
61+
SQLite usually defaults to `:file`.
62+
* `:foreign_keys` - we set it to `:on`, for better relational guarantees.
63+
This is also the default of the underlying `Exqlite` driver.
64+
SQLite usually defaults to `:off` for backwards compat.
65+
* `:busy_timeout` - we set it to `2000`, to better enable concurrent access.
66+
This is also the default of `Exqlite`. SQLite usually defaults to `0`.
67+
* `:cache_size` - we set it to `-64000`, to speed up access of data.
68+
SQLite usually defaults to `-2000`.
69+
70+
These defaults can of course be overridden, as noted above, to suit other needs.
71+
72+
[1]: https://www.sqlite.org/pragma.html
73+
[2]: https://sqlite.org/wal.html
74+
75+
## Limitations
76+
77+
There are some limitations when using Ecto with SQLite that one needs
78+
to be aware of. The ones listed below are specific to Ecto usage, but it
79+
is encouraged to also view the guidance on [when to use SQLite][4] provided
80+
by the SQLite documentation, as well.
81+
82+
### Async Sandbox testing
83+
84+
The Ecto SQLite3 adapter does not support async tests when used with
85+
`Ecto.Adapters.SQL.Sandbox`. This is due to SQLite only allowing up one
86+
write transaction at a time, which often does not work with the Sandbox approach of
87+
wrapping each test in a transaction.
88+
89+
### LIKE match on BLOB columns
90+
91+
We have the DSQLITE_LIKE_DOESNT_MATCH_BLOBS compile-time option set to true,
92+
as [recommended][3] by SQLite. This means you cannot do LIKE queries on BLOB columns.
93+
94+
### Schemaless queries
95+
96+
Using [schemaless Ecto queries][5] will not work well with SQLite. This is because
97+
the Ecto SQLite adapter relies heavily on the schema to support a rich array of Elixir
98+
types, despite the fact SQLite only has [five storage classes][5]. The query will still
99+
work and return data, but you will need to do this mapping on your own.
100+
101+
[3]: https://www.sqlite.org/compile.html
102+
[4]: https://www.sqlite.org/whentouse.html
103+
[5]: https://www.sqlite.org/datatype3.html
104+
"""
105+
2106
use Ecto.Adapters.SQL,
3107
driver: :exqlite
4108

lib/ecto/adapters/sqlite3/codec.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Ecto.Adapters.SQLite3.Codec do
2+
@moduledoc false
3+
24
def bool_decode(nil), do: {:ok, nil}
35
def bool_decode(0), do: {:ok, false}
46
def bool_decode("0"), do: {:ok, false}

lib/ecto/adapters/sqlite3/connection.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Ecto.Adapters.SQLite3.Connection do
2+
@moduledoc false
3+
24
@behaviour Ecto.Adapters.SQL.Connection
35

46
alias Ecto.Migration.Constraint
@@ -34,6 +36,10 @@ defmodule Ecto.Adapters.SQLite3.Connection do
3436
# todo: we may want to consider wrapping any provided :configure
3537
# with our custom connection buffering logic
3638
opts
39+
|> Keyword.put_new(:journal_mode, :wal)
40+
|> Keyword.put_new(:cache_size, -64000)
41+
|> Keyword.put_new(:temp_store, :memory)
42+
|> Keyword.put_new(:pool_size, 5)
3743
|> Keyword.put_new(:configure, &handle_thundering_herd/1)
3844
end
3945

lib/ecto/adapters/sqlite3/data_type.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Ecto.Adapters.SQLite3.DataType do
2+
@moduledoc false
3+
24
# Simple column types. Note that we ignore options like :size, :precision,
35
# etc. because columns do not have types, and SQLite will not coerce any
46
# stored value. Thus, "strings" are all text and "numerics" have arbitrary

mix.exs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ defmodule EctoSQLite3.MixProject do
1313
package: package(),
1414
description: description(),
1515
test_paths: test_paths(System.get_env("EXQLITE_INTEGRATION")),
16-
elixirc_paths: elixirc_paths(Mix.env())
16+
elixirc_paths: elixirc_paths(Mix.env()),
17+
18+
# Docs
19+
name: "Ecto SQLite3",
20+
docs: docs()
1721
]
1822
end
1923

@@ -65,6 +69,12 @@ defmodule EctoSQLite3.MixProject do
6569
]
6670
end
6771

72+
defp docs do
73+
[
74+
main: "Ecto.Adapters.SQLite3",
75+
]
76+
end
77+
6878
defp elixirc_paths(:test), do: ["lib", "test/support"]
6979
defp elixirc_paths(_), do: ["lib"]
7080

test/test_helper.exs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ alias Ecto.Integration.TestRepo
1111
Application.put_env(:ecto_sqlite3, TestRepo,
1212
adapter: Ecto.Adapters.SQLite3,
1313
database: "/tmp/exqlite_sandbox_test.db",
14-
journal_mode: :wal,
15-
cache_size: -64000,
16-
temp_store: :memory,
1714
pool: Ecto.Adapters.SQL.Sandbox,
18-
pool_size: 5,
1915
show_sensitive_data_on_connection_error: true
2016
)
2117

0 commit comments

Comments
 (0)