Coder Social home page Coder Social logo

sqlite_ecto's Introduction

Sqlite.Ecto Build Status

Sqlite.Ecto is a SQLite3 Adapter for Ecto.

Read the tutorial for a detailed example of how to setup and use a SQLite repo with Ecto, or just check-out the CliffsNotes in the sections below if you want to get started quickly.

Dependencies

Sqlite.Ecto relies on Sqlitex and esqlite. Since esqlite uses Erlang NIFs, you will need a valid C compiler to build the library.

Example

Here is an example usage:

# In your config/config.exs file
config :my_app, Repo,
  adapter: Sqlite.Ecto,
  database: "ecto_simple.sqlite3"

# In your application code
defmodule Repo do
  use Ecto.Repo,
    otp_app: :my_app,
    adapter: Sqlite.Ecto
end

defmodule Weather do
  use Ecto.Model

  schema "weather" do
    field :city     # Defaults to type :string
    field :temp_lo, :integer
    field :temp_hi, :integer
    field :prcp,    :float, default: 0.0
  end
end

defmodule Simple do
  import Ecto.Query

  def sample_query do
    query = from w in Weather,
          where: w.prcp > 0 or is_nil(w.prcp),
         select: w
    Repo.all(query)
  end
end

Usage

Add Sqlite.Ecto as a dependency in your mix.exs file.

def deps do
  [{:sqlite_ecto, "~> 1.0.0"}]
end

You should also update your applications list to include both projects:

def application do
  [applications: [:logger, :sqlite_ecto, :ecto]]
end

To use the adapter in your repo:

defmodule MyApp.Repo do
  use Ecto.Repo,
    otp_app: :my_app,
    adapter: Sqlite.Ecto
end

Unsupported Ecto Constraints

The changeset functions foreign_key_constraint/3 and unique_constraint/3 are not supported by Sqlite.Ecto because the underlying SQLite database does not provide enough information when such constraints are violated to support the features.

Note that SQLite does support both unique and foreign key constraints via unique_index/3 and references/2, respectively. When such constraints are violated, they will raise Sqlite.Ecto.Error exceptions.

Silently Ignored Options

There are a few Ecto options which Sqlite.Ecto silently ignores because SQLite does not support them and raising an error on them does not make sense:

  • Most column options will ignore size, precision, and scale constraints on types because columns in SQLite have no types, and SQLite will not coerce any stored value. Thus, all "strings" are TEXT and "numerics" will have arbitrary precision regardless of the declared column constraints. The lone exception to this rule are Decimal types which accept precision and scale options because these constraints are handled in the driver software, not the SQLite database.
  • If we are altering a table to add a DATETIME column with a NOT NULL constraint, SQLite will require a default value to be provided. The only default value which would make sense in this situation is CURRENT_TIMESTAMP; however, when adding a column to a table, defaults must be constant values. Therefore, in this situation the NOT NULL constraint will be ignored so that a default value does not need to be provided.
  • When creating an index, concurrently and using values are silently ignored since they do not apply to SQLite.

sqlite_ecto's People

Contributors

jazzyb avatar lowks avatar parkerl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sqlite_ecto's Issues

Table of Sqlite.Ecto Functionality

Write some sort of table in the wiki to compare what functionality Sqlite.Ecto provides versus basic SQL syntax and the PostgreSQL adapter. That way users don't get any surprises about what capabilities are missing. We can also use it to keep track of the development of new functionality.

General cleanup of code

Refactor. Consolidate duplicate code. Make sure functionality is divided into appropriate modules.

VACUUM

Every time when I run this command I have got the same result: it ends with timeout. Can I do anything with that? Thanks.

