Code Monkey home page Code Monkey logo

turbo_ecto's Introduction

Greetings, my friend! 👋

My name is Zven Wang and I am Software Developer based in Beijing.

Developing software since 2011, went from Python to Ruby and React until landing on Elixir and a particular interested for distributed scalable systems and computational logic.

Technologies I love:

  • EventSourcing and CQRS in Elixir
  • Expert systems
  • DSL and parsers built in Elixir/Erlang
  • Phoenix framework
  • Javascript and React
  • gRPC
  • Ruby

turbo_ecto's People

Contributors

dependabot-preview[bot] avatar docjerem avatar kianmeng avatar redmar avatar vtm9 avatar zgohr avatar zven21 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

Watchers

 avatar  avatar  avatar

turbo_ecto's Issues

Support for ecto 3.0

I am trying out a phoenix 1.4 codebase, and for that, the ecto is 3.0. Due to the constaints on this package, I'm unable to use it. Could you please upgrade and release a new version?

Bug: base-query with join generates improper sql

I need to layer the turbo-ecto query with a base-query:

def list_paginated_reviews(params, user) do
    Review
    |> with_friends(user)
    |> preload(...)
    |> Turbo.Ecto.turbo(params)
end
  
def with_friends(review, user) do
  review
  |> join(:inner, [r], uf in UserFriend, on: uf.user_id == ^user.id)
  ...

Trying to filter by category-name:

from r0 in Review,
 join: u1 in UserFriend,
 on: u1.user_id == ^2,
 join: c2 in Category,
 on: c2.id == r0.category_id,
 where: u1.name == ^"Cool stuff",
 order_by: [desc: r0.inserted_at],
 ...

Am I doing something wrong?

support 'or' associate symbol.

Product table structure

Field Type Comment
title string
body text
price float
available boolean
inserted_at datetime
uupdated_at datetime

Input

url_query = http://localhost:4000/products?q[title_or_body_like]=elixir

Transfer:

iex> params = %{"q" => %{"title_or_body_like" = "elixir"}}
iex> Turbo.Ecto.turboq(Product, params)

Expect output:

#Ecto.Query<from t in Product, where: like(t.title, ^"elixir"), or_where: like(t.body, ^"elixir")>

Support for Ecto 3.

Hi!
Wonder if there's any plans to create a public release for supporting Ecto 3. As our library is dependent on your library and we want to upgrade to Ecto 3 (hex wont allow for any non released packages afaik) it would be awesome if it can happen :)

FLEWID-AB/alkemist#24

How to Preload associations data?

Is there a way to preload associations data?

result = Product |> Turbo.Ecto.turbo(params, [entry_name: "entries"])

How we do also preload category?
ps. I am a newbie

support *_in keyword

Product table structure

Field Type Comment
title string
body text
price float
available boolean
inserted_at datetime
uupdated_at datetime

Input:

url_query = http://localhost:4000/products?q[price_in][]=100&q[price_in][]=200

Transfter

iex> params = %{"q" => %{"price_in" = ["100", "200"]}}
iex> Turbo.Ecto.turboq(Product, params)

Output:

#Ecto.Query<from t in Product, where: t.price in (100, 200)>

support assoc table within search.

Table structure

  • Category
Field Type Comment
name string
  • Product
Field Type Comment
title string
body text
price float
category_id integer
available boolean
  • Variant
Field Type Comment
title string
price float
product_id integer

Input

url_query = http://localhost:4000/varinats?q[product_category_name_like]=elixir

Process:

iex> params = %{"q" => %{"product_category_name_like" = "elixir"}}
iex> Turbo.Ecto.turboq(Variant, params)

Expect output:

#Ecto.Query<from v in Varinat, join: p in Product,
 on: v.product_id == p.id, join: c in Category, on: p.category_id == c.id,
 where: like(c.name, ^"%elixir%")>

The current state of the library

I've read the docs and the title page of the project but still left in some doughts about what features are supported.

Does it support filtering entities by values of their associations and if the answer is yes, where can I see the examples of how it can be done?

If the previous question has positive answer, then the second question is are there any problems with associations namings if for example they have same naming for different sub-associations or if they have underscores in their names? I'm asking because from example it seems that the names are havily used in search form params names.

