Re[3]: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 20.01.14 03:24
Оценка:
avpavlov,

A>В Скала намного больше мета-информации доступно, и то к ЛИНКу даже близко не приблизились. Правда макросы сейчас пилят, вот на макросах уже можно будет ЛИНК сделать.


Твои сведения либо сильно искажены, либо устарели. Typesafe Slick полностью повторяет Linq, а в версии 2.0 идëт намного дальше в сторону NoSql баз данных.

Макросы позволяют более эффективно генерировать запросы и выдавать более человеческие ошибки (т.н. direct query Api), функционал же доступен уже сейчас через lifted api.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[4]: LINQ для Java
От: avpavlov  
Дата: 20.01.14 04:39
Оценка:
LCR>Твои сведения либо сильно искажены, либо устарели. Typesafe Slick полностью повторяет Linq,

Либо ты смотришь через розовые очки

Сравним

LIN2SQL — обрати внимание, компилятор подтянул имена CompanyName и Phone в кортеж, поэтому нам не надо помнить, что там первое, что второе

var q =
from c in db.Customers
where c.City == "London"
select new { c.CompanyName, c.Phone };
foreach(var c in q)
Console.WriteLine("{0}, {1}", c.CompanyName, c.Phone);


Slick — старые добрые _1 и _2

// Perform a join to retrieve coffee names and supplier names for
    // all coffees costing less than $9.00
    println("Manual join:")
    val q2 = for {
      c <- coffees if c.price < 9.0
      s <- suppliers if s.id === c.supID
    } yield (c.name, s.name)
    for(t <- q2) println("  " + t._1 + " supplied by " + t._2)


Ну и синтаксис у Линка куда ближе к реальному СКЛ, чем у Слика
Re[5]: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 21.01.14 08:05
Оценка:
avpavlov,

LCR>>Твои сведения либо сильно искажены, либо устарели. Typesafe Slick полностью повторяет Linq,

A>Либо ты смотришь через розовые очки

Возможно.

A>Сравним

A>LIN2SQL — обрати внимание, компилятор подтянул имена CompanyName и Phone в кортеж, поэтому нам не надо помнить, что там первое, что второе

Во-первых. Компилятор C# конечно молодец, однако всё что здесь делается — это используется анонимный тип с именованными полями.
Аналог в Скала тоже можно нарисовать при желании:
    case class Supply(coffeeName: String, supplierName: String)

    // Perform a join to retrieve coffee names and supplier names for
    // all coffees costing less than $9.00
    println("Manual join:")
    val q2 = for {
      c <- coffees if c.price < 9.0
      s <- suppliers if s.id === c.supID
    } yield Supply(c.name, s.name)
    for(t <- q2) println("  " + t.coffeeName + " supplied by " + t.supplierName)


Во-вторых, речь шла о захвате AST (в терминологии Expression Tree) и генерации по нему SQL инструкций. И утверждалось, что де Скала даже близко не стоит. Ответ — стоит, и даже умеет кое-что большее.

A>Ну и синтаксис у Линка куда ближе к реальному СКЛ, чем у Слика

Это необязательное требование Linq, более того спорное — Linq-выражения выглядят чуждо, интеллисенс на них работает криво и многим это не нравится. Исключительно синтаксический сахар.
В Скала такой сахар отсутствует (точнее никому не потребовалось его изобретать), но с другой стороны, в Скала не потребовались и спец. костыли для поддержки нового синтаксиса, а вся работа делается на привычном и поддерживаемом синтаксисе.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[6]: LINQ для Java
От: dimgel Россия https://github.com/dimgel
Дата: 21.01.14 08:11
Оценка: +1
Здравствуйте, lazy-cjow-rhrr, Вы писали:

A>>Ну и синтаксис у Линка куда ближе к реальному СКЛ, чем у Слика

LCR>Это необязательное требование Linq, более того спорное — Linq-выражения выглядят чуждо, интеллисенс на них работает криво и многим это не нравится. Исключительно синтаксический сахар.
LCR>В Скала такой сахар отсутствует (точнее никому не потребовалось его изобретать), но с другой стороны, в Скала не потребовались и спец. костыли для поддержки нового синтаксиса, а вся работа делается на привычном и поддерживаемом синтаксисе.

