Skip to content

Custom transforms for creating arbitrarily complex POROs with identity maps #76

@noteflakes

Description

@noteflakes

Right now Extralite supports custom transforms by providing a transform proc that takes the raw values and can return custom objects. A related idea is the ability to turn query results into arbitrarily complex PORO objects, with support for identity maps. This can be especially useful when performing joins where we want to turn the results into a bunch of related objects.

Some preliminary work towards this goal was done in commit bbcf12e.

Example query:

SELECT books.id, books.title, authors.id, authors.name
  FROM books LEFT OUTER JOIN authors ON authors.id = books.author_id

What we want is an identity map expressing relations as nested objects:

# The author object is the same for both book objects.
[
  {
    id: 1,
    title: "foo",
    author: {
      id: 1,
      name: "bar"
    }
  },
  {
    id: 2,
    title: "baz",
    author: {
      id: 1,
      name: "bar"
    }
  }
]

The projection transform is expressed using a DSL:

transform = Extralite.project do
  # the identity modifier is used to express which field is used as key to the identity map
  id.identity
  title
  author {
    id.identity
    name
  }
end

transform.class #=> Extralite::Transform

books = DB.query(transform, sql)

So instead of passing a proc, we pass a transform object. The transform is performed at the C-level, accompanied by identity maps for both book and author objects.

An important limitation for this is that if identity maps are used, the entire result set must be converted before any rows are returned to the application code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions