github.com/altipla-consulting/ravendb-go-client@v0.1.3/examples/main.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"os"
     9  	"path/filepath"
    10  	"reflect"
    11  	"sort"
    12  	"time"
    13  
    14  	"github.com/altipla-consulting/ravendb-go-client/examples/northwind"
    15  
    16  	"github.com/kylelemons/godebug/pretty"
    17  	ravendb "github.com/altipla-consulting/ravendb-go-client"
    18  )
    19  
    20  // "Demo" is a Northwind sample database
    21  // You can browse its content via web interface at
    22  // http://live-test.ravendb.net/studio/index.html#databases/documents?&database=Demo
    23  var (
    24  	dbName        = "Demo"
    25  	serverNodeURL = "http://live-test.ravendb.net"
    26  
    27  	// if true, we'll show summary of HTTP requests made to the server
    28  	// and dump full info about failed HTTP requests
    29  	verboseLogging = true
    30  
    31  	// if true, logs all http requests/responses to a file for further inspection
    32  	// this is for use in tests so the file has a fixed location:
    33  	// logs/trace_${test_name}_go.txt
    34  	logAllRequests = false
    35  
    36  	// if logAllRequests is true, this is a path of a file where we log
    37  	// info about all HTTP requests
    38  	logAllRequestsPath = "http_requests_log.txt"
    39  )
    40  
    41  func printRQL(q *ravendb.DocumentQuery) {
    42  	iq, err := q.GetIndexQuery()
    43  	if err != nil {
    44  		log.Fatalf("q.GetIndexQuery() returned '%s'\n", err)
    45  	}
    46  	fmt.Printf("RQL: %s\n", iq.GetQuery())
    47  	params := iq.GetQueryParameters()
    48  	if len(params) == 0 {
    49  		return
    50  	}
    51  	fmt.Printf("Parameters:\n")
    52  	var keys []string
    53  	for k := range params {
    54  		keys = append(keys, k)
    55  	}
    56  	sort.Strings(keys)
    57  	for _, key := range keys {
    58  		fmt.Printf("  $%s: %#v\n", key, params[key])
    59  	}
    60  	fmt.Print("\n")
    61  }
    62  
    63  func getDocumentStore(databaseName string) (*ravendb.DocumentStore, error) {
    64  	serverNodes := []string{serverNodeURL}
    65  	store := ravendb.NewDocumentStore(serverNodes, databaseName)
    66  	if err := store.Initialize(); err != nil {
    67  		return nil, err
    68  	}
    69  	return store, nil
    70  }
    71  
    72  func openSession(databaseName string) (*ravendb.DocumentStore, *ravendb.DocumentSession, error) {
    73  	store, err := getDocumentStore(dbName)
    74  	if err != nil {
    75  		return nil, nil, fmt.Errorf("getDocumentStore() failed with %s", err)
    76  	}
    77  
    78  	session, err := store.OpenSession("")
    79  	if err != nil {
    80  		return nil, nil, fmt.Errorf("store.OpenSession() failed with %s", err)
    81  	}
    82  	return store, session, nil
    83  }
    84  
    85  func loadUpdateSave() {
    86  	store, session, err := openSession(dbName)
    87  	if err != nil {
    88  		log.Fatalf("openSession() failed with %s\n", err)
    89  	}
    90  	defer store.Close()
    91  	defer session.Close()
    92  
    93  	var e *northwind.Employee
    94  	err = session.Load(&e, "employees/7-A")
    95  	if err != nil {
    96  		log.Fatalf("session.Load() failed with %s\n", err)
    97  	}
    98  
    99  	origName := e.FirstName
   100  	e.FirstName = e.FirstName + "Changed"
   101  	err = session.Store(e)
   102  	if err != nil {
   103  		log.Fatalf("session.Store() failed with %s\n", err)
   104  	}
   105  
   106  	err = session.SaveChanges()
   107  	if err != nil {
   108  		log.Fatalf("session.SaveChanges() failed with %s\n", err)
   109  	}
   110  
   111  	var e2 *northwind.Employee
   112  	err = session.Load(&e2, "employees/7-A")
   113  	if err != nil {
   114  		log.Fatalf("session.Load() failed with %s\n", err)
   115  	}
   116  	fmt.Printf("Updated Employee.FirstName from '%s' to '%s'\n", origName, e2.FirstName)
   117  }
   118  
   119  func crudStore() {
   120  	store, session, err := openSession(dbName)
   121  	if err != nil {
   122  		log.Fatalf("openSession() failed with %s\n", err)
   123  	}
   124  	defer store.Close()
   125  	defer session.Close()
   126  
   127  	product := &northwind.Product{
   128  		Name:         "iPhone X",
   129  		PricePerUnit: 999.99,
   130  		Category:     "electronics",
   131  		ReorderLevel: 15,
   132  	}
   133  	err = session.Store(product)
   134  	if err != nil {
   135  		log.Fatalf("session.Store() failed with %s\n", err)
   136  	}
   137  	fmt.Printf("Product ID: %s\n", product.ID)
   138  	err = session.SaveChanges()
   139  	if err != nil {
   140  		log.Fatalf("session.SaveChanges() failed with %s\n", err)
   141  	}
   142  }
   143  
   144  func crudLoad() {
   145  	store, session, err := openSession(dbName)
   146  	if err != nil {
   147  		log.Fatalf("openSession() failed with %s\n", err)
   148  	}
   149  	defer store.Close()
   150  	defer session.Close()
   151  
   152  	var e *northwind.Employee
   153  	err = session.Load(&e, "employees/7-A")
   154  	if err != nil {
   155  		log.Fatalf("session.Load() failed with %s\n", err)
   156  	}
   157  	fmt.Print("empolyee:\n")
   158  	pretty.Print(e)
   159  }
   160  
   161  func crudLoadWithIncludes() {
   162  	store, session, err := openSession(dbName)
   163  	if err != nil {
   164  		log.Fatalf("openSession() failed with %s\n", err)
   165  	}
   166  	defer store.Close()
   167  	defer session.Close()
   168  
   169  	// load employee with id "employees/7-A" and entity whose id is ReportsTo
   170  	var e *northwind.Employee
   171  	err = session.Include("ReportsTo").Load(&e, "employees/5-A")
   172  	if err != nil {
   173  		log.Fatalf("session.Load() failed with %s\n", err)
   174  	}
   175  	if e.ReportsTo == "" {
   176  		fmt.Printf("Employee with id employees/5-A doesn't report to anyone\n")
   177  		return
   178  	}
   179  
   180  	numRequests := session.GetNumberOfRequests()
   181  	var reportsTo *northwind.Employee
   182  	err = session.Load(&reportsTo, e.ReportsTo)
   183  	if err != nil {
   184  		log.Fatalf("session.Load() failed with %s\n", err)
   185  	}
   186  	if numRequests != session.GetNumberOfRequests() {
   187  		fmt.Printf("Something's wrong, this shouldn't send a request to the server\n")
   188  	} else {
   189  		fmt.Printf("Loading e.ReportsTo employee didn't require a new request to the server because we've loaded it in original requests thanks to using Include functionality\n")
   190  	}
   191  }
   192  
   193  func crudUpdate() {
   194  	store, err := getDocumentStore(dbName)
   195  	if err != nil {
   196  		log.Fatalf("getDocumentStore() failed with %s\n", err)
   197  	}
   198  	defer store.Close()
   199  
   200  	var productID string
   201  	{
   202  		session, err := store.OpenSession("")
   203  		if err != nil {
   204  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   205  		}
   206  
   207  		product := &northwind.Product{
   208  			Name:         "iPhone X",
   209  			PricePerUnit: 999.99,
   210  			Category:     "electronics",
   211  			ReorderLevel: 15,
   212  		}
   213  		err = session.Store(product)
   214  		if err != nil {
   215  			log.Fatalf("session.Store() failed with %s\n", err)
   216  		}
   217  		productID = product.ID
   218  		err = session.SaveChanges()
   219  		if err != nil {
   220  			log.Fatalf("session.SaveChanges() failed with %s\n", err)
   221  		}
   222  
   223  		session.Close()
   224  	}
   225  
   226  	var origPrice float64
   227  	var newPrice float64
   228  	{
   229  		session, err := store.OpenSession("")
   230  		if err != nil {
   231  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   232  		}
   233  
   234  		// load entity from the server
   235  		var p *northwind.Product
   236  		err = session.Load(&p, productID)
   237  		if err != nil {
   238  			log.Fatalf("session.Load() failed with %s\n", err)
   239  		}
   240  
   241  		// update price
   242  		origPrice = p.PricePerUnit
   243  		newPrice = origPrice + 10
   244  		p.PricePerUnit = newPrice
   245  		err = session.Store(p)
   246  		if err != nil {
   247  			log.Fatalf("session.Store() failed with %s\n", err)
   248  		}
   249  
   250  		// persist changes on the server
   251  		err = session.SaveChanges()
   252  		if err != nil {
   253  			log.Fatalf("session.SaveChanges() failed with %s\n", err)
   254  		}
   255  
   256  		session.Close()
   257  	}
   258  
   259  	{
   260  		session, err := store.OpenSession("")
   261  		if err != nil {
   262  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   263  		}
   264  		var p *northwind.Product
   265  		err = session.Load(&p, productID)
   266  		if err != nil {
   267  			log.Fatalf("session.Load() failed with %s\n", err)
   268  		}
   269  
   270  		if p.PricePerUnit != newPrice {
   271  			fmt.Printf("Error: a change to PricePerUnit was not persisted (is %v should be %v)\n", newPrice, p.PricePerUnit)
   272  		} else {
   273  			fmt.Printf("Updated the price from %v to %v\n", origPrice, newPrice)
   274  		}
   275  		session.Close()
   276  	}
   277  }
   278  
   279  func crudDeleteUsingID() {
   280  	store, err := getDocumentStore(dbName)
   281  	if err != nil {
   282  		log.Fatalf("getDocumentStore() failed with %s\n", err)
   283  	}
   284  	defer store.Close()
   285  
   286  	var productID string
   287  	{
   288  		session, err := store.OpenSession("")
   289  		if err != nil {
   290  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   291  		}
   292  
   293  		product := &northwind.Product{
   294  			Name:         "iPhone X",
   295  			PricePerUnit: 999.99,
   296  			Category:     "electronics",
   297  		}
   298  		err = session.Store(product)
   299  		if err != nil {
   300  			log.Fatalf("session.Store() failed with %s\n", err)
   301  		}
   302  		productID = product.ID
   303  		err = session.SaveChanges()
   304  		if err != nil {
   305  			log.Fatalf("session.SaveChanges() failed with %s\n", err)
   306  		}
   307  
   308  		session.Close()
   309  	}
   310  
   311  	{
   312  		session, err := store.OpenSession("")
   313  		if err != nil {
   314  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   315  		}
   316  
   317  		err = session.DeleteByID(productID, "")
   318  		if err != nil {
   319  			log.Fatalf("session.DeleteByID() failed with %s\n", err)
   320  		}
   321  
   322  		err = session.SaveChanges()
   323  		if err != nil {
   324  			log.Fatalf("session.SaveChanges() failed with %s\n", err)
   325  		}
   326  
   327  		session.Close()
   328  	}
   329  
   330  	{
   331  		session, err := store.OpenSession("")
   332  		if err != nil {
   333  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   334  		}
   335  
   336  		// try to load deleted entity from the server
   337  		var p *northwind.Product
   338  		err = session.Load(&p, productID)
   339  		if err != nil {
   340  			log.Fatalf("session.Load() failed with %s\n", err)
   341  		}
   342  
   343  		if p == nil {
   344  			fmt.Printf("Success: we deleted Product with this id so we get nil when we try to load it\n")
   345  		} else {
   346  			fmt.Printf("Error: this entity was deleted so we shouldn't be able to load it\n")
   347  		}
   348  
   349  		session.Close()
   350  	}
   351  }
   352  
   353  func crudDeleteUsingEntity() {
   354  	store, err := getDocumentStore(dbName)
   355  	if err != nil {
   356  		log.Fatalf("getDocumentStore() failed with %s\n", err)
   357  	}
   358  	defer store.Close()
   359  
   360  	// store a new entity and remember its id
   361  	var productID string
   362  	{
   363  		session, err := store.OpenSession("")
   364  		if err != nil {
   365  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   366  		}
   367  
   368  		product := &northwind.Product{
   369  			Name:         "iPhone X",
   370  			PricePerUnit: 999.99,
   371  			Category:     "electronics",
   372  		}
   373  		err = session.Store(product)
   374  		if err != nil {
   375  			log.Fatalf("session.Store() failed with %s\n", err)
   376  		}
   377  		productID = product.ID
   378  		err = session.SaveChanges()
   379  		if err != nil {
   380  			log.Fatalf("session.SaveChanges() failed with %s\n", err)
   381  		}
   382  
   383  		session.Close()
   384  	}
   385  
   386  	// delete the entity
   387  	{
   388  		session, err := store.OpenSession("")
   389  		if err != nil {
   390  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   391  		}
   392  
   393  		var p *northwind.Product
   394  		err = session.Load(&p, productID)
   395  		if err != nil {
   396  			log.Fatalf("session.Load() failed with %s\n", err)
   397  		}
   398  
   399  		err = session.Delete(p)
   400  		if err != nil {
   401  			log.Fatalf("session.Delete() failed with %s\n", err)
   402  		}
   403  
   404  		err = session.SaveChanges()
   405  		if err != nil {
   406  			log.Fatalf("session.SaveChanges() failed with %s\n", err)
   407  		}
   408  
   409  		session.Close()
   410  	}
   411  
   412  	// verify entity was deleted
   413  	{
   414  		session, err := store.OpenSession("")
   415  		if err != nil {
   416  			log.Fatalf("store.OpenSession() failed with %s\n", err)
   417  		}
   418  
   419  		// try to load deleted entity from the server
   420  		var p *northwind.Product
   421  		err = session.Load(&p, productID)
   422  		if err != nil {
   423  			log.Fatalf("session.Load() failed with %s\n", err)
   424  		}
   425  
   426  		if p == nil {
   427  			fmt.Printf("Success: we deleted Product with this id so we get nil when we try to load it\n")
   428  		} else {
   429  			fmt.Printf("Error: this entity was deleted so we shouldn't be able to load it\n")
   430  		}
   431  
   432  		session.Close()
   433  	}
   434  }
   435  
   436  // shows how to query collection of a given name
   437  func queryCollectionByName() {
   438  	store, session, err := openSession(dbName)
   439  	if err != nil {
   440  		log.Fatalf("openSession() failed with %s\n", err)
   441  	}
   442  	defer store.Close()
   443  	defer session.Close()
   444  
   445  	q := session.QueryCollection("employees")
   446  	printRQL(q)
   447  
   448  	var results []*northwind.Employee
   449  	err = q.GetResults(&results)
   450  	if err != nil {
   451  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   452  	}
   453  	if len(results) > 0 {
   454  		fmt.Print("First result:\n")
   455  		pretty.Print(results[0])
   456  	}
   457  }
   458  
   459  // shows how to query a collection for a given type
   460  func queryCollectionByType() {
   461  	store, session, err := openSession(dbName)
   462  	if err != nil {
   463  		log.Fatalf("openSession() failed with %s\n", err)
   464  	}
   465  	defer store.Close()
   466  	defer session.Close()
   467  
   468  	tp := reflect.TypeOf(&northwind.Employee{})
   469  	q := session.QueryCollectionForType(tp)
   470  	printRQL(q)
   471  
   472  	var results []*northwind.Employee
   473  	err = q.GetResults(&results)
   474  	if err != nil {
   475  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   476  	}
   477  	fmt.Printf("Query returned %d results\n", len(results))
   478  	if len(results) > 0 {
   479  		fmt.Print("First result:\n")
   480  		pretty.Print(results[0])
   481  	}
   482  }
   483  
   484  func queryIndex() {
   485  	store, session, err := openSession(dbName)
   486  	if err != nil {
   487  		log.Fatalf("openSession() failed with %s\n", err)
   488  	}
   489  	defer store.Close()
   490  	defer session.Close()
   491  
   492  	q := session.QueryIndex("Orders/ByCompany")
   493  	printRQL(q)
   494  
   495  	// we're using anonymous struct whose definition matches
   496  	// the fields of in the index
   497  	var results []*struct {
   498  		Company    string
   499  		Count      int
   500  		TotalValue float64 `json:"Total"`
   501  	}
   502  	err = q.GetResults(&results)
   503  	if err != nil {
   504  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   505  	}
   506  	fmt.Printf("Query returned %d results\n", len(results))
   507  	if len(results) > 0 {
   508  		fmt.Print("First result:\n")
   509  		pretty.Print(results[0])
   510  	}
   511  }
   512  
   513  // shows how to use First() to get first result
   514  func queryFirst() {
   515  	store, session, err := openSession(dbName)
   516  	if err != nil {
   517  		log.Fatalf("openSession() failed with %s\n", err)
   518  	}
   519  	defer store.Close()
   520  	defer session.Close()
   521  
   522  	tp := reflect.TypeOf(&northwind.Employee{})
   523  	q := session.QueryCollectionForType(tp)
   524  	printRQL(q)
   525  
   526  	var first *northwind.Employee
   527  	err = q.First(&first)
   528  	if err != nil {
   529  		log.Fatalf("q.First() failed with '%s'\n", err)
   530  	}
   531  	// if there are no matching results, first will be unchanged (i.e. equal to nil)
   532  	if first != nil {
   533  		fmt.Print("First() returned:\n")
   534  		pretty.Print(first)
   535  	}
   536  }
   537  
   538  func queryComplex() {
   539  	store, session, err := openSession(dbName)
   540  	if err != nil {
   541  		log.Fatalf("openSession() failed with %s\n", err)
   542  	}
   543  	defer store.Close()
   544  	defer session.Close()
   545  
   546  	tp := reflect.TypeOf(&northwind.Product{})
   547  	q := session.QueryCollectionForType(tp)
   548  	q = q.WaitForNonStaleResults(0)
   549  	q = q.WhereEquals("Name", "iPhone X")
   550  	q = q.OrderBy("PricePerUnit")
   551  	q = q.Take(2) // limit to 2 results
   552  	printRQL(q)
   553  
   554  	var results []*northwind.Product
   555  	err = q.GetResults(&results)
   556  	if err != nil {
   557  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   558  	}
   559  	fmt.Printf("Query returned %d results\n", len(results))
   560  	if len(results) > 0 {
   561  		fmt.Print("First result:\n")
   562  		pretty.Print(results[0])
   563  	}
   564  }
   565  
   566  func querySelectSingleField() {
   567  	store, session, err := openSession(dbName)
   568  	if err != nil {
   569  		log.Fatalf("openSession() failed with %s\n", err)
   570  	}
   571  	defer store.Close()
   572  	defer session.Close()
   573  
   574  	// RQL equivalent:
   575  	// from employees select FirstName
   576  	tp := reflect.TypeOf(&northwind.Employee{})
   577  	q := session.QueryCollectionForType(tp)
   578  	q = q.SelectFields(reflect.TypeOf(""), "FirstName")
   579  	printRQL(q)
   580  
   581  	var names []string
   582  	err = q.GetResults(&names)
   583  	if err != nil {
   584  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   585  	}
   586  	fmt.Printf("Query returned %d results\n", len(names))
   587  	if len(names) > 0 {
   588  		fmt.Printf("First name: %s\n", names[0])
   589  	}
   590  }
   591  
   592  type employeeNameTitle struct {
   593  	FirstName string
   594  	Title     string
   595  }
   596  
   597  func querySelectFields() {
   598  	store, session, err := openSession(dbName)
   599  	if err != nil {
   600  		log.Fatalf("openSession() failed with %s\n", err)
   601  	}
   602  	defer store.Close()
   603  	defer session.Close()
   604  
   605  	// RQL equivalent:
   606  	// from employees select FirstName, Title
   607  	tp := reflect.TypeOf(&northwind.Employee{})
   608  	q := session.QueryCollectionForType(tp)
   609  	q = q.SelectFields(reflect.TypeOf(&employeeNameTitle{}), "FirstName", "Title")
   610  	printRQL(q)
   611  
   612  	var results []*employeeNameTitle
   613  	err = q.GetResults(&results)
   614  	if err != nil {
   615  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   616  	}
   617  	fmt.Printf("Query returned %d results\n", len(results))
   618  	if len(results) > 0 {
   619  		fmt.Print("First result:\n")
   620  		pretty.Print(results[0])
   621  	}
   622  }
   623  
   624  func queryDistinct() {
   625  	store, session, err := openSession(dbName)
   626  	if err != nil {
   627  		log.Fatalf("openSession() failed with %s\n", err)
   628  	}
   629  	defer store.Close()
   630  	defer session.Close()
   631  
   632  	// RQL equivalent:
   633  	// from employees select distinct Title
   634  	tp := reflect.TypeOf(&northwind.Employee{})
   635  	q := session.QueryCollectionForType(tp)
   636  	q = q.SelectFields(reflect.TypeOf(""), "Title")
   637  	q = q.Distinct()
   638  	printRQL(q)
   639  
   640  	var results []string
   641  	err = q.GetResults(&results)
   642  	if err != nil {
   643  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   644  	}
   645  	fmt.Printf("Query returned %d results. Results: %#v\n", len(results), results)
   646  }
   647  
   648  func queryEquals() {
   649  	store, session, err := openSession(dbName)
   650  	if err != nil {
   651  		log.Fatalf("openSession() failed with %s\n", err)
   652  	}
   653  	defer store.Close()
   654  	defer session.Close()
   655  
   656  	// RQL equivalent:
   657  	// from employees where Title = 'Sales Representative'
   658  	tp := reflect.TypeOf(&northwind.Employee{})
   659  	q := session.QueryCollectionForType(tp)
   660  	q = q.WhereEquals("Title", "Sales Representative")
   661  	printRQL(q)
   662  
   663  	var results []*northwind.Employee
   664  	err = q.GetResults(&results)
   665  	if err != nil {
   666  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   667  	}
   668  	fmt.Printf("Query returned %d results\n", len(results))
   669  	if len(results) > 0 {
   670  		fmt.Print("First result:\n")
   671  		pretty.Print(results[0])
   672  	}
   673  }
   674  
   675  func queryIn() {
   676  	store, session, err := openSession(dbName)
   677  	if err != nil {
   678  		log.Fatalf("openSession() failed with %s\n", err)
   679  	}
   680  	defer store.Close()
   681  	defer session.Close()
   682  
   683  	// RQL equivalent:
   684  	// from employees where Title in ['Sales Representative', 'Sales Manager']
   685  	tp := reflect.TypeOf(&northwind.Employee{})
   686  	q := session.QueryCollectionForType(tp)
   687  	q = q.WhereIn("Title", []interface{}{"Sales Representative", "Sales Manager"})
   688  	printRQL(q)
   689  
   690  	var results []*northwind.Employee
   691  	err = q.GetResults(&results)
   692  	if err != nil {
   693  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   694  	}
   695  	fmt.Printf("Query returned %d results\n", len(results))
   696  	if len(results) > 0 {
   697  		fmt.Print("First result:\n")
   698  		pretty.Print(results[0])
   699  	}
   700  }
   701  
   702  func queryStartsWith() {
   703  	store, session, err := openSession(dbName)
   704  	if err != nil {
   705  		log.Fatalf("openSession() failed with %s\n", err)
   706  	}
   707  	defer store.Close()
   708  	defer session.Close()
   709  
   710  	// RQL equivalent:
   711  	// from employees where startsWith('Ro')
   712  	tp := reflect.TypeOf(&northwind.Employee{})
   713  	q := session.QueryCollectionForType(tp)
   714  	q = q.WhereStartsWith("FirstName", "Ro")
   715  	printRQL(q)
   716  
   717  	var results []*northwind.Employee
   718  	err = q.GetResults(&results)
   719  	if err != nil {
   720  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   721  	}
   722  	fmt.Printf("Query returned %d results\n", len(results))
   723  	if len(results) > 0 {
   724  		fmt.Print("First result:\n")
   725  		pretty.Print(results[0])
   726  	}
   727  }
   728  
   729  func queryEndsWith() {
   730  	store, session, err := openSession(dbName)
   731  	if err != nil {
   732  		log.Fatalf("openSession() failed with %s\n", err)
   733  	}
   734  	defer store.Close()
   735  	defer session.Close()
   736  
   737  	// RQL equivalent:
   738  	// from employees where endsWith('rt')
   739  	tp := reflect.TypeOf(&northwind.Employee{})
   740  	q := session.QueryCollectionForType(tp)
   741  	q = q.WhereEndsWith("FirstName", "rt")
   742  	printRQL(q)
   743  
   744  	var results []*northwind.Employee
   745  	err = q.GetResults(&results)
   746  	if err != nil {
   747  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   748  	}
   749  	fmt.Printf("Query returned %d results\n", len(results))
   750  	if len(results) > 0 {
   751  		fmt.Print("First result:\n")
   752  		pretty.Print(results[0])
   753  	}
   754  }
   755  
   756  func queryBetween() {
   757  	store, session, err := openSession(dbName)
   758  	if err != nil {
   759  		log.Fatalf("openSession() failed with %s\n", err)
   760  	}
   761  	defer store.Close()
   762  	defer session.Close()
   763  
   764  	// RQL equivalent:
   765  	// from orders where Freight between 11 and 13
   766  	tp := reflect.TypeOf(&northwind.Order{})
   767  	q := session.QueryCollectionForType(tp)
   768  	q = q.WhereBetween("Freight", 11, 13)
   769  	printRQL(q)
   770  
   771  	var results []*northwind.Order
   772  	err = q.GetResults(&results)
   773  	if err != nil {
   774  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   775  	}
   776  	fmt.Printf("Query returned %d results\n", len(results))
   777  	if len(results) > 0 {
   778  		fmt.Print("First result:\n")
   779  		pretty.Print(results[0])
   780  	}
   781  }
   782  
   783  func queryGreater() {
   784  	store, session, err := openSession(dbName)
   785  	if err != nil {
   786  		log.Fatalf("openSession() failed with %s\n", err)
   787  	}
   788  	defer store.Close()
   789  	defer session.Close()
   790  
   791  	// RQL equivalent:
   792  	// from orders where Freight Freight > 11
   793  	tp := reflect.TypeOf(&northwind.Order{})
   794  	q := session.QueryCollectionForType(tp)
   795  	// can also be WhereGreaterThanOrEqual(), WhereLessThan(), WhereLessThanOrEqual()
   796  	q = q.WhereGreaterThan("Freight", 11)
   797  	printRQL(q)
   798  
   799  	var results []*northwind.Order
   800  	err = q.GetResults(&results)
   801  	if err != nil {
   802  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   803  	}
   804  	fmt.Printf("Query returned %d results\n", len(results))
   805  	if len(results) > 0 {
   806  		fmt.Print("First result:\n")
   807  		pretty.Print(results[0])
   808  	}
   809  }
   810  
   811  func queryExists() {
   812  	store, session, err := openSession(dbName)
   813  	if err != nil {
   814  		log.Fatalf("openSession() failed with %s\n", err)
   815  	}
   816  	defer store.Close()
   817  	defer session.Close()
   818  
   819  	// RQL equivalent:
   820  	// from employees where exists ("ReportsTo")
   821  	tp := reflect.TypeOf(&northwind.Employee{})
   822  	q := session.QueryCollectionForType(tp)
   823  	q = q.WhereExists("ReportsTo")
   824  	printRQL(q)
   825  
   826  	var results []*northwind.Employee
   827  	err = q.GetResults(&results)
   828  	if err != nil {
   829  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   830  	}
   831  	fmt.Printf("Query returned %d results\n", len(results))
   832  	if len(results) > 0 {
   833  		fmt.Print("First result:\n")
   834  		pretty.Print(results[0])
   835  	}
   836  }
   837  
   838  func queryContainsAny() {
   839  	store, session, err := openSession(dbName)
   840  	if err != nil {
   841  		log.Fatalf("openSession() failed with %s\n", err)
   842  	}
   843  	defer store.Close()
   844  	defer session.Close()
   845  
   846  	// RQL equivalent:
   847  	// from employees where FirstName in ("Anne", "Nancy")
   848  	tp := reflect.TypeOf(&northwind.Employee{})
   849  	q := session.QueryCollectionForType(tp)
   850  	// can also be ContainsAll()
   851  	q = q.ContainsAny("FirstName", []interface{}{"Anne", "Nancy"})
   852  	printRQL(q)
   853  
   854  	var results []*northwind.Employee
   855  	err = q.GetResults(&results)
   856  	if err != nil {
   857  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   858  	}
   859  	fmt.Printf("Query returned %d results\n", len(results))
   860  	if len(results) > 0 {
   861  		fmt.Print("First result:\n")
   862  		pretty.Print(results[0])
   863  	}
   864  }
   865  
   866  func querySearch() {
   867  	store, session, err := openSession(dbName)
   868  	if err != nil {
   869  		log.Fatalf("openSession() failed with %s\n", err)
   870  	}
   871  	defer store.Close()
   872  	defer session.Close()
   873  
   874  	// RQL equivalent:
   875  	// from employees where search(FirstName, 'Anne Nancy')
   876  	tp := reflect.TypeOf(&northwind.Employee{})
   877  	q := session.QueryCollectionForType(tp)
   878  	q = q.Search("FirstName", "Anne Nancy")
   879  	printRQL(q)
   880  
   881  	var results []*northwind.Employee
   882  	err = q.GetResults(&results)
   883  	if err != nil {
   884  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   885  	}
   886  	fmt.Printf("Query returned %d results\n", len(results))
   887  	if len(results) > 0 {
   888  		fmt.Print("First result:\n")
   889  		pretty.Print(results[0])
   890  	}
   891  }
   892  
   893  func querySubclause() {
   894  	store, session, err := openSession(dbName)
   895  	if err != nil {
   896  		log.Fatalf("openSession() failed with %s\n", err)
   897  	}
   898  	defer store.Close()
   899  	defer session.Close()
   900  
   901  	// RQL equivalent:
   902  	// from employees where (FirstName = 'Steven') or (Title = 'Sales Representative' and LastName = 'Davolio')
   903  	tp := reflect.TypeOf(&northwind.Employee{})
   904  	q := session.QueryCollectionForType(tp)
   905  	q = q.WhereEquals("FirstName", "Steven")
   906  	q = q.OrElse()
   907  	q = q.OpenSubclause()
   908  	q = q.WhereEquals("Title", "Sales Representative")
   909  	q = q.WhereEquals("LastName", "Davolio")
   910  	q = q.CloseSubclause()
   911  	printRQL(q)
   912  
   913  	var results []*northwind.Employee
   914  	err = q.GetResults(&results)
   915  	if err != nil {
   916  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   917  	}
   918  	fmt.Printf("Query returned %d results\n", len(results))
   919  	if len(results) > 0 {
   920  		fmt.Print("First result:\n")
   921  		pretty.Print(results[0])
   922  	}
   923  }
   924  
   925  func queryNot() {
   926  	store, session, err := openSession(dbName)
   927  	if err != nil {
   928  		log.Fatalf("openSession() failed with %s\n", err)
   929  	}
   930  	defer store.Close()
   931  	defer session.Close()
   932  
   933  	// RQL equivalent:
   934  	// from employees where not FirstName = 'Steven'
   935  	tp := reflect.TypeOf(&northwind.Employee{})
   936  	q := session.QueryCollectionForType(tp)
   937  	q = q.Not()
   938  	q = q.WhereEquals("FirstName", "Steven")
   939  	printRQL(q)
   940  
   941  	var results []*northwind.Employee
   942  	err = q.GetResults(&results)
   943  	if err != nil {
   944  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   945  	}
   946  	fmt.Printf("Query returned %d results\n", len(results))
   947  	if len(results) > 0 {
   948  		fmt.Print("First result:\n")
   949  		pretty.Print(results[0])
   950  	}
   951  }
   952  
   953  func queryOrElse() {
   954  	store, session, err := openSession(dbName)
   955  	if err != nil {
   956  		log.Fatalf("openSession() failed with %s\n", err)
   957  	}
   958  	defer store.Close()
   959  	defer session.Close()
   960  
   961  	// RQL equivalent:
   962  	// from employees where FirstName = 'Steven' or FirstName  = 'Nancy'
   963  	tp := reflect.TypeOf(&northwind.Employee{})
   964  	q := session.QueryCollectionForType(tp)
   965  	q = q.WhereEquals("FirstName", "Steven")
   966  	// can also be AndElse()
   967  	q = q.OrElse()
   968  	q = q.WhereEquals("FirstName", "Nancy")
   969  	printRQL(q)
   970  
   971  	var results []*northwind.Employee
   972  	err = q.GetResults(&results)
   973  	if err != nil {
   974  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
   975  	}
   976  	fmt.Printf("Query returned %d results\n", len(results))
   977  	if len(results) > 0 {
   978  		fmt.Print("First result:\n")
   979  		pretty.Print(results[0])
   980  	}
   981  }
   982  
   983  func queryOrderBy() {
   984  	store, session, err := openSession(dbName)
   985  	if err != nil {
   986  		log.Fatalf("openSession() failed with %s\n", err)
   987  	}
   988  	defer store.Close()
   989  	defer session.Close()
   990  
   991  	// RQL equivalent:
   992  	// from employees order by FirstName
   993  	tp := reflect.TypeOf(&northwind.Employee{})
   994  	q := session.QueryCollectionForType(tp)
   995  	// can also be RandomOrdering()
   996  	q = q.OrderBy("FirstName")
   997  	printRQL(q)
   998  
   999  	var results []*northwind.Employee
  1000  	err = q.GetResults(&results)
  1001  	if err != nil {
  1002  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
  1003  	}
  1004  	fmt.Printf("Query returned %d results\n", len(results))
  1005  	if len(results) > 0 {
  1006  		fmt.Print("First result:\n")
  1007  		pretty.Print(results[0])
  1008  	}
  1009  }
  1010  
  1011  func queryTake() {
  1012  	store, session, err := openSession(dbName)
  1013  	if err != nil {
  1014  		log.Fatalf("openSession() failed with %s\n", err)
  1015  	}
  1016  	defer store.Close()
  1017  	defer session.Close()
  1018  
  1019  	// RQL equivalent:
  1020  	// from employees order by FirstName desc
  1021  	tp := reflect.TypeOf(&northwind.Employee{})
  1022  	q := session.QueryCollectionForType(tp)
  1023  	q = q.OrderByDescending("FirstName")
  1024  	q = q.Take(2)
  1025  	printRQL(q)
  1026  
  1027  	var results []*northwind.Employee
  1028  	err = q.GetResults(&results)
  1029  	if err != nil {
  1030  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
  1031  	}
  1032  	fmt.Printf("Query returned %d results\n", len(results))
  1033  	if len(results) > 0 {
  1034  		fmt.Print("First result:\n")
  1035  		pretty.Print(results[0])
  1036  	}
  1037  }
  1038  
  1039  func querySkip() {
  1040  	store, session, err := openSession(dbName)
  1041  	if err != nil {
  1042  		log.Fatalf("openSession() failed with %s\n", err)
  1043  	}
  1044  	defer store.Close()
  1045  	defer session.Close()
  1046  
  1047  	// RQL equivalent:
  1048  	// from employees order by FirstName desc
  1049  	tp := reflect.TypeOf(&northwind.Employee{})
  1050  	q := session.QueryCollectionForType(tp)
  1051  	q = q.OrderByDescending("FirstName")
  1052  	q = q.Take(2)
  1053  	q = q.Skip(1)
  1054  	printRQL(q)
  1055  
  1056  	var results []*northwind.Employee
  1057  	err = q.GetResults(&results)
  1058  	if err != nil {
  1059  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
  1060  	}
  1061  	fmt.Printf("Query returned %d results\n", len(results))
  1062  	if len(results) > 0 {
  1063  		fmt.Print("First result:\n")
  1064  		pretty.Print(results[0])
  1065  	}
  1066  }
  1067  
  1068  func queryStatistics() {
  1069  	store, session, err := openSession(dbName)
  1070  	if err != nil {
  1071  		log.Fatalf("openSession() failed with %s\n", err)
  1072  	}
  1073  	defer store.Close()
  1074  	defer session.Close()
  1075  
  1076  	var stats *ravendb.QueryStatistics
  1077  	tp := reflect.TypeOf(&northwind.Employee{})
  1078  	q := session.QueryCollectionForType(tp)
  1079  	q = q.WhereGreaterThan("FirstName", "Bernard")
  1080  	q = q.OrderByDescending("FirstName")
  1081  	q.Statistics(&stats)
  1082  	printRQL(q)
  1083  
  1084  	var results []*northwind.Employee
  1085  	err = q.GetResults(&results)
  1086  	if err != nil {
  1087  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
  1088  	}
  1089  	fmt.Printf("Query returned %d results\n", len(results))
  1090  	fmt.Printf("Statistics:\n")
  1091  	pretty.Print(stats)
  1092  }
  1093  
  1094  func querySingle() {
  1095  	store, session, err := openSession(dbName)
  1096  	if err != nil {
  1097  		log.Fatalf("openSession() failed with %s\n", err)
  1098  	}
  1099  	defer store.Close()
  1100  	defer session.Close()
  1101  
  1102  	tp := reflect.TypeOf(&northwind.Employee{})
  1103  	q := session.QueryCollectionForType(tp)
  1104  	q = q.WhereEquals("LastName", "Davolio")
  1105  	printRQL(q)
  1106  
  1107  	var result *northwind.Employee
  1108  	err = q.Single(&result)
  1109  	if err != nil {
  1110  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
  1111  	}
  1112  	fmt.Printf("Query returned:\n")
  1113  	pretty.Print(result)
  1114  }
  1115  
  1116  func queryCount() {
  1117  	store, session, err := openSession(dbName)
  1118  	if err != nil {
  1119  		log.Fatalf("openSession() failed with %s\n", err)
  1120  	}
  1121  	defer store.Close()
  1122  	defer session.Close()
  1123  
  1124  	tp := reflect.TypeOf(&northwind.Employee{})
  1125  	q := session.QueryCollectionForType(tp)
  1126  	q = q.WhereGreaterThan("LastName", "Davolio")
  1127  	printRQL(q)
  1128  
  1129  	n, err := q.Count()
  1130  	if err != nil {
  1131  		log.Fatalf("q.GetResults() failed with '%s'\n", err)
  1132  	}
  1133  	fmt.Printf("Query returned %d results\n", n)
  1134  }
  1135  
  1136  // auto-detect path to "examples" directory
  1137  func dataDir() string {
  1138  	dir := "."
  1139  	_, err := os.Stat("examples")
  1140  	if err == nil {
  1141  		dir = "examples"
  1142  	}
  1143  	path, err := filepath.Abs(dir)
  1144  	if err != nil {
  1145  		log.Fatalf("filepath.Abs() failed with '%s'\n", err)
  1146  	}
  1147  	return path
  1148  }
  1149  
  1150  func storeAttachments() string {
  1151  	store, session, err := openSession(dbName)
  1152  	if err != nil {
  1153  		log.Fatalf("openSession() failed with %s\n", err)
  1154  	}
  1155  	defer store.Close()
  1156  	defer session.Close()
  1157  
  1158  	e := &northwind.Employee{
  1159  		FirstName: "Jon",
  1160  		LastName:  "Snow",
  1161  	}
  1162  	err = session.Store(e)
  1163  	if err != nil {
  1164  		log.Fatalf("session.Store() failed with '%s'\n", err)
  1165  	}
  1166  
  1167  	path := filepath.Join(dataDir(), "pic.png")
  1168  	fileStream, err := os.Open(path)
  1169  	if err != nil {
  1170  		log.Fatalf("os.Open() failed with '%s'\n", err)
  1171  	}
  1172  	defer fileStream.Close()
  1173  
  1174  	fmt.Printf("new employee id: %s\n", e.ID)
  1175  	err = session.Advanced().Attachments().Store(e, "photo.png", fileStream, "image/png")
  1176  
  1177  	// could also be done using document id
  1178  	// err = session.Advanced().Attachments().Store(e.ID, "photo.png", fileStream, "image/png")
  1179  
  1180  	if err != nil {
  1181  		log.Fatalf("session.Advanced().Attachments().Store() failed with '%s'\n", err)
  1182  	}
  1183  
  1184  	err = session.SaveChanges()
  1185  	if err != nil {
  1186  		log.Fatalf("session.SaveChanges() failed with '%s'\n", err)
  1187  	}
  1188  
  1189  	return e.ID
  1190  }
  1191  
  1192  func getAttachments() {
  1193  	docID := storeAttachments()
  1194  	store, session, err := openSession(dbName)
  1195  	if err != nil {
  1196  		log.Fatalf("openSession() failed with %s\n", err)
  1197  	}
  1198  	defer store.Close()
  1199  	defer session.Close()
  1200  
  1201  	attachment, err := session.Advanced().Attachments().GetByID(docID, "photo.png")
  1202  	if err != nil {
  1203  		log.Fatalf("session.Advanced().Attachments().Get() failed with '%s'\n", err)
  1204  	}
  1205  	defer attachment.Close()
  1206  	fmt.Print("Attachment details:\n")
  1207  	pretty.Print(attachment.Details)
  1208  	// read attachment data
  1209  	// attachment.Data is io.Reader
  1210  	var attachmentData bytes.Buffer
  1211  	n, err := io.Copy(&attachmentData, attachment.Data)
  1212  	if err != nil {
  1213  		log.Fatalf("io.Copy() failed with '%s'\n", err)
  1214  	}
  1215  	fmt.Printf("Attachment size: %d bytes\n", n)
  1216  }
  1217  
  1218  func checkAttachmentExists() {
  1219  	docID := storeAttachments()
  1220  	store, session, err := openSession(dbName)
  1221  	if err != nil {
  1222  		log.Fatalf("openSession() failed with %s\n", err)
  1223  	}
  1224  	defer store.Close()
  1225  	defer session.Close()
  1226  
  1227  	{
  1228  		name := "photo.png"
  1229  		exists, err := session.Advanced().Attachments().Exists(docID, name)
  1230  		if err != nil {
  1231  			log.Fatalf("session.Advanced().Attachments().Exists() failed with '%s'\n", err)
  1232  		}
  1233  		if exists {
  1234  			fmt.Printf("attachment '%s' exists\n", name)
  1235  		} else {
  1236  			fmt.Printf("attachment '%s' doesn't exists\n", name)
  1237  		}
  1238  	}
  1239  
  1240  	{
  1241  		name := "non-existent.png"
  1242  		exists, err := session.Advanced().Attachments().Exists(docID, name)
  1243  		if err != nil {
  1244  			log.Fatalf("session.Advanced().Attachments().Exists() failed with '%s'\n", err)
  1245  		}
  1246  		if exists {
  1247  			fmt.Printf("attachment '%s' exists\n", name)
  1248  		} else {
  1249  			fmt.Printf("attachment '%s' doesn't exists\n", name)
  1250  		}
  1251  	}
  1252  }
  1253  
  1254  func getAttachmentNames() {
  1255  	docID := storeAttachments()
  1256  	store, session, err := openSession(dbName)
  1257  	if err != nil {
  1258  		log.Fatalf("openSession() failed with %s\n", err)
  1259  	}
  1260  	defer store.Close()
  1261  	defer session.Close()
  1262  
  1263  	var doc *northwind.Employee
  1264  	err = session.Load(&doc, docID)
  1265  	if err != nil {
  1266  		log.Fatalf("session.Load() failed with '%s'\n", err)
  1267  	}
  1268  
  1269  	names, err := session.Advanced().Attachments().GetNames(doc)
  1270  	if err != nil {
  1271  		log.Fatalf("session.Advanced().Attachments().GetNames() failed with '%s'\n", err)
  1272  	}
  1273  	fmt.Print("Attachment names:\n")
  1274  	pretty.Print(names)
  1275  }
  1276  
  1277  func bulkInsert() {
  1278  	store, session, err := openSession(dbName)
  1279  	if err != nil {
  1280  		log.Fatalf("openSession() failed with %s\n", err)
  1281  	}
  1282  	defer store.Close()
  1283  	defer session.Close()
  1284  
  1285  	bulkInsert := store.BulkInsert("")
  1286  
  1287  	names := []string{"Anna", "Maria", "Miguel", "Emanuel", "Dayanara", "Aleida"}
  1288  	var ids []string
  1289  	for _, name := range names {
  1290  		e := &northwind.Employee{
  1291  			FirstName: name,
  1292  		}
  1293  		id, err := bulkInsert.Store(e, nil)
  1294  		if err != nil {
  1295  			log.Fatalf("bulkInsert.Store() failed with '%s'\n", err)
  1296  		}
  1297  		ids = append(ids, id)
  1298  	}
  1299  	// flush data and finish
  1300  	err = bulkInsert.Close()
  1301  	if err != nil {
  1302  		log.Fatalf("bulkInsert.Close() failed with '%s'\n", err)
  1303  	}
  1304  
  1305  	fmt.Printf("Finished %d documents with ids: %v\n", len(names), ids)
  1306  }
  1307  
  1308  func changes() {
  1309  	store, session, err := openSession(dbName)
  1310  	if err != nil {
  1311  		log.Fatalf("openSession() failed with %s\n", err)
  1312  	}
  1313  	defer session.Close()
  1314  	defer store.Close()
  1315  
  1316  	changes := store.Changes("")
  1317  
  1318  	err = changes.EnsureConnectedNow()
  1319  	if err != nil {
  1320  		log.Fatalf("changes.EnsureConnectedNow() failed with '%s' of type %T\n", err, err)
  1321  	}
  1322  
  1323  	// wg is to signal main goroutine a change was received
  1324  	// in a real program you would not do that
  1325  	chChanges := make(chan *ravendb.DocumentChange, 16)
  1326  	cb := func(change *ravendb.DocumentChange) {
  1327  		fmt.Print("change:\n")
  1328  		pretty.Print(change)
  1329  		chChanges <- change
  1330  	}
  1331  	docChangesCancel, err := changes.ForAllDocuments(cb)
  1332  	if err != nil {
  1333  		log.Fatalf("changes.ForAllDocuments() failed with '%s'\n", err)
  1334  	}
  1335  
  1336  	defer docChangesCancel()
  1337  
  1338  	e := &northwind.Employee{
  1339  		FirstName: "Jon",
  1340  		LastName:  "Snow",
  1341  	}
  1342  	err = session.Store(e)
  1343  	if err != nil {
  1344  		log.Fatalf("session.Store() failed with '%s'\n", err)
  1345  	}
  1346  
  1347  	err = session.SaveChanges()
  1348  	if err != nil {
  1349  		log.Fatalf("session.SaveChanges() failed with '%s'\n", err)
  1350  	}
  1351  
  1352  	fmt.Print("Waiting for the change\n")
  1353  	timeStart := time.Now()
  1354  	// wait to receive at least one notofication
  1355  	select {
  1356  	case <-chChanges:
  1357  	// no-op
  1358  	case <-time.After(time.Second):
  1359  		// timed out
  1360  		fmt.Printf("Timed out waiting for a notificaiton\n")
  1361  	}
  1362  	fmt.Printf("Took %s to receive change notifications\n", time.Since(timeStart))
  1363  }
  1364  
  1365  func streamWithIDPrefix() {
  1366  	store, session, err := openSession(dbName)
  1367  	if err != nil {
  1368  		log.Fatalf("openSession() failed with %s\n", err)
  1369  	}
  1370  	defer store.Close()
  1371  	defer session.Close()
  1372  
  1373  	args := &ravendb.StartsWithArgs{
  1374  		StartsWith: "products/",
  1375  	}
  1376  	iterator, err := session.Advanced().Stream(args)
  1377  	if err != nil {
  1378  		log.Fatalf("session.Advanced().Stream() failed with '%s'\n", err)
  1379  	}
  1380  	n := 0
  1381  	for {
  1382  		var p *northwind.Product
  1383  		streamResult, err := iterator.Next(&p)
  1384  		if err != nil {
  1385  			// io.EOF means there are no more results
  1386  			if err == io.EOF {
  1387  				err = nil
  1388  			} else {
  1389  				log.Fatalf("iterator.Next() failed with '%s'\n", err)
  1390  			}
  1391  			break
  1392  		}
  1393  		if n < 1 {
  1394  			fmt.Print("streamResult:\n")
  1395  			pretty.Print(streamResult)
  1396  			fmt.Print("metadata:\n")
  1397  			pretty.Print(streamResult.Metadata.EntrySet())
  1398  			fmt.Print("product:\n")
  1399  			pretty.Print(p)
  1400  			fmt.Print("\n")
  1401  		}
  1402  		n++
  1403  	}
  1404  	fmt.Printf("Got %d results\n", n)
  1405  }
  1406  
  1407  func streamQueryResults() {
  1408  	store, session, err := openSession(dbName)
  1409  	if err != nil {
  1410  		log.Fatalf("openSession() failed with %s\n", err)
  1411  	}
  1412  	defer store.Close()
  1413  	defer session.Close()
  1414  
  1415  	tp := reflect.TypeOf(&northwind.Product{})
  1416  	q := session.QueryCollectionForType(tp)
  1417  	q = q.WhereGreaterThan("PricePerUnit", 15)
  1418  	q = q.OrderByDescending("PricePerUnit")
  1419  
  1420  	iterator, err := session.Advanced().StreamQuery(q, nil)
  1421  	if err != nil {
  1422  		log.Fatalf("session.Advanced().StreamQuery() failed with '%s'\n", err)
  1423  	}
  1424  	n := 0
  1425  	for {
  1426  		var p *northwind.Product
  1427  		streamResult, err := iterator.Next(&p)
  1428  		if err != nil {
  1429  			// io.EOF means there are no more results
  1430  			if err == io.EOF {
  1431  				err = nil
  1432  			} else {
  1433  				log.Fatalf("iterator.Next() failed with '%s'\n", err)
  1434  			}
  1435  			break
  1436  		}
  1437  		if n < 1 {
  1438  			fmt.Print("streamResult:\n")
  1439  			pretty.Print(streamResult)
  1440  			fmt.Print("product:\n")
  1441  			pretty.Print(p)
  1442  			fmt.Print("\n")
  1443  		}
  1444  		n++
  1445  	}
  1446  	fmt.Printf("Got %d results\n", n)
  1447  }
  1448  
  1449  func setupRevisions(store *ravendb.DocumentStore, purgeOnDelete bool, minimumRevisionsToKeep int64) (*ravendb.ConfigureRevisionsOperationResult, error) {
  1450  
  1451  	revisionsConfiguration := &ravendb.RevisionsConfiguration{}
  1452  	defaultCollection := &ravendb.RevisionsCollectionConfiguration{}
  1453  	defaultCollection.PurgeOnDelete = purgeOnDelete
  1454  	defaultCollection.MinimumRevisionsToKeep = minimumRevisionsToKeep
  1455  
  1456  	revisionsConfiguration.DefaultConfig = defaultCollection
  1457  	operation := ravendb.NewConfigureRevisionsOperation(revisionsConfiguration)
  1458  
  1459  	err := store.Maintenance().Send(operation)
  1460  	if err != nil {
  1461  		return nil, err
  1462  	}
  1463  
  1464  	return operation.Command.Result, nil
  1465  }
  1466  
  1467  func revisions() {
  1468  	store, session, err := openSession(dbName)
  1469  	if err != nil {
  1470  		log.Fatalf("openSession() failed with %s\n", err)
  1471  	}
  1472  	defer store.Close()
  1473  	defer session.Close()
  1474  
  1475  	// first must configure the store to enable revisions
  1476  	_, err = setupRevisions(store, true, 5)
  1477  	if err != nil {
  1478  		log.Fatalf("setupRevisions() failed with '%s'\n", err)
  1479  	}
  1480  
  1481  	e := &northwind.Employee{
  1482  		FirstName: "Jon",
  1483  		LastName:  "Snow",
  1484  	}
  1485  	err = session.Store(e)
  1486  	if err != nil {
  1487  		log.Fatalf("session.Store() failed with '%s'\n", err)
  1488  	}
  1489  	err = session.SaveChanges()
  1490  	if err != nil {
  1491  		log.Fatalf("session.SaveChanges() failed with '%s'\n", err)
  1492  	}
  1493  
  1494  	// modify document to create a new revision
  1495  	e.FirstName = "Jhonny"
  1496  	err = session.SaveChanges()
  1497  	if err != nil {
  1498  		log.Fatalf("session.SaveChanges() failed with '%s'\n", err)
  1499  	}
  1500  
  1501  	var revisions []*northwind.Employee
  1502  	err = session.Advanced().Revisions().GetFor(&revisions, e.ID)
  1503  	if err != nil {
  1504  		log.Fatalf(" session.Advanced().Revisions().GetFor() failed with '%s'\n", err)
  1505  	}
  1506  	pretty.Print(revisions)
  1507  }
  1508  
  1509  func suggestions() {
  1510  	store, session, err := openSession(dbName)
  1511  	if err != nil {
  1512  		log.Fatalf("openSession() failed with %s\n", err)
  1513  	}
  1514  	defer store.Close()
  1515  	defer session.Close()
  1516  
  1517  	index := ravendb.NewIndexCreationTask("EmployeeIndex")
  1518  	index.Map = "from doc in docs.Employees select new { doc.FirstName }"
  1519  	index.Suggestion("FirstName")
  1520  
  1521  	err = store.ExecuteIndex(index, "")
  1522  	if err != nil {
  1523  		log.Fatalf("store.ExecuteIndex() failed with '%s'\n", err)
  1524  	}
  1525  
  1526  	tp := reflect.TypeOf(&northwind.Employee{})
  1527  	q := session.QueryCollectionForType(tp)
  1528  	su := ravendb.NewSuggestionWithTerm("FirstName")
  1529  	su.Term = "Micael"
  1530  	suggestionQuery := q.SuggestUsing(su)
  1531  	results, err := suggestionQuery.Execute()
  1532  	if err != nil {
  1533  		log.Fatalf("suggestionQuery.Execute() failed with '%s'\n", err)
  1534  	}
  1535  	pretty.Print(results)
  1536  }
  1537  
  1538  func advancedPatching() {
  1539  	store, session, err := openSession(dbName)
  1540  	if err != nil {
  1541  		log.Fatalf("openSession() failed with %s\n", err)
  1542  	}
  1543  	defer store.Close()
  1544  	defer session.Close()
  1545  
  1546  	product := &northwind.Product{
  1547  		Name:         "iPhone X",
  1548  		PricePerUnit: 50,
  1549  		Category:     "electronics",
  1550  		ReorderLevel: 15,
  1551  	}
  1552  	err = session.Store(product)
  1553  	if err != nil {
  1554  		log.Fatalf("session.Store() failed with %s\n", err)
  1555  	}
  1556  	fmt.Printf("Product ID: %s\n", product.ID)
  1557  	err = session.SaveChanges()
  1558  	if err != nil {
  1559  		log.Fatalf("session.SaveChanges() failed with %s\n", err)
  1560  	}
  1561  
  1562  	err = session.Advanced().IncrementByID(product.ID, "PricePerUnit", 15)
  1563  	if err != nil {
  1564  		log.Fatalf("session.Advanced().IncrementByID() failed with %s\n", err)
  1565  	}
  1566  
  1567  	err = session.Advanced().Patch(product, "Category", "expensive products")
  1568  	if err != nil {
  1569  		log.Fatalf("session.Advanced().PatchEntity() failed with %s\n", err)
  1570  	}
  1571  
  1572  	err = session.SaveChanges()
  1573  	if err != nil {
  1574  		log.Fatalf("session.SaveChanges() failed with %s\n", err)
  1575  	}
  1576  
  1577  	{
  1578  		newSession, err := store.OpenSession("")
  1579  		if err != nil {
  1580  			log.Fatalf("store.OpenSession() failed with %s\n", err)
  1581  		}
  1582  
  1583  		var p *northwind.Product
  1584  		err = newSession.Load(&p, product.ID)
  1585  		if err != nil {
  1586  			log.Fatalf("newSession.Load() failed with %s\n", err)
  1587  		}
  1588  		pretty.Print(p)
  1589  
  1590  		newSession.Close()
  1591  	}
  1592  }
  1593  
  1594  func subscriptions() {
  1595  	store, session, err := openSession(dbName)
  1596  	if err != nil {
  1597  		log.Fatalf("openSession() failed with %s\n", err)
  1598  	}
  1599  	defer store.Close()
  1600  	defer session.Close()
  1601  
  1602  	opts := ravendb.SubscriptionCreationOptions{
  1603  		Query: "from Products where PricePerUnit > 17 and PricePerUnit < 19",
  1604  	}
  1605  	tp := reflect.TypeOf(&northwind.Product{})
  1606  	subscriptionName, err := store.Subscriptions().Create(&opts, "")
  1607  	if err != nil {
  1608  		log.Fatalf("store.Subscriptions().Create() failed with %s\n", err)
  1609  	}
  1610  	wopts := ravendb.NewSubscriptionWorkerOptions(subscriptionName)
  1611  	worker, err := store.Subscriptions().GetSubscriptionWorker(tp, wopts, "")
  1612  	if err != nil {
  1613  		log.Fatalf("store.Subscriptions().GetSubscriptionWorker() failed with %s\n", err)
  1614  	}
  1615  
  1616  	results := make(chan *ravendb.SubscriptionBatch, 16)
  1617  	cb := func(batch *ravendb.SubscriptionBatch) error {
  1618  		results <- batch
  1619  		return nil
  1620  	}
  1621  	err = worker.Run(cb)
  1622  	if err != nil {
  1623  		log.Fatalf("worker.Run() failed with %s\n", err)
  1624  	}
  1625  
  1626  	// wait for first batch result
  1627  	select {
  1628  	case batch := <-results:
  1629  		fmt.Print("Batch of subscription results:\n")
  1630  		pretty.Print(batch)
  1631  	case <-time.After(time.Second * 5):
  1632  		fmt.Printf("Timed out waiting for first subscription batch\n")
  1633  
  1634  	}
  1635  
  1636  	_ = worker.Close()
  1637  }
  1638  
  1639  var nameToFunc = map[string]func(){
  1640  	"loadUpdateSave":         loadUpdateSave,
  1641  	"crudStore":              crudStore,
  1642  	"crudLoad":               crudLoad,
  1643  	"crudLoadWithIncludes":   crudLoadWithIncludes,
  1644  	"crudUpdate":             crudUpdate,
  1645  	"crudDeleteUsingID":      crudDeleteUsingID,
  1646  	"crudDeleteUsingEntity":  crudDeleteUsingEntity,
  1647  	"queryCollectionByName":  queryCollectionByName,
  1648  	"queryCollectionByType":  queryCollectionByType,
  1649  	"queryIndex":             queryIndex,
  1650  	"queryFirst":             queryFirst,
  1651  	"queryComplex":           queryComplex,
  1652  	"querySelectSingleField": querySelectSingleField,
  1653  	"querySelectFields":      querySelectFields,
  1654  	"queryDistinct":          queryDistinct,
  1655  	"queryEquals":            queryEquals,
  1656  	"queryIn":                queryIn,
  1657  	"queryStartsWith":        queryStartsWith,
  1658  	"queryEndsWith":          queryEndsWith,
  1659  	"queryBetween":           queryBetween,
  1660  	"queryGreater":           queryGreater,
  1661  	"queryExists":            queryExists,
  1662  	"queryContainsAny":       queryContainsAny,
  1663  	"querySearch":            querySearch,
  1664  	"querySubclause":         querySubclause,
  1665  	"queryNot":               queryNot,
  1666  	"queryOrElse":            queryOrElse,
  1667  	"queryOrderBy":           queryOrderBy,
  1668  	"queryTake":              queryTake,
  1669  	"querySkip":              querySkip,
  1670  	"queryStatistics":        queryStatistics,
  1671  	"querySingle":            querySingle,
  1672  	"queryCount":             queryCount,
  1673  	"getAttachments":         getAttachments,
  1674  	"checkAttachmentExists":  checkAttachmentExists,
  1675  	"getAttachmentNames":     getAttachmentNames,
  1676  	"bulkInsert":             bulkInsert,
  1677  	"changes":                changes,
  1678  	"streamWithIDPrefix":     streamWithIDPrefix,
  1679  	"streamQueryResults":     streamQueryResults,
  1680  	"revisions":              revisions,
  1681  	"suggestions":            suggestions,
  1682  	"advancedPatching":       advancedPatching,
  1683  	"subscriptions":          subscriptions,
  1684  }
  1685  
  1686  func dispatchByName(name string) {
  1687  	fn, ok := nameToFunc[name]
  1688  	if ok {
  1689  		fn()
  1690  		return
  1691  	}
  1692  	fmt.Printf("didn't find function named '%s'\n", name)
  1693  }
  1694  
  1695  func main() {
  1696  	// setup optional logging
  1697  	setupLogging()
  1698  	defer finishLogging()
  1699  
  1700  	// you can either provide a name of example to run on command line e.g.
  1701  	// go run examples\main.go examples\log.go crudStore
  1702  	// or you can uncomment wanted function below
  1703  	if len(os.Args) == 2 {
  1704  		dispatchByName(os.Args[1])
  1705  		return
  1706  	}
  1707  
  1708  	//loadUpdateSave()
  1709  	//crudStore()
  1710  
  1711  	//crudLoad()
  1712  	//crudLoadWithIncludes()
  1713  	//crudUpdate()
  1714  	//crudDeleteUsingID()
  1715  	//crudDeleteUsingEntity()
  1716  	//queryCollectionByName()
  1717  	//queryCollectionByType()
  1718  	//queryIndex()
  1719  	//queryFirst()
  1720  	//queryComplex()
  1721  	//querySelectSingleField()
  1722  	//querySelectFields()
  1723  	//queryDistinct()
  1724  	//queryEquals()
  1725  	//queryIn()
  1726  	//queryStartsWith()
  1727  	//queryEndsWith()
  1728  	//queryBetween()
  1729  	//queryGreater()
  1730  	//queryExists()
  1731  	//queryContainsAny()
  1732  	//querySearch()
  1733  	//querySubclause()
  1734  	//queryNot()
  1735  	//queryOrElse()
  1736  	//queryOrderBy()
  1737  	//queryTake()
  1738  	//querySkip()
  1739  	//queryStatistics()
  1740  	//querySingle()
  1741  	//queryCount()
  1742  	//storeAttachments()
  1743  	//getAttachments()
  1744  	//checkAttachmentExists()
  1745  	//getAttachmentNames()
  1746  	//bulkInsert()
  1747  	changes()
  1748  	//streamWithIDPrefix()
  1749  	//streamQueryResults()
  1750  	//revisions()
  1751  	//suggestions()
  1752  	//advancedPatching()
  1753  	//subscriptions()
  1754  }