Slick идёт нафиг не в последнюю очередь как раз из-за синтаксиса: переформулировать простейший group by на for comprehensions — да ну его нафиг. А уж если что посложнее приспичит...
Re[6]: LINQ для Java
От: avpavlov  
Дата: 21.01.14 08:21
Оценка:
Здравствуйте, lazy-cjow-rhrr, Вы писали:

LCR>Во-первых. Компилятор C# конечно молодец, однако всё что здесь делается — это используется анонимный тип с именованными полями.

LCR>Аналог в Скала тоже можно нарисовать при желании:

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

LCR>
LCR>    case class Supply(coffeeName: String, supplierName: String)
LCR>    } yield Supply(c.name, s.address)
LCR>    for(t <- q2) println("  " + t.coffeeName + " supplied by " + t.supplierName)
LCR>


См. выделенное. Я исправил, а Скала и не заметила, а ЛИНК даст компайл-тайм еррор и заставит меня убедиться, что логика приложения не нарушена

LCR>Во-вторых, речь шла о захвате AST (в терминологии Expression Tree) и генерации по нему SQL инструкций. И утверждалось, что де Скала даже близко не стоит. Ответ — стоит, и даже умеет кое-что большее.


Нет, утверждалось что без макросов не стоит. С макросами стоит, но это ещё мало где с умом прикручено.

LCR>Это необязательное требование Linq, более того спорное — Linq-выражения выглядят чуждо, интеллисенс на них работает криво и многим это не нравится. Исключительно синтаксический сахар.


А мне нравится синтаксис SQL
Re[7]: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 21.01.14 09:02
Оценка:
avpavlov,

LCR>>Во-первых. Компилятор C# конечно молодец, однако всё что здесь делается — это используется анонимный тип с именованными полями.

LCR>>Аналог в Скала тоже можно нарисовать при желании:

A>Не, это не аналог. Это рисование нового класса для каждого кортежа. Линк делает тоже самое, но за сценой и не заставляет программиста об этом думать.


Классы моделей в любом случае нужны, и их можно (и нужно) здесь использовать. Анонимные классы в C# имеют помимо указанных тобой достоинств и ряд недостатков и ограничений, так что предпочтительнее использовать нормальные классы.

LCR>>    case class Supply(coffeeName: String, supplierName: String)
LCR>>    } yield Supply(c.name, s.address)
LCR>>    for(t <- q2) println("  " + t.coffeeName + " supplied by " + t.supplierName)

A>См. выделенное. Я исправил, а Скала и не заметила, а ЛИНК даст компайл-тайм еррор и заставит меня убедиться, что логика приложения не нарушена

Что-то, аргументация несколько однобокая и неубедительная. Попробуй сейчас не заметить:
    } yield Supply(coffeeName = c.name, supplierName = s.address)


Совершенно аналогично ты и в конструктор анонимного типа можешь передать неправильное значение (случай 1). Скажешь, не было?
new {CoffeeName = c.Name, SupplierName = s.Address} // 1
new {c.Name, s.Address} // 2

Есть определённое преимущество у C# в случае (2). По мне, так весьма частный случай, когда нам не нужно использовать модели (почему-то). Обычно всё-таки создавать модели нужно.

LCR>>Во-вторых, речь шла о захвате AST (в терминологии Expression Tree) и генерации по нему SQL инструкций. И утверждалось, что де Скала даже близко не стоит. Ответ — стоит, и даже умеет кое-что большее.


A>Нет, утверждалось что без макросов не стоит. С макросами стоит, но это ещё мало где с умом прикручено.


Синтаксический сахар необязателен. Что-то ещё?

A>А мне нравится синтаксис SQL

На здоровье. Мне — нравятся HOF.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[8]: LINQ для Java
От: avpavlov  
Дата: 21.01.14 09:11
Оценка:
LCR>Что-то, аргументация несколько однобокая и неубедительная. Попробуй сейчас не заметить:
LCR>
LCR>    } yield Supply(coffeeName = c.name, supplierName = s.address)
LCR>


ЧТД. Требуется вводить coding rules и следить, чтобы их все соблюдали, вместо перекладывания на компилятор.