iex(11)> Ecto.Adapters.SQL.query(Stats.Repo, "VACUUM", [], timeout: 10 * 60 * 10000)
[error] GenServer #PID<0.607.0> terminating
** (stop) bad return value: {:error, :timeout, #Reference<0.0.7.137441>}
** (exit) exited in: GenServer.call(#PID<0.607.0>, {:query, "VACUUM", [bind: [], timeout: 6000000]}, 6000000)
    ** (EXIT) bad return value: {:error, :timeout, #Reference<0.0.7.137441>}
         (elixir) lib/gen_server.ex:544: GenServer.call/3
    (sqlite_ecto) lib/sqlite_ecto/query.ex:207: Sqlite.Ecto.Query.do_query/4
         (stdlib) timer.erl:197: :timer.tc/3
           (ecto) lib/ecto/adapters/sql.ex:246: Ecto.Adapters.SQL.query/7
           (ecto) lib/ecto/pool.ex:159: Ecto.Pool.do_run/4
           (ecto) lib/ecto/adapters/sql.ex:231: Ecto.Adapters.SQL.query/6
           (ecto) lib/ecto/adapters/sql.ex:209: Ecto.Adapters.SQL.query/5

Tutorial for Setting up Sqlite.Ecto as a Test Database

In mix and config we can setup different development environments for our code depending on whether we are in production, testing, etc. A particular use case could be to configure Sqlite.Ecto for testing and the default PostgreSQL adapter for production.

Figure out how to do the above, and write a tutorial to walk a user through the configuration.

escript build breaks NIF load path

played around with this and noticed that in iex everything works nicely but if I build an escript out of the project I get the following error:

16:25:27.509 [error] The on_load function for module esqlite3_nif returned {{:badmatch,
  {:error,
   {:load_failed,
    'Failed to load NIF library: \'dlopen(priv/esqlite3_nif.so, 2): image not found\''}}},
 [{:esqlite3_nif, :init, 0, [file: 'src/esqlite3_nif.erl', line: 47]},
  {:code_server, :"-handle_on_load/4-fun-0-", 1,
   [file: 'code_server.erl', line: 1659]}]}

stack trace:

** (CaseClauseError) no case clause matching: {:undef, [{:esqlite3_nif, :start, [], []}, {:esqlite3, :open, 2, [file: 'src/esqlite3.erl', line: 59]}, {Sqlitex.Server, :init, 1, [file: 'lib/sqlitex/server.ex', line: 11]}, {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 306]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 237]}]}
    (ecto) lib/ecto/adapters/sql/worker.ex:60: Ecto.Adapters.SQL.Worker.call!/3
    (brain) lib/brain/repo.ex:2: Brain.Repo.log/2
    (ecto) lib/ecto/adapters/sql.ex:451: Ecto.Adapters.SQL.transaction/3
    (ecto) lib/ecto/repo/model.ex:183: Ecto.Repo.Model.with_transactions_if_callbacks/6
    (brain) lib/brain/cli.ex:49: Brain.CLI.process/1
    (elixir) lib/kernel/cli.ex:70: anonymous fn/3 in Kernel.CLI.exec_fun/2

Support for custom SQL queries with sqlite_ecto

By custom SQL query, I mean some kind of SQL query that isn't immediately supported by Ecto. Is there support for writing these queries with this library? For example, Postgrex's adapter allows for custom SQL, but I don't know if there's something similar here.

Modifying a field's value?

Hi @jazzyb ! I was reading the basic tutorial and I saw

Sqlite.Ecto can only add columns to tables -- it cannot remove or modify columns once they have been created.

I am working on a project of mine where people have to be able to add data to an item (the comments field, to be precise).
Do I have to understand that it won't be possible? Or am I misunderstanding any workaround?

Getting error in the tutorial example.

Working through the tutorial in the wiki (https://github.com/jazzyb/sqlite_ecto/wiki/Basic-Sqlite.Ecto-Tutorial) I'm getting the following error when running mix ecto.migrate:

** (MatchError) no match of right hand side value: %{num_rows: 1, rows: [{0}]} lib/sqlite_ecto.ex:31: Sqlite.Ecto.ddl_exists?/3 (ecto) lib/ecto/migration/schema_migration.ex:20: Ecto.Migration.SchemaMigration.ensure_schema_migrations_table!/1 (ecto) lib/ecto/migrator.ex:36: Ecto.Migrator.migrated_versions/1 (ecto) lib/ecto/migrator.ex:134: Ecto.Migrator.run/4 (mix) lib/mix/cli.ex:55: Mix.CLI.run_task/2

Elixir 1.0.4

Delete/Update All with Joins

See the note at the bottom of the tests:

    # NOTE:  The assertions commented out below represent how joins *could* be
    # handled in SQLite to produce the same effect.  Evenually, joins should
    # be converted to the below output.  Until then, joins should raise
    # exceptions.

Handle Decimal module as type

Postgrex and Mariaex both have special handlers for the Decimal module. Figure out if we should handle this in Sqlitex as well or whether it should be handled in Sqlite.Ecto.

Basic Tutuorial

Write a basic tutorial in a wiki that lets a user get up and running with Sqlite.Ecto.

can't create repo

I did the command

mix ecto.gen.repo Blog.Repo

error is

== Compilation error on file lib/sqlite_ecto.ex ==
** (CompileError) lib/sqlite_ecto.ex:41: no super defined for load/2 in module Sqlite.Ecto. Overridable functions available are: autogenerate/1, delete/4, dumpers/2, ensure_all_started/2, execute/6, execute_ddl/3, insert/5, insert_all/6, loaders/2, prepare/2, update/6
    lib/sqlite_ecto.ex:40: (module)

my mix.exs file is

  defp deps do
    [{:phoenix, "~> 1.2.1"},
     {:phoenix_pubsub, "~> 1.0"},
     {:poison, "~> 2.1", override: true},
     {:ecto, "~> 2.0", override: true},
     {:phoenix_ecto, "~> 3.0"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_html, "~> 2.6"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:sqlite_ecto, "~> 1.0.2"},
     {:cowboy, "~> 1.0"}]
  end

Add Ecto2 support

Hey,

I like Ecto2 and sqlite, but they don't play well together. Are there any plans to support Ecto2?

Sqlite.Ecto.DateTime

Write a special datetime type for Sqlite.Ecto to handle the conversions between Ecto.DateTime and the strings that Sqlitex expects in the repos.

Change Transaction to Savepoint

Rewrite the pseudo-returning implementation using savepoints rather than transactions. This way the query can be safely run within another transaction.

Note Silent Failures in the README

There are a few situations where Ecto options are silently ignored because SQLite does not support them but the effects of ignoring them were so minor as to not need raising an error. These "silent failures" should be enumerated and documented in the README.

Quote strings in queries

Need to make sure we are correctly quoting identifiers in queries. Copy the way the Postres adapter does it.

"db" directory is not created when generating a new phoenix app using --database sqlite

When I created a new app using "mix phoenix.new myapp --database sqlite" then I executed "cd myapp && mix ecto.create" the task has finished with the following error:

** (Mix) The database for Myapp.Repo couldn't be created, reason given: {:cantopen, 'unable to open database file'}.

After inspecting the end of the file "myapp/config/dev.exs" I can see that the database adapter configuration is correct:

Configure your database

config :myapp, Myapp.Repo,
adapter: Sqlite.Ecto,
database: "db/myapp_dev.sqlite",
pool_size: 10

But the "db" directory does not exist in the application directory.

The workaround is to create the "db" directory prior executing "mix ecto.create", it would be desirable to fix that issue.

Affected and used version: 1.0.0

DDL

Write SQLite.Ecto.Connection.execute_ddl/1

Usage with Phoenix

So im testing out Elixir/Phoenix and have a old project with a sqlite database, im thinking of reusing the same database, but there is conflicts in the ecto version Phoenix wants to use and the on required by sqlite_ecto. So basically im wondering if sqlite_ecto has support/any issues with ecto 13.0/14.0?

Looking up alternatives for conflicting requirements on ecto
From mix.lock: 0.13.0
From sqlite_ecto v0.2.0: ~> 0.12.1
** (Mix) Hex dependency resolution failed, relax the version requirements or unlock dependencies

Pseudo Returning Clause

General task list for finalizing the syntax/format of the pseudo returning clause:

  • Make sure the syntax for the returning clause won't overlap with any "normal" SQLite query
  • The values extracted from SQLite.Ecto.Connection.parse_query_type/1 should be added to the returning clause.

Initial Documentation

  • Module docs
  • Document all exported functions
  • Write README with example usage
  • Setup inch doc thingy
  • Write-up a wiki page to document RETURNING clause algorithm
  • Ditto the ALTER TABLE algorithm

Empty schemas when using more than one database.

Hi, I'm having a particularly weird issue where the databases don't have a schema after the migration. For instance, my migration file for a user database looks like

defmodule Exon.Repo.Migrations.CreateUser do
  use Ecto.Migration

  def change do
    create table(:users) do
      add :username, :string
      add :hashed_password, :string

      timestamps
    end
  end
end

I run mix ecto.create -r Exon.Repo.Users and mix ecto.migrate -r Exon.Repo.Users and everything is successful.
However, when I run sqlite3 users.dev.sqlite3 .schema on the newly created database, it gives me
this โ†“

CREATE TABLE "schema_migrations" ("version" BIGINT PRIMARY KEY, "inserted_at" DATETIME);

The User model is

defmodule Exon.User do
  use Ecto.Model

  schema "users" do
    field :username, :string
    field :hashed_password, :string
    timestamps
  end

end

And I have this

config :exon, Exon.Repo.Users,
  adapter: Sqlite.Ecto,
  database: "priv/users.dev.sqlite3"

in config/dev.exs.

@jazzyb Do you have any idea about this problem?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.