The third question: are search queries like
SELECT * from entities e where (e.field1=‘value1’ OR e.field1=‘value2’) AND (e.field2=‘value3’ OR e.field2=‘value4’ OR …)
with grouping of AND and OR where closes supported?

Fourth question: Ecto.Query.Api supports functions like datetime_add/3, date_add/3, from_now/2, ago/2 for filtering by date intervals. How can we incorporate them within the search using your library?

Raise actual error reason during search

In the scenario where a search field is not part for the schema(queryable) supplied to turboq/2, here is the current result in the case of an error (RuntimeError) Expected params, got %{"q" => %{"name_like" => "son"}, "s" => "inserted_at+asc"} raised from

{:error, _} -> raise "Expected `params`, got #{inspect(params)}"

Current error is generic and does not help in terms of debugging issues.

I will suggest returning the exact error reason from the tuple (:error, reason) returned from the with clause execution e.g

{_assoc, nil} -> {:error, :attribute_not_found}
currently this is being silenced and a generic error message is returned.

A solution can be to match against the returned error reason atom and provide human readable error messages. Something like;

def run(queryable, params) do
    schema = extract_schema(queryable)
    params = Utils.stringify_keys(params)

    with {:ok, %Search{} = searches} <- Search.run(schema, params),
         {:ok, sorts} <- Sort.run(schema, params),
         {:ok, %Paginate{} = %{limit: limit, offset: offset}} <- Paginate.run(params) do
      relations = build_relations(searches, sorts)
      binding = relations |> build_binding()

      queryable
      |> join(relations)
      |> where(searches, binding)
      |> order_by(sorts, binding)
      |> limit(limit, binding)
      |> offset(offset, binding)
    else
      {:error, :attribute_not_found} -> raise "One or more keys in your search are not contained or can't be linked to the specified schema"
      {:error, _} -> raise "Expected `params`, got #{inspect(params)}"
    end
  end

support *_between keyword

Product table structure

Field Type Comment
title string
body text
price float
available boolean

Input:

url_query = http://localhost:4000/products?q[price_between][]=100&q[price_between][]=200

Transfter

iex> params = %{"q" => %{"price_between" = ["100", "200"]}}
iex> Turbo.Ecto.turboq(Product, params)

Output:

#Ecto.Query<from t in Product, where: (t.price between ^100 and ^200)>

support 'and' associate symbol.

Product table structure

Field Type Comment
title string
body text
price float
available boolean
inserted_at datetime
uupdated_at datetime

Input

url_query = http://localhost:4000/products?q[title_or_body_like]=elixir

Transfer:

iex> params = %{"q" => %{"title_and_body_like" = "elixir"}}
iex> Turbo.Ecto.turboq(Product, params)

Expect output:

#Ecto.Query<from t in Product, where: like(t.title, ^"elixir"), where: like(t.body, ^"elixir")>

support *_present keyword

Product table structure

Field Type Comment
title string
body text
price float
available boolean
inserted_at datetime
uupdated_at datetime

Input:

iex> params = %{"q" => %{"price_present" = true}}
iex> Turbo.Ecto.turboq(Product, params)

Expect output:

#Ecto.Query<from t in Product, where: t.price != '', where: not(is_nil(t.price))>

support *_not_eq keyword at searching.

Product table structure

Field Type Comment
title string
body text
price float
available boolean
inserted_at datetime
uupdated_at datetime

Input

url_query = http://localhost:4000/products?q[price_not_eq]=100

Transfer:

iex> params = %{"q" => %{"price_not_eq" = 100}}
iex> Turbo.Ecto.turboq(Product, params)

Expect output:

#Ecto.Query<from t in Product, where: t.price != ^100>

support *_blank keyword

Product table structure

Field Type Comment
title string
body text
price float
available boolean
inserted_at datetime
uupdated_at datetime

Input:

iex> params = %{"q" => %{"price_blank" = true}}
iex> Turbo.Ecto.turboq(Product, params)

Expect output:

#Ecto.Query<from t in Product, where: t.price = '', or_where: is_nil(t.price)>

Usage with multitenancy libraries like Triplex

For this I need an easy way to pass a prefix param to Repo.

  def list_users do
    Repo.all(Users, prefix: "demo")
  end

and my urbo repo call is:

 Turbo.Ecto.turbo(Users, params, entry_name: "users")

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.