LCR>Совершенно аналогично ты и в конструктор анонимного типа можешь передать неправильное значение (случай 1). Скажешь, не было?

LCR>new {CoffeeName = c.Name, SupplierName = s.Address} // 1

ЧТД. Если использование ЛИНКА намеренно ухудшить, то получится как в Скале

LCR>Синтаксический сахар необязателен. Что-то ещё?


Если синтаксический сахар необязателен, то вообще вся эта тема не нужна и непонятно зачем ты в неё влез. Работу с базой делали ещё на Коболе 50 лет назад и не жужжали.

A>>А мне нравится синтаксис SQL

LCR>На здоровье. Мне — нравятся HOF.

Вот и разработчикам библиотек для Скала нравится. Из-за этого так и будем иметь на выходе УГ, пока за разработку не возьмётся человек, которому нравится SQL
Re[7]: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 21.01.14 09:15
Оценка:
dimgel,

D>Slick идёт нафиг не в последнюю очередь как раз из-за синтаксиса: переформулировать простейший group by на for comprehensions — да ну его нафиг. А уж если что посложнее приспичит...


А что не так? Работаешь с таблицами как с массивами и в ус не дуешь — интеллисенс и типобезопасность в комплекте
session.withTransaction {
  // seek for the jobs that have specified status and earlier than lowerBound and select the oldest one
  val jobsOpt = Query(schema.Jobs)
    .filter(_.status === status)
    .filter(_.isDeleted === Active.value)
    .filter(_.fireTime <= lowerBound)
    // .sortBy(_.fireTime.desc) -- newer jobs are higher
    .sortBy(_.fireTime).firstOption
  if (jobsOpt.isDefined) {
    val job: Job = jobsOpt.get
    val jobId = job.id.get
    logger.debug(s"Job (id = $jobId) is selected to acquire")
    // try to aquire it
    val n = schema.Jobs.filter(_.id === jobId).update(job.copy(status = Status.next(status)))
    if (n > 0) {
      logger.debug(s"Job (id = $jobId) is acquired for processing")
      selectByWithDeps(jobId)
    } else {
      logger.debug(s"Job (id = $jobId) is failed to acquire")
      None
    }
  } else None
}

Если конечно у человека в прошлом опыт DBA, то тут да, будут сложности. Ну в этом случае ждите макросов, чё.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[8]: LINQ для Java
От: dimgel Россия https://github.com/dimgel
Дата: 21.01.14 09:15
Оценка:
Здравствуйте, lazy-cjow-rhrr, Вы писали:

A>>А мне нравится синтаксис SQL

LCR>На здоровье. Мне — нравятся HOF.

Вы оба не правы, а вот мне нравится, когда поменьше разных синтаксисов, так что если SQL — необсуждаемая данность, которой частенько приходится пользоваться для ковыряния в потрохах базы, то забивать себе башку ещё одним диалектом, через зад в этот SQL компилирующимся — довольно глупо.
Re[9]: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 21.01.14 09:22
Оценка:
avpavlov, Вы писали:

A>Если синтаксический сахар необязателен, то вообще вся эта тема не нужна и непонятно зачем ты в неё влез. Работу с базой делали ещё на Коболе 50 лет назад и не жужжали.


Ценность и польза Linq вообще не в синтаксическом сахаре. И Кобол тут непричём.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[8]: LINQ для Java
От: dimgel Россия https://github.com/dimgel
Дата: 21.01.14 09:26
Оценка: 14 (1) +1
Здравствуйте, lazy-cjow-rhrr, Вы писали:

LCR>dimgel,


D>>Slick идёт нафиг не в последнюю очередь как раз из-за синтаксиса: переформулировать простейший group by на for comprehensions — да ну его нафиг. А уж если что посложнее приспичит...


LCR>А что не так? Работаешь с таблицами как с массивами и в ус не дуешь — интеллисенс и типобезопасность в комплекте


