Upgrade to Pro — share decks privately, control downloads, hide ads and more …

github.com/pinzolo/sqlt

3140de70ab04d8f9fc979447b0b4fb16?s=47 pinzolo
January 18, 2019

 github.com/pinzolo/sqlt

3140de70ab04d8f9fc979447b0b4fb16?s=128

pinzolo

January 18, 2019
Tweet

Transcript

  1. github.com/ pinzolo/sqlt

  2. $ whoami • NODA Masato • @pinzolo • Go ͸ϓϥΠϕʔτͰ࢖͍࢝Ίͯ2೥͙

    Β͍ • SQL͸ࣗ෼Ͱ௚઀ॻ͖͍ͨ੎
  3. sqltͱ͸ text/template Λϕʔεʹͯ͠࡞੒ͨ͠ 2way SQL ϥΠϒϥ Ϧ

  4. 2way SQL ͬͯʁ • ΫΤϦϏϧμͷҰछ • ςϯϓϨʔτʹରͯ͠ύϥϝʔλΛ౉ͯ͠SQLΛੜ੒͢Δ • ςϯϓϨʔτࣗମ͕࣮ߦͰ͖ΔSQLͰ͋Δ

  5. 2way SQL ͬͯʁ • ΫΤϦϏϧμͷҰछ • ςϯϓϨʔτʹରͯ͠ύϥϝʔλΛ౉ͯ͠SQLΛੜ੒͢Δ • ςϯϓϨʔτࣗମ͕࣮ߦͰ͖ΔSQLͰ͋Δ <-

    ࠷େͷಛ௃
  6. ͜Μͳ΍ͭ ex: Doma SELECT * FROM item WHERE status =

    'AVAILABLE' /*%if name != null*/ AND name = /*name*/'John Doe' /*%end*/
  7. 2way SQL ࣗମͷϝϦ οτɾσϝϦοτ΍ ORM ࿦૪͸͜͜Ͱ͸ׂѪ

  8. None
  9. ͳͥ text/template ϕʔεͰ࡞Ζ͏ͱࢥͬͨ ͷ͔ʁ

  10. ָ͔͔ͨͬͨ͠Β

  11. text/template Λ࢖͏ͱ if range ͱ੍͍ͬͨޚߏจ͕ఏڙ͞Ε͓ͯΓɺeq ne and or ͳͲͷ΄΅ if

    ʹඞਢͳॲཧ΋࠷࣮૷ͷඞཁ͕ແ͍
  12. text/template Λ࢖͏ͱ template.FuncMap ܦ༝ͰςϯϓϨʔτ಺Ͱ࢖͑Δؔ਺Λొ࿥ Ͱ͖ΔͷͰɺSQLʹؔ͢Δ૊ΈࠐΈؔ਺΍ϓϩδΣΫτຖͷศརؔ ਺ͷొ࿥͕༰қ

  13. text/template Λ࢖͏ͱ ύϑΥʔϚϯε໰୊ΛຊՈʹͿΜ౤͛ΒΕΔɻ ʢͨͩ͠ɺ౰વࣗ෼ͰScannerΛॻ͍ͨํ͕ΑΓߴੑೳͳ΋ͷʹ ͸ͳΔʣ

  14. ϝϦοτଟ͍

  15. (ςϯϓϨʔτݴޠΛ࢖ͬͯςϯϓϨʔτݴޠΛ࡞ΔΜ͔ͩΒ େ఍͕ྲྀ༻Ͱ͖ͯ౰ͨΓલͳͷ͚ͩͲ)

  16. None
  17. Sample code SQL SELECT * FROM users WHERE id IN

    /*% in "ids" %*/(1, 2) AND name = /*% p "name" %*/'John Doe' /*%- if get "onlyMale" %*/ AND sex = 'MALE' /*%- end %*/ ORDER BY /*% out "order" %*/id
  18. Sample code Go st := sqlt.New(sqlt.Postgres) query, args, err :=

    st.Exec(s, map[string]interface{}{ "ids": []int{1, 2, 3}, "order": "name DESC", "onlyMale": false, "name": "Alex", })
  19. Sample code Generated SQL SELECT * FROM users WHERE id

    IN ($1, $2, $3) AND name = $4 ORDER BY name DESC
  20. Sample code Generated SQL (ExecNamed) SELECT * FROM users WHERE

    id IN (:ids__1, :ids__2, :ids__3) AND name = :name ORDER BY name DESC
  21. Sample code Generated SQL (Annotation Option) SELECT * FROM users

    WHERE id IN ($1, $2, $3)/*# ids */ AND name = $4/*# name */ ORDER BY name DESC
  22. ͳͥ text/template Λ༻͍ͯ͜Μͳ͜ͱ͕ग़ དྷΔͷ͔ʁ

  23. sqlt Λ࣮ݱ͍ͯ͠Δೋͭͷൃ૝ 1.Template.Delims ʹΑΔ SQL ϑϨϯυϦʔͳσϦϛλ 2.ؔ਺Ͱ͸ͳ͘ϝιουΛ FuncMap ʹొ࿥ͯ͠෭࡞༻Λར༻͢ Δ

  24. Template.Delims ຊདྷ {{ ͱ }} Ͱ͋Δ text/template ͷσϦϛλΛมߋ͢Δ ػೳɻ ͜ΕΛ

    /*% ͱ %*/ ͱ͍͏SQLʹͱͬͯ͸ίϝϯτͰ͋Δจࣈʹ มߋ͍ͯ͠ΔͷͰɺςϯϓϨʔτͷ֤छ໋ྩΛແಟԽ͍ͯ͠Δɻ
  25. ϝιουͷ෭࡞༻ར༻ FuncMap ʹొ࿥͢Δؔ਺Λ७ਮͳؔ਺Ͱ͸ͳ͘ɺಛఆͷΠϯελ ϯεʹॴଐ͢Δϝιουʹ͢Δ͜ͱʹΑͬͯεϨουϩʔΧϧͳ෭ ࡞༻Λར༻Ͱ͖Δɻ ͓΋ʹςϯϓϨʔτʹ౉͞Εͨύϥϝʔλ͔ΒɺSQL࣮ߦʹඞཁͳ ύϥϝʔλΛ࡞੒͢ΔͨΊʹར༻͍ͯ͠Δɻ

  26. ྫ1ʣύϥϝʔλͷ໾ׂ໰୊ SELECT * FROM users WHERE name LIKE /*% infix

    "name" %*/'John Doe' /*% if get "available" %*/ AND status = /*% in "stats" %*/(NULL) /*% end %*/ /*% if get "email" %*/ AND email = /*% p "email" %*/'foo@example.com' /*% end %*/
  27. ྫ1ʣύϥϝʔλͷ໾ׂ໰୊ 1.SQL࣮ߦ࣌ʹඞཁͳύϥϝʔλʢnameʣ 2.SQLߏங࣌ʹඞཁͳύϥϝʔλ(available) 3.྆ํʹඞཁͳύϥϝʔλʢemailʣ 4.ಛఆͷ৚݅࣌ʹඞཁͳύϥϝʔλʢstatsʣ ͜ͷ͏ͪɺ࣮ߦ࣌ʹ͸ 2 ΍৚݅ʹΑͬͯ͸ 4 Λഉআ͍ͨ͠

  28. ྫ2ʣIN ۟ʹ͓͚ΔεϥΠεͷల։ ΄ͱΜͲͷ database/sql ͷυϥΠό͸ WHERE id IN $1 ʹ

    ରͯ͠εϥΠεΛ౉ͯ͠΋ల։͠ͳ͍ɻ
  29. ྫ3ʣΤεέʔϓॲཧͨ͠ύϥϝʔλ͕ ඞཁ SELECT id , name , name = /*%

    out "name" %*/'John' AS matched FROM users WHERE name LIKE /*% infix "name" %*/'John' ORDER BY matched DESC, name
  30. ྫ3ʣΤεέʔϓॲཧͨ͠ύϥϝʔλ͕ ඞཁ ಉ͡ name ύϥϝʔλΛར༻͍ͯ͠Δ͕ɺ1ͭΊ͸ͦͷ··Ͱ͍ ͍ͷʹର͠ɺ2ͭΊ͸ LIKE ͷର৅ʹ͢ΔͨΊ % ΍

    _ ΛΤεέ ʔϓͨ͠஋͕ඞཁɻ
  31. None
  32. sqltͰղܾͰ͖Δ͜ͱ

  33. 1.SQLΛผϑΝΠϧͰ؅ཧͰ͖Δ 2.2way-SQLͳͷͰςετ͠΍͍͢ 3.Pure SQL ͳͷͰπʔϧͷԸܙΛड͚΍͍͢ 4.ύϥϝʔλʹ໊લΛ෇͚ΒΕΔ 5.in, suffix, prefix ͷΑ͏ͳ

    SQL ઐ༻ؔ਺ʹΑΓແବͳ ॲཧΛආ͚ΒΕΔ 6.DBͷҧ͍ΛSQLͷத͚ͩʹด͡ࠐΊ΍͍͢
  34. sqlt͕ղܾ࢓੾Εͳ͔ ͬͨ͜ͱ

  35. SQLΠϯδΣΫγϣϯ

  36. ࢒೦ͳ͕Β type Form struct { Name string } st :=

    sqlt.New(sqlt.Postgres) query, args, err := st.Exec(s, map[string]interface{}{ "form": Form{Name: "' OR 1 = 1;"}, })
  37. ͜Μͳίʔυ͕ SELECT * FROM users /*%- $f := get "form"

    %*/ WHERE name = '/*% $f.Name %*/'
  38. ͔͚ͯ͠·͏ SELECT * FROM users WHERE name = '' OR

    1 = 1;
  39. range Ͱ΋ type V struct { Value string } st

    := sqlt.New(sqlt.Postgres) query, args, err := st.Exec(s, map[string]interface{}{ "values": []V{ V{"' OR 1 = 1;"}, V{"foo"}, V{"bar"}, }, })
  40. ॻ͚ͯ͠·͏ SELECT * FROM users WHERE ( /*%- range $i,

    $v := get "values" %*/ /*%- if ne $i 0 %*/ OR /*% end %*/ name = '/*% $v.Value %*/' /*%- end %*/ )
  41. ͪͳΈʹ SELECT * FROM users WHERE ( /*%- range $i,

    $v := get "values" %*/ /*%- if ne $i 0 %*/ OR /*% end %*/ name = /*% p (name "values" $i "Value") %*/'' /*%- end %*/ ) ҆શʹॻ͘ํ๏͸ఏڙ͍ͯ͠Δɻ
  42. σϑΥϧτͷຒΊࠐΈॲཧʹରͯ͋͠·Γʹ΋ແྗͳͷͰɺҰ࣌ม ਺Λܦ༝͢Δ͚ͩͰ͍͘ΒͰ΋SQLΠϯδΣΫγϣϯΛ࢓ࠐΊͯ͠ ·͏ɻ σϑΥϧτͷຒΊࠐΈॲཧʹ hook Λॻ͚ͨΓ͢Δ͜ͱ͕ग़དྷΔ ͳΒରࡦ͸Ͱ͖Δͷ͕ͩɺͦΜͳ͜ͱ͕ग़དྷΔͳΒ͓ͦΒ͘ html/template ͳΜͯଘࡏ͍ͯ͠ͳ͍ɻ

  43. ࢖͑Δͷʁ • ϨϏϡʔ͕͔ͬ͠ΓճΔ • Θ͔͍ͬͯΔਓ͚ͩ • ݸਓϓϩμΫτ ʹ͸࢖͑ͳ͍͜ͱ΋ͳ͍͔΋͠Εͳ͘΋ͳ͍ɻੵۃతʹ͓͢͢Ί͸ ͠ͳ͍ɻ ʢࣗ෼͕࢖͏෼ʹ͸͜ΕͰ΋·͍͍͔͋ͱ΋ࢥͬͯΔʣ

  44. Կ͕͍͚ͳ͔ͬͨͷ͔ʁ • 7ʙ8ׂͷػೳΛຬͨ͢ͱ͍͏ϝϦοτΛ༏ઌ͗ͨ͢͠ • Ұ൪େࣄͳͱ͜ΖΛ֎͞ͳ͍ͱ͍͏ߟ͑Λ༏ઌ͢΂͖ • ָʹղܾͰ͖Δ͜ͱ͸୭͔͕ղܾ͍ͯ͠Δ • ͍͟ͱ͍͏ͱ͖ʹ௿Ϩϕϧ෦෼ΛίϯτϩʔϧͰ͖Δ͔ͬͯͷ ͸Ϛδେࣄ

  45. ڭ܇

  46. अಓʹ҆қʹඈͼ͔ͭͳ ͍