Набор строк Anorm из столбца postgres ltree

У меня есть таблица с одним из столбцов, имеющим тип ltree, и следующий код, извлекающий из нее данные:

SQL("""select * from "queue"""")()
.map(
    row =>
        {
            val queue =
                Queue(
                    row[String]("path"),
                    row[String]("email_recipients"),
                    new DateTime(row[java.util.Date]("created_at")),
                    row[Boolean]("template_required")
                )
            queue
        }
).toList

что приводит к следующей ошибке:

RuntimeException: TypeDoesNotMatch(Cannot convert notification.en.incident_happened:class org.postgresql.util.PGobject to String for column ColumnName(queue.path,Some(path)))

Схема таблицы очереди следующая:

CREATE TABLE queue
(
  id serial NOT NULL,
  template_id integer,
  template_version integer,
  path ltree NOT NULL,
  json_params text,
  email_recipients character varying(1024) NOT NULL,
  email_from character varying(128),
  email_subject character varying(512),
  created_at timestamp with time zone NOT NULL,
  sent_at timestamp with time zone,
  failed_recipients character varying(1024),
  template_required boolean NOT NULL DEFAULT true,
  attachments hstore,
  CONSTRAINT pk_queue PRIMARY KEY (id ),
  CONSTRAINT fk_queue__email_template FOREIGN KEY (template_id)
      REFERENCES email_template (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT
)
WITH (
  OIDS=FALSE
);
ALTER TABLE queue
  OWNER TO postgres;
GRANT ALL ON TABLE queue TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE queue TO writer;
GRANT SELECT ON TABLE queue TO reader;

Это почему? Разве notification.en.incident_happened не обычная строка? Или я что-то упускаю?

UPD:

Вопрос все еще актуален, но вот обходной путь:

SQL("""select id, path::varchar, email_recipients, created_at, template_required from "queue"""")()

person Vadim Samokhin    schedule 06.02.2013    source источник
comment
Какова схема для таблицы queue?   -  person Jason Webb    schedule 24.06.2014
comment
@JasonWebb Обновил вопрос.   -  person Vadim Samokhin    schedule 25.06.2014
comment
Эта ссылка может помочь: stackoverflow.com/questions/20024357/   -  person Mandar Pandit    schedule 26.06.2014
comment
@MandarPandit, спасибо, но это всего лишь обходной путь. Корень проблемы до сих пор неясен...   -  person Vadim Samokhin    schedule 26.06.2014


Ответы (1)


Это выглядело как забавный проект, поэтому я реализовал сопоставитель столбцов ltree.

Я использовал anorm-postgresql, так как этот проект уже реализует некоторые типы postgres в anorm. Это выглядит хорошо, и было бы полезно, если бы он реализовал весь спектр типов postgres. Мой код был объединен, так что вы можете использовать эту библиотеку. В качестве альтернативы просто используйте следующий код:

import org.postgresql.util.PGobject
import anorm._
object LTree {
  implicit def rowToStringSeq: Column[Seq[String]] = Column.nonNull { (value, meta) =>
    val MetaDataItem(qualified, nullable, clazz) = meta
      value match {
        case pgo:PGobject => {
          val seq = pgo.getValue().split('.')
          Right(seq.toSeq)
        }
        case x => Left(TypeDoesNotMatch(x.getClass.toString))
      }
    }
    implicit def stringSeqToStatement = new ToStatement[Seq[String]] {
      def set(s: java.sql.PreparedStatement, index: Int, aValue: Seq[String]) {
      val stringRepresentation = aValue.mkString(".")
      val pgo:org.postgresql.util.PGobject = new org.postgresql.util.PGobject()
      pgo.setType("ltree");
      pgo.setValue( stringRepresentation );
      s.setObject(index, pgo)
    }
  }
}

Затем вы можете сопоставить ltree с Seq[String]. Обратите внимание, что это последовательность элементов пути, порядок которых имеет значение, поэтому это Seq[String], а не String или Set[String]. Если вам нужна одна строка, просто скажите path.mkString("."). Использование ниже:

import LTree._

SQL("""select * from "queue"""")()
.map(
    row =>
        {
            val queue =
                Queue(
                    row[Seq[String]]("path"),
                    row[String]("email_recipients"),
                    new DateTime(row[java.util.Date]("created_at")),
                    row[Boolean]("template_required")
                )
            queue
        }
).toList
person triggerNZ    schedule 13.08.2014