Slide 1

Slide 1 text

͸͡Ίͯͷ
 (SPPOHBCJOEJOHͮ͘Γ ઃᒜ༸࣐
 !EBSBTIJ (PͰମݧ 5IFNBTDPUXBTEFTJHOFECZ3FOÉF'SFODI
 -JDFOTFEVOEFS$$#: શจݕࡧΤϯδϯ(SPPOHBษڧձˏࡳຈ
 ࡳຈࢢຽϗʔϧୈձٞࣨ — The First Step for Building Groonga Bindings with Golang

Slide 2

Slide 2 text

5IFNBTDPUXBTEFTJHOFECZ3FOÉF'SFODI
 -JDFOTFEVOEFS$$#:

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

(Pʔϧ (P͔Β(SPPOHBΛ৮ΔϥΠϒϥϦΛ࡞Δ
 ʜͨΊͷୈҰาΛ౿Έग़͢

Slide 6

Slide 6 text

΍Βͳ͍͜ͱ w ϥΠϒϥϦͱͯ͠៉ྷʹ੔͑Δ w େ൒ͷΤϥʔॲཧ w ΫΤϦʔݴޠΛհ͞ͳ͍
 ௿Ϩϕϧͳ(SPPOHB"1*ͷར༻

Slide 7

Slide 7 text

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"

Slide 8

Slide 8 text

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" ͔͜͜Β
 ࢖͏

Slide 9

Slide 9 text

HSPPOHBίϚϯυ

Slide 10

Slide 10 text

$ 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}]

Slide 11

Slide 11 text

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" ࠓͷ͸
 $-*

Slide 12

Slide 12 text

ඞཁͳ"1*

Slide 13

Slide 13 text

͜Θ͘ͳ͍ w ࢝·ΓͱऴΘΓ
 HSO@JOJU HSO@pO w ίϯςΩετ HSO@DUY ͷ࡞੒ͱഁغ
 HSO@DUY@JOJU HSO@DUY@pO w σʔλϕʔεͷ࡞੒ɾΦʔϓϯͱΫϩʔζ
 HSO@EC@DSFBUF HSO@EC@PQFO HSO@PCK@DMPTF w ίϚϯυͷૹ৴ͱड৴
 HSO@DUY@TFOE HSO@DUY@SFDW

Slide 14

Slide 14 text

͸͡ΊͷҰา

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

(SPPOHBϥΠϒϥϦͷ
 ॳظԽͱ։์

Slide 19

Slide 19 text

' ' ( ( ) ) * * # # , , 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

Slide 20

Slide 20 text

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 ͕ऴΘΔͱ͖ʹ࣮ߦ͢Δ

Slide 21

Slide 21 text

ίϯςΩετͷ
 ࡞੒ͱഁغ

Slide 22

Slide 22 text

ʜίϯςΩετͬͯԿ

Slide 23

Slide 23 text

IUUQHSPPOHBPSHKBEPDTSFGFSFODFBQJHSO@DUYIUNM

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

IUUQHSPPOHBPSHKBEPDTSFGFSFODFBQJHSO@DUYIUNM ͬͪ͜Λ࢖ͬͯΈ·͢ HSO@DUY@JOJUͰ͸ͳ͘

Slide 26

Slide 26 text

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͸ͱΓ͋͑ͣͰ

Slide 27

Slide 27 text

σʔλϕʔεΛ
 ͭ͘Δɾͱ͡Δ

Slide 28

Slide 28 text

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Λࢦఆ͠·͢ɻ ϞδϡʔϧɺΫϥεɺ·ͨ͸ؔ਺໊ Λೖྗ͍ͯͩ͘͠͞ IUUQHSPPOHBPSHKBEPDTSFGFSFODFBQJHSO@ECIUNM طଘͷ%#Λ։͘ͱ͖͸͜Ε ͜ΕΛ࢖͍·͢

Slide 29

Slide 29 text

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Λ$ͷจࣈྻʹ͠·͢

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

͓͘Δ

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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͸ͱΓ͋͑ͣͰ

Slide 34

Slide 34 text

͏͚ͱΔ

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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)) }

Slide 37

Slide 37 text

Ͱ͖ͨ

Slide 38

Slide 38 text

$ 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}

Slide 39

Slide 39 text

͜Θ͘ͳ͍ w ࢝·ΓͱऴΘΓ
 HSO@JOJU HSO@pO w ίϯςΩετ HSO@DUY ͷ࡞੒ͱഁغ
 HSO@DUY@JOJU HSO@DUY@pO w σʔλϕʔεͷ࡞੒ɾΦʔϓϯͱΫϩʔζ
 HSO@EC@DSFBUF HSO@EC@PQFO HSO@PCK@DMPTF w ίϚϯυͷૹ৴ͱड৴
 HSO@DUY@TFOE HSO@DUY@SFDW

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

IUUQHSPPOHBPSHKBEPDTSFGFSFODFBQJHSO@DUYIUNM

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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)) } ݺͼग़ͨ͠HSO@͕໭Γ஋Ͱ
 ΤϥʔΛڭ͑ͯ͘ΕΔ৔߹
 ࣮͸DUYSD΋(3/@46$$&44ʹͳ͍ͬͯΔ

Slide 45

Slide 45 text

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)) } HUY@DUY@TFOEʹண໨

Slide 46

Slide 46 text

ݺͼग़ͨ͠HSO@͕໭Γ஋Ͱ
 ΤϥʔΛڭ͑ͯ͘ΕΔ৔߹ /* ུ */ ! 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ͨ͠

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

l͜Μ͝ͷ͔͍ͩz

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

·ͱΊ

Slide 51

Slide 51 text

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