Не так то, что мне частенько приходилось нарываться на ситуации, когда два логически эквивалентных запроса, сформулированных через join и через вложенный подзапрос, дают ОООЧЕНЬ разную эффективность. Мне также приходилось заниматься оптимизацией постгреса на огромной базе, разбивая сложные запросы на сотню маленьких медведей с использованием временных промежуточных таблиц, потому что эта дрянь убей бог не хотела давать мне нужный план. И по итогам всего этого суммарно-многолетнего секса я предпочитаю иметь ПОЛНЫЙ контроль над видом генерируемого SQL, что естественным образом достигается только если статически типизированный язык запросов имеет близкий к SQL синтаксис, а не является очередным <матерно>paradigm mismatch bridge</матерно>.
Re[9]: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 21.01.14 10:30
Оценка:
dimgel,

LCR>>А что не так? Работаешь с таблицами как с массивами и в ус не дуешь — интеллисенс и типобезопасность в комплекте


D>Не так то, что мне частенько приходилось нарываться на ситуации, когда два логически эквивалентных запроса, сформулированных через join и через вложенный подзапрос, дают ОООЧЕНЬ разную эффективность. Мне также приходилось заниматься оптимизацией постгреса на огромной базе, разбивая сложные запросы на сотню маленьких медведей с использованием временных промежуточных таблиц, потому что эта дрянь убей бог не хотела давать мне нужный план. И по итогам всего этого суммарно-многолетнего секса я предпочитаю иметь ПОЛНЫЙ контроль над видом генерируемого SQL, что естественным образом достигается только если статически типизированный язык запросов имеет близкий к SQL синтаксис, а не является очередным <матерно>paradigm mismatch bridge</матерно>.


Цена абстракции-с. Зато типобезопасность, блэкджек и шлюхи, а для большой и чистой любви есть другие места.

Понятненько, спасибо за коммент, я такие вещи особенно люблю (в смысле вербализованный опыт коллег) Конечно, в твоём случае придётся использовать либо прямое исполнение SQL (в Slick тоже есть, но типобезопасность накрывается медным тазом), либо какой-нибудь примитивный враппер типа Anorm (или myBatis). Чтобы иметь полный контроль над сиквелем, генерируемом думателем (что Linq, что Slick), нужно частенько погружаться в кодяру и держать руку на пульсе логов. По виду Customers.First().CustomerOrders.SelectMany(item => item.Orders) невозможно догадаться, что эта строчка порождает кучу запросов вместо одного. Только либо знать, либо увидеть собственными глазами.

Я по своей воле тщательно избегал чересчур плотного погружения в SQL, дебри планов, повадки оптимизаторов и прочей хрени. Но однажды эта участь таки меня настигла — я примерно на 4.5 года вынужден был основательно потра...подружиться с мускулем и мелкософтовским сервером. Это был безусловно полезный и нужный опыт, я много подчерпнул для себя полезного. Но он (опыт) отложил отпечаток — с тех пор я стараюсь держать DAO слой как можно проще, пусть даже ценой какого-то ухудшения перфоманса в некритических местах. Потому что жизнь одна, а субдей много, и в каждой ещё по выводку тараканов. А ежели DAO простой как три копейки, то и возможностей что Linq, что Slick хватает с избытком. Лично я Slick, за вычетом ряда раздражающих неудобств, полностью доволен.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[10]: LINQ для Java
От: dimgel Россия https://github.com/dimgel
Дата: 21.01.14 10:50
Оценка:
Здравствуйте, lazy-cjow-rhrr, Вы писали:

LCR>Цена абстракции-с. Зато типобезопасность,


Типобезопасность тут ортогональна, её и squeryl обеспечивает, который гораздо ближе к SQL, чем Slick. И точно такой же синтаксис можно на макросах обеспечить.

LCR>блэкджек и шлюхи,


Да вот что-то не видать. Сложный запрос запаришься формулировать. Разве что если работать с базой как с плоским хранилищем, то да, наверное стандартными scala-циклами удобнее.

LCR>А ежели DAO простой как три копейки, то и возможностей что Linq, что Slick хватает с избытком.


Во-во, ну а я привык в духе anemic — оптимизированная загрузка данных достаточно развесистыми запросами.
Re: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 22.01.14 18:13
Оценка: 8 (1)
Аноним,

А>Наткнулся тут на статью по этому поводу.

А>Кто что думает по этому поводу?
А>А там есть упоминание вот этого.

