Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of EctoRange.Num #13

Open
pcapel opened this issue Nov 29, 2023 · 2 comments
Open

Use of EctoRange.Num #13

pcapel opened this issue Nov 29, 2023 · 2 comments

Comments

@pcapel
Copy link

pcapel commented Nov 29, 2023

Hello!

Awesome little library, thanks for building it!

I had some questions about the use of the EctoRange.Num type. I've got some numeric ranges that I want to store and for one of them, I'd like to represent it as '[N, infinity]'::numrange. The issue I'm having is figuring out how to get this translated into a valid changeset for the entry.

Additionally, it seems that if you write an empty range, reading it back will fail in loading due to no matching handler for an :empty atom.

Happy to help out with a PR. I've dug around a bit an have some ideas about how this might be addressed, but I wanted to get some thoughts.

Namely, it looks like the cast logic is pretty restrictive in terms of the types it expects. So by widening that out, we could address the issue of infinity.

Loading seems like it just needs a case for normalize_range to handle an empty range.

I was also curious if adding in a parser for string definitions to be cast to ranges would be something you'd be interested in? That is, EctoRange.from("[1,5)") -> %Postgrex.Range{upper: 5, lower: 1, upper_inclusive: true, lower_inclusive: false}. Just a thought. It would make working with numeric ranges a fair bit simpler.

@davydog187
Copy link
Owner

Hello @pcapel, thank you for your interest in this library! I do believe that this library needs some rework to support infinite ranges. Here's a little livebook test I did

# Run as: iex --dot-iex path/to/notebook.exs

# Title: Infinite Ranges

Mix.install([
  {:ecto, "~> 3.11"},
  {:ecto_range, "~> 0.2.1"}
])

# ── Schema ──

defmodule Schema do
  use Ecto.Schema
  import Ecto.Changeset

  embedded_schema do
    field(:name, :string)
    field(:range, EctoRange.Num)
  end

  def changeset(schema \\ %__MODULE__{}, attrs) do
    schema
    |> cast(attrs, [:name, :range])
  end
end

# ── Ranges ──

[
  Schema.changeset(%{name: "infinity", range: {1, :infinity}}),
  Schema.changeset(%{name: "unbound", range: {1, :unbound}}),
  Schema.changeset(%{name: "nil", range: {1, nil}})
]

If you're interested in a PR, that would be great!

I was also curious if adding in a parser for string definitions to be cast to ranges would be something you'd be interested in? That is, EctoRange.from("[1,5)") -> %Postgrex.Range{upper: 5, lower: 1, upper_inclusive: true, lower_inclusive: false}.

I'm not opposed to this addition! If you're going to send a PR, I would implement this separately.

Let me know how I can help

@pcapel
Copy link
Author

pcapel commented Dec 6, 2023

Excellent. I'll probably have some questions around the semantics and the details of the API implementation. But I'll try and deduce as much as I can from the code base. May be a little while due to the holidays, but I'll try and get something working sooner or later. 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants