Fork me on GitHub
#clojure-russia
<
2016-08-02
>
shinych07:08:00

(переcпросил в #C03RZMDSH кому интересно)

maxim08:08:22

Кто что использует для работы с базой данных (postgresql)? Есть те, кто пишет чистый SQL (hugsql), как вы это организуете? Я создал repository namespace и там происходит mapping. Но гложет чувство, что что-то делаю не так. Или большинство предпочитает ORM (korma)? У кого какой опыт, поделитесь кому не жалко 🙂

andfadeev08:08:00

honeysql не вариант?

niwinz08:08:47

@mkaschenko: ^ (my example usage)

niwinz08:08:06

I define all sql's related stuff in one ns,and later use them from the uxbox.services namespace

maxim08:08:37

andfadeev: вариант, почему нет

andfadeev08:08:08

корму точно не советую

maxim08:08:27

а что там с кормой?

maxim08:08:16

@niwinz: у меня, примерно, так же, только еще сверху абстракция repository. А у тебя напрямую вызовы типа db/insert-project?

niwinz08:08:05

depends, I have functions in services that does access to db and other perform other kind of logic

niwinz08:08:29

later I'm using hugsql just for parsing and creating sqlvecs

niwinz08:08:42

the sql execution I'm doing with other library

niwinz08:08:30

later the http part communicate with the services with "messages" so tecnically services can be run in an other process and communicate via rabbitmq/kafka/whatever...

niwinz08:08:38

the services part hast two kind of messages: novelty and query, novelty are logged in a transaction log that can be analyzed or used for derive other materialized views (not used at this time in the app...)

niwinz08:08:11

I'm pretty happy with the current architecture but it is not silver bullet, it works for me in this case...

maxim08:08:43

That sounds interesting, thanks for the explanation.

niwinz08:08:14

this is an example of the service, it is very very simple...

maxim08:08:51

I think I've got the answer what I wanted 🙂

asolovyov09:08:47

@mkaschenko: корма заброшена, плюс она дурацкая

asolovyov09:08:19

мы юзаем honeysql и все счастливы по этому поводу; оно даж не мешает дропаться в raw, когда в ней не хватает фичи какой-то мелкой

asolovyov09:08:47

в смысле оно буквально как {:select [:u.name (sql/raw "u.password")]} выглядит

maxim09:08:55

единственное что меня немного смущало, то что я не хотел мешать чистый sql и dsl как, например, active record в rails, или в django и т.д.

comerc09:08:09

@mkaschenko: про Korma и вообще про DB познавательно - https://www.youtube.com/watch?v=kD6GyDesuCQ

maxim09:08:37

ну я изначально ORM не люблю

andfadeev09:08:43

про корму: нет смысла тащить в код описание релейшенов, это не дает никакого профита

andfadeev09:08:12

как и с любым орм теряется контроль над запросами

andfadeev09:08:27

а просто dsl как например в honeysql это неплохо, можно реюзать куски запросов и композировать запросы средствами языка (без конкатинации строк)

konukhov10:08:12

я в 2х проектах использовал honeysql + небольшой свой код для маппинга джойнов. в следующих думаю либо yesql заюзать, либо что-то подобное (чистый jdbc?), чтобы писать запросы на sql. да, на clojure круто запросы писать, но для чего-то нетривиального все равно постоянно приходится лезть в документацию и разбираться, как же на этом dsl это написать (либо raw) + компоузить (@nicola говорил, что главное преимущество, если не ошибаюсь) запросы с ней все равно неудобно.

konukhov10:08:56

с другой стороны, yesql форсит тебя, как нужно передавать параметры, а в honey можно любую структуру данных передать в метод и средствами clojure ее расфигачить по параметрам запроса.

andfadeev10:08:10

это можно решить обернув вызов уesql еще одной функцией

konukhov10:08:40

да, я так и делал, когда его пробовал

niwinz10:08:58

hugsql > yesql 😛

andfadeev10:08:13

я всеже не вижу смысла все запросы переводить в чистые sql файлы, приходится постоянно переключаться между кодом и запросами, по разному редактировать, 90проц запросов какогонить веб-приложения довольно стандартны и dsl вполне хватает

konukhov10:08:58

в репле удобнее honeysql в 100 раз, согласен

konukhov10:08:25

@niwinz: класс, не знал о ней – посмотрю

Kira Sotnikov14:08:48

Господа, чот у меня затык. Есть вот у меня на входе вот такая штука

({:instance-id "i-d881e748", :private-ip "10.0.1.4"}
 {:instance-id "i-724717f4", :private-ip "10.0.0.207"}
 {:instance-id "i-ccb1a649", :private-ip "10.0.0.204"}
 {:instance-id "i-f26b3062", :private-ip "10.0.1.193"}
 {:instance-id "i-e558947f", :private-ip "10.0.1.149"})
Потом я делаю так:
(->> (->> instances
         (map :private-ip))
         (map check-uri)
         doall)
и получаю вот такой список
("OK" "OK" nil "OK" nil)
мне надо вместо OK чтобы встали instance-id а там где нил ничего не было

Kira Sotnikov14:08:32

пробовал filter но чото никак не соображу как соорудить

Kira Sotnikov14:08:09

то есть по идее мне нужен кондишен, если на айпишник check-uri выдал Ok то записать id в список

rmuslimov14:08:35

ну filter c check-uri и результат через :instance-id

Kira Sotnikov14:08:53

а вот эту всю лесенку в фильтр засунуть получится?

rmuslimov14:08:10

(map :instance-id (filter #(-> % :private-ip check-uri) <DATA>))

rmuslimov14:08:18

как то так

Kira Sotnikov14:08:51

rmuslimov: а что значит % в данном контексте?

Kira Sotnikov14:08:54

чото в доке не найду

rmuslimov14:08:27

aргумент lambda функции

rmuslimov14:08:48

#(print %) == (fn [x] (print x))

Kira Sotnikov14:08:59

аа спасибо

Kira Sotnikov14:08:07

Вместо <DATA> моя перменная с хешмапой? правильно?

Kira Sotnikov14:08:10

user=> (get-not-healthy-ids)
("i-d881e748" user=>

Kira Sotnikov14:08:20

чото как-то не получилось

Kira Sotnikov14:08:35

(defn get-not-healthy-ids []
  (let [instances (get-instances-ec2)]

;;    (pprint instances)

    (map :instance-id
         (filter #(-> % :private-ip check-uri) instances))))

(defn check-uri [ip]
    (slurp (str "http://" ip ":3000/health-check")))

rmuslimov15:08:48

сорри, я отвлекся

rmuslimov15:08:04

(defn check-uri [ip] (= ip "10.0.1.193"))

rmuslimov15:08:13

попробуй заменить slurp вот на это

rmuslimov15:08:26

тогда сразу ясно что работает

rmuslimov15:08:34

("i-f26b3062")

rmuslimov15:08:11

вообще у тебя check-uri сейчас вернет http response

rmuslimov15:08:20

вместо булева

Kira Sotnikov15:08:51

user=> (get-not-healthy-ids) ({:instance-id "i-d881e748", :private-ip "10.0.1.4"} {:instance-id "i-724717f4", :private-ip "10.0.0.207"} {:instance-id "i-ccb1a649", :private-ip "10.0.0.204"} {:instance-id "i-f26b3062", :private-ip "10.0.1.193"} {:instance-id "i-e558947f", :private-ip "10.0.1.149"}) ("i-f26b3062")

rmuslimov15:08:07

следовательно проверь check-uri

rmuslimov15:08:21

оно должно вернуть true/false

Kira Sotnikov15:08:23

user=> (true? (check-uri "10.0.1.4")) false

Kira Sotnikov15:08:30

похоже криво чек айпи )

Kira Sotnikov15:08:07

user=> (check-uri "10.0.1.193")
true

Kira Sotnikov15:08:51

user=> (check-uri "10.0.1.149")
user=>

Kira Sotnikov15:08:55

а где фолс?

Kira Sotnikov15:08:57

похоже slurp надо менять на что-то где можно получить код респонса

rustam.gilaztdinov16:08:11

Товарищи, подскажите — есть задача — беру данные из редиса, как pub/sub, дальше надо достать нужные поля и положить в dynamodb в связке с titandb. БД графовая, соотвественно надо либо дописать связей к существующей вершине, либо создать новую. Для всех баз обертки нашел, дальше вот думаю — может написать макрос, чтобы завернуть все это дело в него или лучше подойдет какое другое решение для таких случаев? Макрос кажется хорошей идеей, но вот может кто примером поможет? В кложе начинающий, выпала возможность впилить ее в проект, руки чешутся)

misha16:08:07

(defn healthy? [m]
  (-> m :private-ip (clojure.string/starts-with? "10.0.1.")))

(defn healthy-ids [mm]
  (->> mm
    (filter healthy?)
    (map :instance-id)))

(healthy-ids
  [{:instance-id "i-d881e748", :private-ip "10.0.1.4"}
   {:instance-id "i-724717f4", :private-ip "10.0.0.207"}
   {:instance-id "i-ccb1a649", :private-ip "10.0.0.204"}
   {:instance-id "i-f26b3062", :private-ip "10.0.1.193"}
   {:instance-id "i-e558947f", :private-ip "10.0.1.149"}])
=>>
("i-d881e748" "i-f26b3062" "i-e558947f")
@lowl4tency

misha17:08:17

@potapenko: как она на девайсе себя чувствует? и на каком?

potapenko17:08:35

еще не пробовал

misha17:08:49

kappa расскажешь

misha17:08:26

много реакт нейтив модулей? (которые в obj c)

potapenko17:08:47

"react": "15.2.0",
    "react-native": "^0.30.0",
    "react-native-animatable": "^0.6.1",
    "react-native-device-info": "^0.9.3",
    "react-native-drawer": "^2.2.4",
    "react-native-fbsdk": "^0.3.0",
    "react-native-fcm": "^1.0.9",
    "react-native-fs": "^1.5.1",
    "react-native-simple-router": "^0.10.0",
    "react-native-swipe-list-view": "^0.2.2",
    "react-native-vector-icons": "^2.0.3",
    "react-native-video": "^0.8.0"

potapenko17:08:15

drawer кстати не пригодился

potapenko17:08:17

нужно убрать

misha17:08:37

а, ну должно быть ок, наверное (или "можно сделать ок")

misha17:08:54

а код страшный? js много?

potapenko17:08:27

у меня нету js

potapenko17:08:32

только clojure

misha17:08:37

ну интеропа

potapenko17:08:56

ну модули вывереные не на одном проекте

misha17:08:01

или для всего макросов ре-натальных хватило обернуть?

potapenko17:08:02

не должно быть сложности с ними

potapenko17:08:12

да, ренатала хватило

potapenko17:08:20

я даже re-frame не использовал

potapenko17:08:27

тупо атомы и reaction

misha17:08:31

ну ты на девайсе всё равно посмотри, будет ли всё бодренько.

potapenko17:08:54

проблема со списками образовалась

potapenko17:08:56

когда большие

potapenko17:08:16

пришлось высчислять какая линия (словосочетание) у меня видима

potapenko17:08:24

решил тупо подсчетом позиции скрола

potapenko17:08:43

там много жрало ресурсов до

potapenko17:08:48

пофиксил - стало летать

potapenko17:08:38

(defn visible-helper
  ([index content] (visible-helper key content [view]))
  ([index content not-visible]
   (let [start-visible-index (dec (/ @phrases-scroll-pos 45))
         end-visible-index (+ start-visible-index 10)]
     (if (and (>= index start-visible-index)
              (<= index end-visible-index)) content not-visible))))

такая хрень для ячеек

potapenko17:08:00

потом

(defn phrase-row-front
  [row-data]
  [view {:style [(height 45)]}
   [visible-helper
    (line-index row-data)
    [phrase-row-front-visible row-data]
    [phrase-row-front-not-visible row-data]
    ]]

  )

potapenko17:08:14

указываю видимая или невидимая

potapenko17:08:24

45 пискселей высота ячейки

potapenko17:08:39

initialListSize не

potapenko17:08:41

не катит

misha17:08:42

типа ячейки все рисуешь, но невидимые - пустыми?

potapenko17:08:50

ну да, гдето-тоа

potapenko17:08:53

где-то так

potapenko17:08:10

главное чтобы атомов и подписок на данные внутри ячеек когда невидимые не было

potapenko17:08:32

ибо 1200 ячеек ждущих когда отработает атом @selected-line это еще та веселуха

misha17:08:49

ага, я такое уже проходил kappa

potapenko17:08:07

а так стандартно все

potapenko17:08:51

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

misha17:08:47

удивился бы, если бы так нельзя было сделать

potapenko17:08:54

еще есть onChangeVisibleRows - но он у меня не работал правильно

potapenko17:08:08

я сделал красивый код который видимость из него вычисляет

potapenko17:08:18

но он почему-то работает только с ячейками, которые вначале, если изменить initiallistsize, то норм…. но так инициализация большого списка занимает десяток секунд, а то и больше.

misha17:08:19

хотя я тут перебирал charting библиотеки, топ 2 не умели строить time series чарты, где грубо говоря по ox - разное расстояние между точками. в итоге я стал меньше удивляться всякому

potapenko17:08:21

баг или я не понял

misha17:08:31

я пока очень длинные листы не рендерил, так что еще не совсем прощупал где что работает, а где нет

Kira Sotnikov20:08:47

misha: спасибо выглядит понятнее )