• Stars
    star
    233
  • Rank 172,230 (Top 4 %)
  • Language
    Elixir
  • License
    MIT License
  • Created about 8 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Ecto elixir adjacency list and tree traversal. Supports Ecto versions 2 and 3.

Arbor

Build Status Hex Version Hex docs

Ecto adjacency list and tree traversal using CTEs. Arbor uses a parent_id field and CTEs to create simple deep tree-like SQL hierarchies.

Installation

If available in Hex, the package can be installed as:

Add arbor to your list of dependencies in mix.exs:

For Ecto SQL 3+:

  def deps do
    [{:arbor, "~> 1.1.0"}]
  end

For Ecto 2:

  def deps do
    [{:arbor, "~> 1.0.6"}]
  end

Benchmarks

Arbor has been benchmarked on 10mm+ record tables with efficient results:

10,000,000 rows, 25% root

Running siblings
	10000 runs
	Total time: 1.793026000000013
	Avg: 1.7930260000000131e-4
Running children
	10000 runs
	Total time: 1.5967949999999786
	Avg: 1.5967949999999787e-4
Running descendants
	10000 runs
	Total time: 2.5418830000000012
	Avg: 2.5418830000000013e-4
Running ancestors
	10000 runs
	Total time: 2.87076499999998
	Avg: 2.87076499999998e-4

Usage

defmodule Comment do
  use Ecto.Schema
  # See config options below
  use Arbor.Tree, foreign_key_type: :binary_id

  schema "comments" do
    field :body, :string
 ย  ย belongs_to :parent, __MODULE__

    timestamps
  end
end

All methods return composable Ecto queries. For in depth examples see the tests

Roots

Returns root level records.

roots = Comment.roots
        |> Repo.all

Siblings

Return the siblings of a record.

siblings = my_comment
           |> Comment.siblings
           |> Comment.order_by_popularity
           |> Repo.all

ancestors

Returns the entire ancestor (parent's parent's parent, etc) path to the record, but not including the record.

ancestors = my_comment
              |> Comment.ancestors
              |> Comment.order_by_inserted_at
              |> Repo.all

Descendants

Returns the entire descendant tree of a record, but not including the record.

descendants = my_comment
              |> Comment.descendants
              |> Comment.order_by_inserted_at
              |> Repo.all

A second parameter can be passed to descendants to specify how deep from the root of the tree to retrieve the descendants from.

descendants = my_comment
              |> Comment.descendants(2)
              |> Comment.order_by_inserted_at
              |> Repo.all

Children

Returns the immediate children of a record.

children = my_comment
           |> Comment.children
           |> Repo.all

Parent

Returns the record's parent.

parent = my_comment
         |> Comment.parent
         |> Repo.first

Options

  • table_name - set the table name to use in CTEs
  • tree_name - set the name of the CTE
  • primary_key - defaults to field from Ecto's @primary_key
  • primary_key_type - defaults to type from Ecto's @primary_key
  • foreign_key - defauts to :parent_id
  • foreign_key_type - defaults to type from Ecto's @primary_key
  • orphan_strategy - defaults to :nothing currently unimplemented

Contributing

You'll need PostgreSQL installed and a user that can create and drop databases.

There is a docker-compose file for your convienence.

You can specify it with the environment variable ARBOR_DB_USER.

The mix test task will drop and create the database for each run.

docker-compose up -d
ARBOR_DB_USER=postgres mix test
docker-compose down

More Repositories

1

bonny

The Elixir based Kubernetes Development Framework
Elixir
320
star
2

k8s

Kubernetes API Client for Elixir
Elixir
283
star
3

speakeasy

Middleware based authorization for Absinthe GraphQL powered by Bodyguard
Elixir
81
star
4

klepto

A mean little DSL'd poltergeist (capybara) based web crawler that stuffs data into your Rails app.
Ruby
21
star
5

terraform-aws-cloudwatch_widget

Terraform AWS Cloudwatch Alarm with Dashboard Widget JSON Outputs
HCL
18
star
6

munson

JSON API Spec client for Ruby
Ruby
17
star
7

apocryphal

Swagger based document driven development for ExUnit
Elixir
17
star
8

ballast

Ballast manages kubernetes node pools to give you the cost of preemptible nodes with the confidence of on demand nodes.
Elixir
16
star
9

regulator

Controller-based minimal authorization through OO design and pure Ruby classes
Ruby
15
star
10

ruby-yui

Ruby wrapper for the YUI Compressor.
JavaScript
12
star
11

notion

Notion is a thin wrapper around telemetry that defines functions that dispatch telemetry events, documentation, and specs for your applications events.
Elixir
9
star
12

warningshot

Dependency Resolution Framework
Ruby
8
star
13

talks

Elixir
8
star
14

docker-kinesis-agent

AWS Kinesis Agent on Debian Slim 9
Makefile
7
star
15

dm-property-manager

Model ancestry and property management
Ruby
5
star
16

jquery.babysteps

A simple tool for turning long forms into baby steps.
5
star
17

federated-absinthe

Federating absinthe graphql with GraphQL Mesh.
Elixir
5
star
18

hello_operator

A greeting-server operator created with Bonny
Elixir
5
star
19

k8s-psp-rbac

Assigning kubernetes pod security policies with RBAC
4
star
20

k8s-elixir-schedulers

This is an example app used to illustrate how online schedulers are configured post OTP23 running in kubernetes.
Elixir
4
star
21

ingestor

Tool for ingesting plain text files in ActiveRecord
Ruby
3
star
22

activity_pub

ActivityPub is a decentralized social networking protocol
Elixir
3
star
23

k8s_conf

Parse Kubernetes' config files and generate HTTP headers/options for authenticating to the k8s API.
Elixir
3
star
24

merb_threshold

Access thresholding for controllers and actions. Set reasonable limits and stop constantly captchaing your users.
Ruby
3
star
25

k8s_client

Experimental kubernetes client in elixir
Elixir
3
star
26

petz

Phoenix app using Apocryphal / Swagger for testing
JavaScript
2
star
27

collectively

Add methods to ActiveRecord relations and collections.
Ruby
2
star
28

MerbMax

A collection of plugins for merb. Get your SEO on with meta, configure your instances with roles.
Ruby
2
star
29

res

Elixir state machine demo
Elixir
2
star
30

activity_streams

ActivityStreams 2.0 Validator
Elixir
2
star
31

merb_meta

SEO your merb, easy access to meta tags on a controller-by-controller or action-by-action basis, wee.
Ruby
2
star
32

try_git

1
star
33

images

Some of the best images on the planet.
1
star
34

metrics-mock

A simple prometheus metrics mock service
Go
1
star
35

kinesis-parser

Parse kinesis events
JavaScript
1
star
36

tf_modules

Terraform modules
HCL
1
star
37

yodeler

A generic instrumentation library with a multiple pluggable backend adapters.
Ruby
1
star
38

sacred

A CLI to sync markdown to the Confluence REST API
Go
1
star
39

json-schema-rails-rspec-demo

JSON Schema demo with Rails, RSpec, prmd, committee and active model serializers
Ruby
1
star
40

drinks

A boozy app to teach JSONAPI and some other stuff on Nerd Nights.
Ruby
1
star
41

phoenix-demo-project

Just a demo project for Phoenix
JavaScript
1
star
42

greeting-server

A greeting server for demoing the Bonny SDK
Go
1
star