@@ -257,6 +257,143 @@ func ExampleRepository_Search() {
257257 // Computer
258258}
259259
260+ func ExampleRepository_ReadLast () {
261+ ctx := context .Background ()
262+ client := getBigTableClient (ctx )
263+ c , err := fs .ReadFile ("testdata/mapping.json" )
264+ if err != nil {
265+ log .Fatalln (err )
266+ }
267+ jsonMapping , err := mapping .LoadMapping (c )
268+ if err != nil {
269+ log .Fatalln (err )
270+ }
271+ mapper := mapping .NewMapper (jsonMapping )
272+ tbl := client .Open (table )
273+
274+ repo := NewRepository (tbl , mapper )
275+ eventSet := & data.Set {Events : map [string ][]* data.Event {
276+ "front" : {
277+ {
278+ RowKey : "contactz-102" ,
279+ Date : time .Date (2018 , time .January , 1 , 0 , 2 , 0 , 0 , time .UTC ),
280+ Cells : map [string ]string {
281+ "event_type" : "add_to_cart" ,
282+ "device_type" : "Computer" ,
283+ "url" : "https://example.org/some/product" ,
284+ },
285+ },
286+ },
287+ }}
288+
289+ // insert
290+ errs , err := repo .Write (ctx , eventSet )
291+ if err != nil {
292+ log .Fatalln (err )
293+ }
294+ if len (errs ) > 0 {
295+ log .Fatalln (errs )
296+ }
297+
298+ // update
299+ eventSet = & data.Set {Events : map [string ][]* data.Event {
300+ "front" : {
301+ {
302+ RowKey : "contactz-102" ,
303+ Date : time .Now (),
304+ Cells : map [string ]string {
305+ "event_type" : "purchase" ,
306+ "device_type" : "Smartphone" ,
307+ "url" : "https://example.org/some/cart" ,
308+ },
309+ },
310+ },
311+ }}
312+ errs , err = repo .Write (ctx , eventSet )
313+ if err != nil {
314+ log .Fatalln (err )
315+ }
316+ if len (errs ) > 0 {
317+ log .Fatalln (errs )
318+ }
319+
320+ readSet , err := repo .ReadLast (ctx , "contactz-102" )
321+ if err != nil {
322+ log .Fatalln (err )
323+ }
324+ for _ , event := range readSet .Events ["front" ] {
325+ fmt .Println (event .Cells ["event_type" ])
326+ fmt .Println (event .Cells ["device_type" ])
327+ }
328+ // Output:
329+ // add_to_cart
330+ //
331+ // purchase
332+ // Smartphone
333+ }
334+
335+ func ExampleRepository_ReadFamily () {
336+ ctx := context .Background ()
337+ client := getBigTableClient (ctx )
338+ c , err := fs .ReadFile ("testdata/mapping.json" )
339+ if err != nil {
340+ log .Fatalln (err )
341+ }
342+ jsonMapping , err := mapping .LoadMapping (c )
343+ if err != nil {
344+ log .Fatalln (err )
345+ }
346+ mapper := mapping .NewMapper (jsonMapping )
347+ tbl := client .Open (table )
348+
349+ repo := NewRepository (tbl , mapper )
350+ eventSet := & data.Set {Events : map [string ][]* data.Event {
351+ "front" : {
352+ {
353+ RowKey : "contactz-102" ,
354+ Date : time .Date (2018 , time .January , 1 , 0 , 2 , 0 , 0 , time .UTC ),
355+ Cells : map [string ]string {
356+ "event_type" : "add_to_cart" ,
357+ "device_type" : "Computer" ,
358+ "url" : "https://example.org/some/product" ,
359+ },
360+ },
361+ },
362+ "blog" : {
363+ {
364+ RowKey : "contactz-102" ,
365+ Date : time .Date (2018 , time .January , 1 , 0 , 2 , 0 , 0 , time .UTC ),
366+ Cells : map [string ]string {
367+ "event_type" : "page_view" ,
368+ "device_type" : "Computer" ,
369+ "url" : "https://example.org/blog/article/1" ,
370+ },
371+ },
372+ },
373+ }}
374+
375+ // insert
376+ errs , err := repo .Write (ctx , eventSet )
377+ if err != nil {
378+ log .Fatalln (err )
379+ }
380+ if len (errs ) > 0 {
381+ log .Fatalln (errs )
382+ }
383+
384+ readSet , err := repo .ReadFamily (ctx , "contactz-102" , "blog" )
385+ if err != nil {
386+ log .Fatalln (err )
387+ }
388+ for _ , event := range readSet .Events ["blog" ] {
389+ fmt .Println (event .Cells ["event_type" ])
390+ fmt .Println (event .Cells ["device_type" ])
391+ }
392+ // Output:
393+ // page_view
394+ // Computer
395+ }
396+
260397var t1 = bigtable .Time (time .Date (2020 , time .January , 1 , 0 , 1 , 0 , 0 , time .UTC ))
261398var t2 = bigtable .Time (time .Date (2020 , time .January , 1 , 0 , 2 , 0 , 0 , time .UTC ))
262399var t3 = bigtable .Time (time .Date (2020 , time .January , 1 , 0 , 3 , 0 , 0 , time .UTC ))
@@ -360,6 +497,111 @@ func TestRepository_Search(t *testing.T) {
360497
361498}
362499
500+ func TestRepository_ReadLast (t * testing.T ) {
501+ ctx := context .Background ()
502+ repository := & Repository {
503+ adapter : mockAdapter {},
504+ mapper : getMockMapper (t ),
505+ }
506+ eventSet , err := repository .ReadLast (ctx , "contact-3" )
507+ if err != nil {
508+ t .Fatal (err )
509+ }
510+ if err != nil {
511+ t .Fatalf ("failed to read: %v" , err )
512+ }
513+ if len (eventSet .Events ) != 1 {
514+ t .Fatalf ("expected 1 event family, got %d" , len (eventSet .Events ))
515+ }
516+ if v , ok := eventSet .Events ["front" ]; ! ok {
517+ t .Fatalf ("expected front family, got %v" , v )
518+ } else {
519+ if len (v ) != 3 {
520+ t .Fatalf ("expected 3 events, got %d" , len (v ))
521+ }
522+
523+ if v [0 ].RowKey != "contact-3" {
524+ t .Fatalf ("expected contact-3, got %s" , v [0 ].RowKey )
525+ }
526+ if v [0 ].Cells ["url" ] != "http://someexample.url/query/string/1" {
527+ t .Fatalf ("expected http://someexample.url/query/string/1, got %s" , v [0 ].Cells ["url" ])
528+ }
529+ if v [0 ].Cells ["device_type" ] != "Smartphone" {
530+ t .Fatalf ("expected Smartphone, got %s" , v [0 ].Cells ["device_type" ])
531+ }
532+ // here we're testing each event_type depending on the timestamp.
533+ // It's because Go doesn't guarantee the order of the map iteration
534+ for _ , event := range v {
535+ if event .Date .Unix () == t1 .Time ().Unix () {
536+ if event .Cells ["event_type" ] != "page_view" {
537+ t .Fatalf ("expected page_view, got %s" , event .Cells ["event_type" ])
538+ }
539+ }
540+ if event .Date .Unix () == t2 .Time ().Unix () {
541+ if event .Cells ["event_type" ] != "add_to_cart" {
542+ t .Fatalf ("expected add_to_cart, got %s" , event .Cells ["event_type" ])
543+ }
544+ }
545+ if event .Date .Unix () == t3 .Time ().Unix () {
546+ if event .Cells ["event_type" ] != "purchase" {
547+ t .Fatalf ("expected purchase, got %s" , event .Cells ["event_type" ])
548+ }
549+ }
550+ }
551+ }
552+ }
553+
554+ func TestRepository_ReadFamily (t * testing.T ) {
555+ ctx := context .Background ()
556+ repository := & Repository {
557+ adapter : mockAdapter {},
558+ mapper : getMockMapper (t ),
559+ }
560+ eventSet , err := repository .ReadFamily (ctx , "contact-3" , "front" )
561+ if err != nil {
562+ t .Fatalf ("failed to read: %v" , err )
563+ }
564+ if len (eventSet .Events ) != 1 {
565+ t .Fatalf ("expected 1 event family, got %d" , len (eventSet .Events ))
566+ }
567+ if v , ok := eventSet .Events ["front" ]; ! ok {
568+ t .Fatalf ("expected front family, got %v" , v )
569+ } else {
570+ if len (v ) != 3 {
571+ t .Fatalf ("expected 3 events, got %d" , len (v ))
572+ }
573+
574+ if v [0 ].RowKey != "contact-3" {
575+ t .Fatalf ("expected contact-3, got %s" , v [0 ].RowKey )
576+ }
577+ if v [0 ].Cells ["url" ] != "http://someexample.url/query/string/1" {
578+ t .Fatalf ("expected http://someexample.url/query/string/1, got %s" , v [0 ].Cells ["url" ])
579+ }
580+ if v [0 ].Cells ["device_type" ] != "Smartphone" {
581+ t .Fatalf ("expected Smartphone, got %s" , v [0 ].Cells ["device_type" ])
582+ }
583+ // here we're testing each event_type depending on the timestamp.
584+ // It's because Go doesn't guarantee the order of the map iteration
585+ for _ , event := range v {
586+ if event .Date .Unix () == t1 .Time ().Unix () {
587+ if event .Cells ["event_type" ] != "page_view" {
588+ t .Fatalf ("expected page_view, got %s" , event .Cells ["event_type" ])
589+ }
590+ }
591+ if event .Date .Unix () == t2 .Time ().Unix () {
592+ if event .Cells ["event_type" ] != "add_to_cart" {
593+ t .Fatalf ("expected add_to_cart, got %s" , event .Cells ["event_type" ])
594+ }
595+ }
596+ if event .Date .Unix () == t3 .Time ().Unix () {
597+ if event .Cells ["event_type" ] != "purchase" {
598+ t .Fatalf ("expected purchase, got %s" , event .Cells ["event_type" ])
599+ }
600+ }
601+ }
602+ }
603+ }
604+
363605//go:embed testdata/mapping.json
364606var fs embed.FS
365607
@@ -497,6 +739,10 @@ func getBigTableClient(ctx context.Context) *bigtable.Client {
497739 log .Fatalln (err )
498740 }
499741
742+ if err = adminClient .CreateColumnFamily (ctx , table , "blog" ); err != nil {
743+ log .Fatalln (err )
744+ }
745+
500746 client , err := bigtable .NewClient (ctx , projectID , instance , option .WithGRPCConn (conn ))
501747 if err != nil {
502748 log .Fatalln (err )
0 commit comments