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

The First Step for Building Groonga Bindings with Golang

The First Step for Building Groonga Bindings with Golang

Goで体験
はじめての
Groonga bindingづくり

全文検索エンジンGroonga勉強会@札幌
2014-03-29 札幌市民ホール 第4会議室

Yoji Shidara

March 29, 2014
Tweet

More Decks by Yoji Shidara

Other Decks in Technology

Transcript

  1. ͸͡Ίͯͷ

    (SPPOHBCJOEJOHͮ͘Γ
    ઃᒜ༸࣐

    !EBSBTIJ
    (PͰମݧ
    5IFNBTDPUXBTEFTJHOFECZ3FOÉF'SFODI

    -JDFOTFEVOEFS$$#:
    શจݕࡧΤϯδϯ(SPPOHBษڧձˏࡳຈ

    ࡳຈࢢຽϗʔϧୈձٞࣨ
    — The First Step for Building Groonga Bindings with Golang

    View Slide

  2. 5IFNBTDPUXBTEFTJHOFECZ3FOÉF'SFODI

    -JDFOTFEVOEFS$$#:

    View Slide

  3. 8IZ(P
    w DHPΛ࢖͏ͱ$ͷίʔυΛखܰʹݺ΂Δ
    w HPSVOͰ͘͘͞͞ࢼͤΔ
    w ָ͍͠ ࣗ෼͕

    View Slide

  4. (Pʔϧ
    (P͔Β(SPPOHBΛ৮ΔϥΠϒϥϦΛ࡞Δ

    View Slide

  5. (Pʔϧ
    (P͔Β(SPPOHBΛ৮ΔϥΠϒϥϦΛ࡞Δ

    ʜͨΊͷୈҰาΛ౿Έग़͢

    View Slide

  6. ΍Βͳ͍͜ͱ
    w ϥΠϒϥϦͱͯ͠៉ྷʹ੔͑Δ
    w େ൒ͷΤϥʔॲཧ
    w ΫΤϦʔݴޠΛհ͞ͳ͍

    ௿Ϩϕϧͳ(SPPOHB"1*ͷར༻

    View Slide

  7. Groonga2013 Powered by Rabbit 2.1.2
    Groonga
    libgroonga
    gqtp
    _
    `a bcd e
    fBg
    e
    fh
    Bij

    kQ
    groonga
    l
    API
    HTTP
    SQL
    CLI
    ,PIFJ4VUP l(SPPOHB଒zIUUQTMJEFSBCCJUTIPDLFSPSHBVUIPSTLPVHSPPOHBOJHIU$$#:4"

    View Slide

  8. Groonga2013 Powered by Rabbit 2.1.2
    Groonga
    libgroonga
    gqtp
    _
    `a bcd e
    fBg
    e
    fh
    Bij

    kQ
    groonga
    l
    API
    HTTP
    SQL
    CLI
    ,PIFJ4VUP l(SPPOHB଒zIUUQTMJEFSBCCJUTIPDLFSPSHBVUIPSTLPVHSPPOHBOJHIU$$#:4"
    ͔͜͜Β

    ࢖͏

    View Slide

  9. HSPPOHBίϚϯυ

    View Slide

  10. $ groonga

    > status
    [[0,1395981744.74587,3.814697265625e-05],
    {"alloc_count":151,"starttime":
    1395981645,"uptime":
    99,"version":"4.0.0","n_queries":
    0,"cache_hit_rate":0.0,"command_version":
    1,"default_command_version":
    1,"max_command_version":2}]

    View Slide

  11. Groonga2013 Powered by Rabbit 2.1.2
    Groonga
    libgroonga
    gqtp
    _
    `a bcd e
    fBg
    e
    fh
    Bij

    kQ
    groonga
    l
    API
    HTTP
    SQL
    CLI
    ,PIFJ4VUP l(SPPOHB଒zIUUQTMJEFSBCCJUTIPDLFSPSHBVUIPSTLPVHSPPOHBOJHIU$$#:4"
    ࠓͷ͸

    $-*

    View Slide

  12. ඞཁͳ"1*

    View Slide

  13. ͜Θ͘ͳ͍
    w ࢝·ΓͱऴΘΓ

    [email protected]
    [email protected]

    w ίϯςΩετ [email protected]
    ͷ࡞੒ͱഁغ

    [email protected]@JOJU
    [email protected]@pO

    w σʔλϕʔεͷ࡞੒ɾΦʔϓϯͱΫϩʔζ

    [email protected]@DSFBUF
    [email protected]@PQFO
    [email protected]@DMPTF

    w ίϚϯυͷૹ৴ͱड৴

    [email protected]@TFOE
    [email protected]@SFDW

    View Slide

  14. ͸͡ΊͷҰา

    View Slide

  15. લఏ
    w (P͕Πϯετʔϧ͞Ε͍ͯΔ
    w (SPPOHB͕Πϯετʔϧ͞Ε͍ͯΔ
    w QLHDPOpH͕(SPPOHBΛݟ͚ͭΒΕΔ

    View Slide

  16. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    */
    import "C"
    !
    func main() {
    }

    View Slide

  17. $ go run main.go
    $
    ʮԿ΋͠ͳ͍ʯΛͨ͠

    View Slide

  18. (SPPOHBϥΠϒϥϦͷ

    ॳظԽͱ։์

    View Slide

  19. '
    '
    (
    (
    )
    )
    *
    *
    #
    #
    ,
    , file
    file 349 lines (221 sloc)
    349 lines (221 sloc) 12.16 kb
    12.16 kb
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    =,groonga,C,API,ϚχϡΞϧ
    groongaͷCݴޠAPI͸ɺ1)ڞ௨APIɺ2)QL,APIɺ3)DB,APIɺ4)௿ϨϕϧAPIͷ4छʹେผ͞ΕΔɻ
    ڞ௨API͸ଞͷશͯͷAPIͱ૊Έ߹Θͤͯڞ௨ʹ࢖༻͞ΕΔɻ࢒Γͷ3छͷAPI͸֊૚ߏ଄Λͳ͍ͯ͠Δɻ
    QL,API͸࠷΋্ҐʹҐஔ͠ɺquery,languageΛհͯ͠σʔλετΞΛૢ࡞͢ΔػೳΛఏڙ͢Δɻ
    DB,API͸QL,APIͷԼҐʹҐஔ͠ɺσʔλετΞΛߏ੒͢Δ֤ΦϒδΣΫτΛૢ࡞͢ΔػೳΛఏڙ͢Δɻ
    ௿ϨϕϧAPI͸DB,APIͷ͞ΒʹԼҐʹҐஔ͠ɺσʔλΦϒδΣΫτͷߏ੒ཁૉΛ௚઀ૢ࡞͢ΔػೳΛఏڙ͢Δɻ
    =,ڞ௨API
    ==,grn_init
    :NAME
    ,,grn_init,,grn_fin,I,groongaϥΠϒϥϦΛॳظԽ/ղ์͢Δ
    :SYNOPSIS
    ,((','))
    ,,#include,
    ,,grn_rc,grn_init(void);
    ,,grn_rc,grn_fin(void);
    :DESCRIPTION
    ,,grn_init()͸ɺlibgroonga͕ඞཁͱ͢ΔࢿݯͷॳظԽΛߦ͏ɻlibgroongaΛ࢖༻͢ΔϓϩάϥϜ͸ଞͷgroonga,APIؔ਺Λݺͼग़͢લʹҰ౓͚ͩgrn_init()Λݺͼग़͞ͳ͚
    ,,grn_fin()͸libgroonga͕࢖༻͢ΔࢿݯΛղ์͢Δɻgrn_fin()࣮ߦޙʹgroonga,APIؔ਺Λ࣮ߦͯ͠͸ͳΒͳ͍ɻ
    :RETURN,VALUE
    ,,੒ޭͨ͠৔߹͸GRN_SUCCESSΛฦ͢ɻ
    ,,grn_init()͸ɺࢿݯͷ֬อʹࣦഊͨ͠৔߹ʹGRN_NO_MEMORY_AVAILABLEΛฦ͢ɻ
    :NOTES
    ,,grn_init(),,grn_fin()͸ϦΤϯτϥϯτͰ͸ͳ͍ɻͦͷଞͷgroongaͷC,APIؔ਺͸શͯϦΤϯτϥϯτͰ͋Δɻ
    -
    -
    - Open
    Open
    Open Edit
    Edit
    Edit Raw
    Raw Blame
    Blame History
    History Delete
    Delete
    IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE

    View Slide

  20. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    */
    import "C"
    !
    func main() {
    C.grn_init() // TODO error handling
    defer C.grn_fin() // TODO error handling
    }
    NBJO
    ͕ऴΘΔͱ͖ʹ࣮ߦ͢Δ

    View Slide

  21. ίϯςΩετͷ

    ࡞੒ͱഁغ

    View Slide

  22. ʜίϯςΩετͬͯԿ

    View Slide

  23. View Slide

  24. 39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    ==,grn_ctx_init
    :NAME
    ,,grn_ctx_init,,grn_ctx_fin,I,grn_ctxߏ଄ମΛॳظԽ/ղ์͢Δ
    :SYNOPSIS
    ,((','))
    ,,#include,
    ,,grn_rc,grn_ctx_init(grn_ctx,*ctx,,int,flags,,grn_encoding,encoding);
    ,,grn_rc,grn_ctx_fin(grn_ctx,*ctx);
    :DESCRIPTION
    ,,grn_ctx͸ɺ1)Τϥʔ৘ใͷ௨஌ɺ2)API಺෦Ͱ࢖༻͢ΔϝϞϦͷ؅ཧɺ3)ΫΤϦݴޠॲཧܥͷ؅ཧͷͨΊʹ࢖༻͞ΕΔߏ଄ମͰ͋Δɻ΄ͱΜͲͷAPIؔ਺͸ୈҰҾ਺ʹgrn_ct
    ,,,typedef,struct,_grn_ctx,grn_ctx;
    ,,,struct,_grn_ctx,{
    ,,,,,grn_rc,rc;,,,,,,,,,,,,,,,,,,,,,,,/*,࠷ޙʹ࣮ߦͨ͠APIͷऴྃίʔυ,*/
    ,,,,,int,flags;,,,,,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,grn_encoding,encoding;,,,,,,,,,,,/*,σϑΥϧτͷจࣈΤϯίʔσΟϯά,*/
    ,,,,,unsigned,char,ntrace;,,,,,,,,,,,,/*,όοΫτϨʔεͷ਺,*/
    ,,,,,unsigned,char,errlvl;,,,,,,,,,,,,/*,࠷ޙʹൃੜͨ͠ΤϥʔͷϨϕϧ,*/
    ,,,,,unsigned,char,stat;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,seqno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,subno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,seqno2;,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,errline;,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠Օॴͷߦ൪߸,*/
    ,,,,,grn_ctx,*prev;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,grn_ctx,*next;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,const,char,*errfile;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠ιʔεϑΝΠϧ໊,*/
    ,,,,,const,char,*errfunc;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨؔ͠਺໊,*/
    ,,,,,struct,_grn_ctx_impl,*impl;,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,void,*trace[16];,,,,,,,,,,,,,,,,,/*,όοΫτϨʔεϙΠϯλ഑ྻ,*/
    ,,,,,char,errbuf[GRN_CTX_MSGSIZE];,,,,/*,࠷ޙʹൃੜͨ͠Τϥʔʹؔ͢Δϝοηʔδ,*/
    ,,,};
    ,,grn_ctxߏ଄ମ͸APIͰ࢖༻͢Δલʹgrn_ctx_init()ͰॳظԽ͠ͳ͚Ε͹ͳΒͳ͍ɻॳظԽ͢Δgrn_ctxߏ଄ମ΁ͷϙΠϯλΛ'ctx'ʹࢦఆ͢Δɻ'flags'ʹGRN_CTX_USE_QL
    IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE

    View Slide

  25. [email protected]
    ͬͪ͜Λ࢖ͬͯΈ·͢
    [email protected]@JOJUͰ͸ͳ͘

    View Slide

  26. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    #include
    */
    import "C"
    !
    func main() {
    C.grn_init() // TODO error handling
    defer C.grn_fin() // TODO error handling
    !
    ctx := C.grn_ctx_open(0)
    defer C.grn_ctx_fin(ctx) // TODO error handling
    }
    qBHT͸ͱΓ͋͑ͣͰ

    View Slide

  27. σʔλϕʔεΛ

    ͭ͘Δɾͱ͡Δ

    View Slide

  28. It is used for specifying options for grn_db_create().
    char **grn_db_create_optarg.builtin_type_names
    ૊ΈࠐΈܕͷ໊લͱͳΔnulऴ୺จࣈྻͷ഑ྻΛࢦఆ͢Δɻ
    int grn_db_create_optarg.n_builtin_type_names
    n_builtin_type_namesʹ͸ɺoptarg.builtin_type_namesͰࢦఆ͢Δจࣈྻͷ਺Λ ࢦఆ͢Δɻ഑
    ྻͷoffset͸enumܕgrn_builtin_typeͷ஋ʹରԠ͢Δɻ
    grn_obj *grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg)
    ৽ͨͳdbΛ࡞੒͠·͢ɻ
    ύ
    ϥ
    ϝ
    λ:
    ctx -- ॳظԽࡁΈͷ grn_ctx Λࢦఆ͠·͢ɻ
    path -- ࡞੒͢ΔdbΛ֨ೲ͢ΔϑΝΠϧύεΛࢦఆ͠·͢ɻNULLͳΒtemporary db
    ͱͳΓ·͢ɻNULLҎ֎ͷύεΛࢦఆͨ͠৔߹͸persistent dbͱͳΓ·͢ɻ
    optarg --
    Currently, it is not used. It is just ignored.
    ࡞੒͢Δdbͷ૊ΈࠐΈܕͷ໊લΛมߋ͢Δ࣌ʹࢦఆ͠·͢ɻ
    optarg.builtin_type_namesʹ͸ɺ૊ΈࠐΈܕͷ໊લͱͳΔnullऴ୺จࣈྻͷ഑ྻΛࢦ
    ఆ͠·͢ɻoptarg.n_builtin_type_namesʹ͸ɺoptarg.builtin_type_namesͰࢦఆ͢Δจ
    ࣈྻͷ਺Λࢦఆ͠·͢ɻ഑ྻͷoffset͸enumܕgrn_builtin_typeͷ஋ʹରԠ͠·͢ɻ
    grn_obj *grn_db_open(grn_ctx *ctx, const char *path)
    طଘͷdbΛ։͖·͢ɻ
    ύϥϝλ: path -- ։͜͏ͱ͢ΔdbΛ֨ೲ͢ΔϑΝΠϧύεΛࢦఆ͠·͢ɻ
    void grn_db_touch(grn_ctx *ctx, grn_obj *db)
    dbͷ಺༰ͷ࠷ऴߋ৽࣌ࠁΛݱࡏ࣌ࠁʹ͠·͢ɻ
    ࠷ऴߋ৽࣌ࠁ͸Ωϟογϡ͕༗ޮ͔Ͳ͏͔ͷ൑அͳͲʹར༻͞Ε·͢ɻ
    ύϥϝλ: db -- ಺༰͕มߋ͞ΕͨdbΛࢦఆ͠·͢ɻ
    grn_obj *grn_obj_db(grn_ctx *ctx, grn_obj *obj)
    objͷଐ͢ΔdbΛฦ͠·͢ɻ
    ύϥϝλ: obj -- ର৅objectΛࢦఆ͠·͢ɻ
    ϞδϡʔϧɺΫϥεɺ·ͨ͸ؔ਺໊
    Λೖྗ͍ͯͩ͘͠͞
    [email protected]
    طଘͷ%#Λ։͘ͱ͖͸͜Ε
    ͜ΕΛ࢖͍·͢

    View Slide

  29. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    #include
    */
    import "C"
    import "unsafe"
    !
    func main() {
    C.grn_init() // TODO error handling
    defer C.grn_fin() // TODO error handling
    !
    ctx := C.grn_ctx_open(0)
    defer C.grn_ctx_fin(ctx) // TODO error handling
    !
    dbPath := "db"
    cDbPath := C.CString(dbPath)
    defer C.free(unsafe.Pointer(cDbPath))
    db := C.grn_db_create(ctx, cDbPath, nil)
    if db == nil {
    log.Fatal("[grn_db_create] Failed to create DB")
    }
    defer C.grn_obj_close(ctx, db)
    }
    EC1BUIΛ$ͷจࣈྻʹ͠·͢

    View Slide

  30. import "fmt"
    func main() {
    f := C.intFunc(C.fortytwo)
    fmt.Println(int(C.bridge_int_func(f)))
    // Output: 42
    }
    In C, a function argument written as a fixed size array actually requires a pointer to the first element of the array. C compilers are
    aware of this calling convention and adjust the call accordingly, but Go cannot. In Go, you must pass the pointer to the first element
    explicitly: C.f(&x[0]).
    A few special functions convert between Go and C types by making copies of the data. In pseudo-Go definitions:
    // Go string to C string
    // The C string is allocated in the C heap using malloc.
    // It is the caller's responsibility to arrange for it to be
    // freed, such as by calling C.free (be sure to include stdlib.h
    // if C.free is needed).
    func C.CString(string) *C.char
    // C string to Go string
    func C.GoString(*C.char) string
    // C string, length to Go string
    func C.GoStringN(*C.char, C.int) string
    // C pointer, length to Go []byte
    func C.GoBytes(unsafe.Pointer, C.int) []byte
    C references to Go
    Go functions can be exported for use by C code in the following way:
    //export MyFunction
    func MyFunction(arg1, arg2 int, arg3 string) int64 {...}
    //export MyFunction2
    func MyFunction2(arg1, arg2 int, arg3 string) (int64, *C.char) {...} IUUQHPMBOHPSHDNEDHP

    View Slide

  31. ͓͘Δ

    View Slide

  32. 265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    ==,grn_ctx_send
    :NAME
    ,,grn_ctx_send,I,͓͘Δ
    :SYNOPSIS
    ,((','))
    ,,#include,
    ,,unsigned,grn_ctx_send(grn_ctx,*ctx,,char,*str,,unsigned,int,str_len,,int,flags);
    :DESCRIPTION
    ,,͓͘Δ
    ==,grn_ctx_recv
    :NAME
    ,,grn_ctx_recv,I,͏͚ͱΔ
    :SYNOPSIS
    ,((','))
    ,,#include,
    ,,unsigned,grn_ctx_recv(grn_ctx,*ctx,,char,**str,,unsigned,int,*str_len,,int,*flags);
    :DESCRIPTION
    ,,͏͚ͱΔ
    =,DB,API
    ==,grn_db_create
    :NAME
    ,,grn_db_create,,grn_db_open,I,σʔλϕʔεΛੜ੒͢Δ
    IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE

    View Slide

  33. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    #include
    */
    import "C"
    import "unsafe"
    !
    func main() {
    C.grn_init() // TODO error handling
    defer C.grn_fin() // TODO error handling
    !
    ctx := C.grn_ctx_open(0)
    defer C.grn_ctx_fin(ctx) // TODO error handling
    !
    dbPath := "db"
    cDbPath := C.CString(dbPath)
    defer C.free(unsafe.Pointer(cDbPath))
    db := C.grn_db_create(ctx, cDbPath, nil)
    if db == nil {
    log.Fatal("[grn_db_create] Failed to create DB")
    }
    defer C.grn_obj_close(ctx, db)
    !
    command := "status"
    cCommand := C.CString(command)
    defer C.free(unsafe.Pointer(cCommand))
    C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling
    }
    DPNNBOEΛ$ͷจࣈྻʹ͠·͢
    ίϚϯυ௕ qBHT͸ͱΓ͋͑ͣͰ

    View Slide

  34. ͏͚ͱΔ

    View Slide

  35. 265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    ==,grn_ctx_send
    :NAME
    ,,grn_ctx_send,I,͓͘Δ
    :SYNOPSIS
    ,((','))
    ,,#include,
    ,,unsigned,grn_ctx_send(grn_ctx,*ctx,,char,*str,,unsigned,int,str_len,,int,flags);
    :DESCRIPTION
    ,,͓͘Δ
    ==,grn_ctx_recv
    :NAME
    ,,grn_ctx_recv,I,͏͚ͱΔ
    :SYNOPSIS
    ,((','))
    ,,#include,
    ,,unsigned,grn_ctx_recv(grn_ctx,*ctx,,char,**str,,unsigned,int,*str_len,,int,*flags);
    :DESCRIPTION
    ,,͏͚ͱΔ
    =,DB,API
    ==,grn_db_create
    :NAME
    ,,grn_db_create,,grn_db_open,I,σʔλϕʔεΛੜ੒͢Δ
    IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE

    View Slide

  36. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    #include
    */
    import "C"
    import "unsafe"
    import "log"
    !
    func main() {
    C.grn_init() // TODO error handling
    defer C.grn_fin() // TODO error handling
    !
    ctx := C.grn_ctx_open(0)
    defer C.grn_ctx_fin(ctx) // TODO error handling
    !
    dbPath := "db"
    cDbPath := C.CString(dbPath)
    defer C.free(unsafe.Pointer(cDbPath))
    db := C.grn_db_create(ctx, cDbPath, nil)
    if db == nil {
    log.Fatal("[grn_db_create] Failed to create DB")
    }
    defer C.grn_obj_close(ctx, db)
    !
    command := "status"
    cCommand := C.CString(command)
    defer C.free(unsafe.Pointer(cCommand))
    C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling
    !
    var resultBuffer *C.char
    var resultLength C.uint
    var flags C.int
    C.grn_ctx_recv(ctx, &resultBuffer, &resultLength, &flags) // TODO error handling
    result := C.GoBytes(unsafe.Pointer(resultBuffer), C.int(resultLength))
    !
    log.Println(string(result))
    }

    View Slide

  37. Ͱ͖ͨ

    View Slide

  38. $ go run main.go
    2014/03/28 15:34:38 {"alloc_count":
    156,"starttime":1395988478,"uptime":
    0,"version":"4.0.0","n_queries":
    0,"cache_hit_rate":0.0,"command_version":
    1,"default_command_version":
    1,"max_command_version":2}

    View Slide

  39. ͜Θ͘ͳ͍
    w ࢝·ΓͱऴΘΓ

    [email protected]
    [email protected]

    w ίϯςΩετ [email protected]
    ͷ࡞੒ͱഁغ

    [email protected]@JOJU
    [email protected]@pO

    w σʔλϕʔεͷ࡞੒ɾΦʔϓϯͱΫϩʔζ

    [email protected]@DSFBUF
    [email protected]@PQFO
    [email protected]@DMPTF

    w ίϚϯυͷૹ৴ͱड৴

    [email protected]@TFOE
    [email protected]@SFDW

    View Slide

  40. Τϥʔॲཧʹ͍ͭͯ
    ͢͜͠

    View Slide

  41. View Slide

  42. ;ͨͭͷΤϥʔ
    w ݺͼग़ͨ͠[email protected]͕໭Γ஋ͰΤϥʔΛڭ͑ͯ͘ΕΔ
    ৔߹
    w ݺͼग़͠͸੒ޭͨ͠΋ͷͷɺ࣮ߦʹ͸ࣦഊͯ͠ίϯ
    ςΩετʹΤϥʔ͕ೖΔ৔߹

    View Slide

  43. 39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    ==,grn_ctx_init
    :NAME
    ,,grn_ctx_init,,grn_ctx_fin,I,grn_ctxߏ଄ମΛॳظԽ/ղ์͢Δ
    :SYNOPSIS
    ,((','))
    ,,#include,
    ,,grn_rc,grn_ctx_init(grn_ctx,*ctx,,int,flags,,grn_encoding,encoding);
    ,,grn_rc,grn_ctx_fin(grn_ctx,*ctx);
    :DESCRIPTION
    ,,grn_ctx͸ɺ1)Τϥʔ৘ใͷ௨஌ɺ2)API಺෦Ͱ࢖༻͢ΔϝϞϦͷ؅ཧɺ3)ΫΤϦݴޠॲཧܥͷ؅ཧͷͨΊʹ࢖༻͞ΕΔߏ଄ମͰ͋Δɻ΄ͱΜͲͷAPIؔ਺͸ୈҰҾ਺ʹgrn_ct
    ,,,typedef,struct,_grn_ctx,grn_ctx;
    ,,,struct,_grn_ctx,{
    ,,,,,grn_rc,rc;,,,,,,,,,,,,,,,,,,,,,,,/*,࠷ޙʹ࣮ߦͨ͠APIͷऴྃίʔυ,*/
    ,,,,,int,flags;,,,,,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,grn_encoding,encoding;,,,,,,,,,,,/*,σϑΥϧτͷจࣈΤϯίʔσΟϯά,*/
    ,,,,,unsigned,char,ntrace;,,,,,,,,,,,,/*,όοΫτϨʔεͷ਺,*/
    ,,,,,unsigned,char,errlvl;,,,,,,,,,,,,/*,࠷ޙʹൃੜͨ͠ΤϥʔͷϨϕϧ,*/
    ,,,,,unsigned,char,stat;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,seqno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,subno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,seqno2;,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,unsigned,int,errline;,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠Օॴͷߦ൪߸,*/
    ,,,,,grn_ctx,*prev;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,grn_ctx,*next;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,const,char,*errfile;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠ιʔεϑΝΠϧ໊,*/
    ,,,,,const,char,*errfunc;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨؔ͠਺໊,*/
    ,,,,,struct,_grn_ctx_impl,*impl;,,,,,,/*,಺෦ॲཧ༻,*/
    ,,,,,void,*trace[16];,,,,,,,,,,,,,,,,,/*,όοΫτϨʔεϙΠϯλ഑ྻ,*/
    ,,,,,char,errbuf[GRN_CTX_MSGSIZE];,,,,/*,࠷ޙʹൃੜͨ͠Τϥʔʹؔ͢Δϝοηʔδ,*/
    ,,,};
    ,,grn_ctxߏ଄ମ͸APIͰ࢖༻͢Δલʹgrn_ctx_init()ͰॳظԽ͠ͳ͚Ε͹ͳΒͳ͍ɻॳظԽ͢Δgrn_ctxߏ଄ମ΁ͷϙΠϯλΛ'ctx'ʹࢦఆ͢Δɻ'flags'ʹGRN_CTX_USE_QL
    IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE

    View Slide

  44. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    #include
    */
    import "C"
    import "unsafe"
    import "log"
    !
    func main() {
    C.grn_init() // TODO error handling
    defer C.grn_fin() // TODO error handling
    !
    ctx := C.grn_ctx_open(0)
    defer C.grn_ctx_fin(ctx) // TODO error handling
    !
    dbPath := "db"
    cDbPath := C.CString(dbPath)
    defer C.free(unsafe.Pointer(cDbPath))
    db := C.grn_db_create(ctx, cDbPath, nil)
    if db == nil {
    log.Fatal("[grn_db_create] Failed to create DB")
    }
    defer C.grn_obj_close(ctx, db)
    !
    command := "status"
    cCommand := C.CString(command)
    defer C.free(unsafe.Pointer(cCommand))
    C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling
    !
    var resultBuffer *C.char
    var resultLength C.uint
    var flags C.int
    C.grn_ctx_recv(ctx, &resultBuffer, &resultLength, &flags) // TODO error handling
    result := C.GoBytes(unsafe.Pointer(resultBuffer), C.int(resultLength))
    !
    log.Println(string(result))
    }
    ݺͼग़ͨ͠[email protected]͕໭Γ஋Ͱ

    ΤϥʔΛڭ͑ͯ͘ΕΔ৔߹

    ࣮͸DUYSD΋(3/@46$$&44ʹͳ͍ͬͯΔ

    View Slide

  45. package main
    !
    /*
    #cgo pkg-config: groonga
    #include
    #include
    */
    import "C"
    import "unsafe"
    import "log"
    !
    func main() {
    C.grn_init() // TODO error handling
    defer C.grn_fin() // TODO error handling
    !
    ctx := C.grn_ctx_open(0)
    defer C.grn_ctx_fin(ctx) // TODO error handling
    !
    dbPath := "db"
    cDbPath := C.CString(dbPath)
    defer C.free(unsafe.Pointer(cDbPath))
    db := C.grn_db_create(ctx, cDbPath, nil)
    if db == nil {
    log.Fatal("[grn_db_create] Failed to create DB")
    }
    defer C.grn_obj_close(ctx, db)
    !
    command := "status"
    cCommand := C.CString(command)
    defer C.free(unsafe.Pointer(cCommand))
    C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling
    !
    var resultBuffer *C.char
    var resultLength C.uint
    var flags C.int
    C.grn_ctx_recv(ctx, &resultBuffer, &resultLength, &flags) // TODO error handling
    result := C.GoBytes(unsafe.Pointer(resultBuffer), C.int(resultLength))
    !
    log.Println(string(result))
    }
    [email protected]@TFOEʹண໨

    View Slide

  46. ݺͼग़ͨ͠[email protected]͕໭Γ஋Ͱ

    ΤϥʔΛڭ͑ͯ͘ΕΔ৔߹
    /* ུ */
    !
    command := "statussssss"
    cCommand := C.CString(command)
    defer C.free(unsafe.Pointer(cCommand))
    rc := C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0)
    if rc != C.GRN_SUCCESS {
    log.Fatal("[grn_ctx_send(rc)]")
    }
    if ctx.rc != C.GRN_SUCCESS {
    message := C.GoString(&ctx.errbuf[0])
    log.Fatal("[grn_ctx_send(ctx.rc)] ", message)
    }
    !
    /* ུ */
    ݺͼग़͠͸੒ޭͨ͠΋ͷͷɺ

    ࣮ߦʹ͸ࣦഊͯ͠ίϯςΩετʹΤϥʔ͕ೖΔ৔߹
    UZQPͨ͠

    View Slide

  47. $ go run main.go
    2014/03/29 13:07:45 [grn_ctx_send(ctx.rc)]
    invalid command name: statussssss
    exit status 1

    View Slide

  48. l͜Μ͝ͷ͔͍ͩz

    View Slide

  49. ϥΠϒϥϦͱͯ͠੔͑Δ
    w %#ΛͻΒ͘৔߹ɺͭ͘Δ৔߹ͷ྆ํʹରԠ
    w (PSPVUJOFͱεϨουͱ[email protected]Λ஥ྑ͘
    w Τϥʔͷॲཧ
    w ࣗಈԽςετ
    w ೖग़ྗΛ(PͰѻ͍қ͍ܗࣜʹ

    View Slide

  50. ·ͱΊ

    View Slide

  51. ·ͱΊ
    w (PͰ(SPPOHBCJOEJOHΛͭ͘ΔͨΊͷ

    ୈҰาΛ঺հͨ͠
    w (SPPOHBCJOEJOHͱͯ͠࢖͑Δ΋ͷʹ͢ΔͨΊʹ
    ඞཁͳ࡞ۀΛࣔͨ͠

    View Slide