Внезапно появилась новая библиотека для Scala, которая сильно использует макросовскую магию и реализует типобезопасные SQL-и, которые выглядят прямо как родные:
object Product {
  def create(name: String, price: Long)(implicit s: DBSession = AutoSession): Long = {
    sql"insert into products values (${name}, ${price})" // don't worry, it prevents SQL injection!
      .updateAndReturnGeneratedKey.apply() // returns auto-incremeneted id
  }

  def findById(id: Long)(implicit s: DBSession = AutoSession): Option[Product] = {
    sql"select id, name, price, created_at from products where id = ${id}"
      .map { rs => Product(rs) }.single.apply()
  }
}

Product.findById(123) // borrows connection from pool and gives it back after execution


Встречайте: http://scalikejdbc.org/
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: LINQ для Java
От: lazy-cjow-rhrr Россия lj://_lcr_
Дата: 22.01.14 18:19
Оценка: 8 (1)
LCR>Внезапно появилась новая библиотека для Scala, которая сильно использует макросовскую магию и реализует типобезопасные SQL-и, которые выглядят прямо как родные:

Да, а вот магия
  withSQL {
    select
      .from(Programmer as p)
      .leftJoin(Company as c).on(p.companyId, c.id)
      .where.eq(p.isDeleted, false)
      .orderBy(p.createdAt)
      .limit(10)
      .offset(0)
  }.map(Programmer(p, c)).list.apply()


Ваще красота.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[3]: LINQ для Java
От: dimgel Россия https://github.com/dimgel
Дата: 22.01.14 19:29
Оценка:
Здравствуйте, lazy-cjow-rhrr, Вы писали:

LCR>>Внезапно появилась новая библиотека для Scala, которая сильно использует макросовскую магию и реализует типобезопасные SQL-и, которые выглядят прямо как родные:

LCR>Да, а вот магия

Блин, опередили, окаянные.
Re[3]: LINQ для Java
От: avpavlov  
Дата: 23.01.14 12:03
Оценка:
Здравствуйте, lazy-cjow-rhrr, Вы писали:


LCR>>Внезапно появилась новая библиотека для Scala, которая сильно использует макросовскую магию и реализует типобезопасные SQL-и, которые выглядят прямо как родные:


LCR>Да, а вот магия

LCR>
LCR>  withSQL {
LCR>    select
LCR>      .from(Programmer as p)
LCR>      .leftJoin(Company as c).on(p.companyId, c.id)
LCR>      .where.eq(p.isDeleted, false)
LCR>      .orderBy(p.createdAt)
LCR>      .limit(10)
LCR>      .offset(0)
LCR>  }.map(Programmer(p, c)).list.apply()
LCR>


LCR>Ваще красота.


Ну не знаю. Мне, кажется, макросы [должны быть] способны на большее. В примеру выше почти всё можно было и без макросов сделать. Только алиасы да проперти бинов. Причём в отсутствие макросов от пропертей можно было бы отказаться и сделать из них дескрипторы колонок, тогда только алиасы бы нереализованными остались.
Re[4]: LINQ для Java
От: avpavlov  
Дата: 23.01.14 12:04
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Здравствуйте, lazy-cjow-rhrr, Вы писали:


LCR>>>Внезапно появилась новая библиотека для Scala, которая сильно использует макросовскую магию и реализует типобезопасные SQL-и, которые выглядят прямо как родные:

LCR>>Да, а вот магия

D>Блин, опередили, окаянные.


Если ты хотел что-то написать, то пиши. Они ещё никого не опередили
Re[2]: LINQ для Java
От: avpavlov  
Дата: 23.01.14 12:05
Оценка:
LCR> sql"select id, name, price, created_at from products where id = ${id}"

А здесь внутри СКЛных строк компайл-тайм проверка или нет?
Re[5]: LINQ для Java
От: dimgel Россия https://github.com/dimgel
Дата: 23.01.14 12:19
Оценка:
Здравствуйте, avpavlov, Вы писали:

D>>Блин, опередили, окаянные.


A>Если ты хотел что-то написать, то пиши. Они ещё никого не опередили


Пишу и буду писать. Чужим фреймворкам в таких тонких вопросах доверять нельзя, это я уже понял. К тому же вряд ли у них есть поддержка prepared statements и компиляции императивного кода в хранимки.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.