func (self *store) Filter(typeName string, offset int, count int, props []string, filter func(record interface{}) bool) (map[int64]interface{}, error) { var t, found = self.types[typeName] if !found { return nil, n.Fail(E_BAD_TYPE, "Invalid type '%s' is not known. Did you register it?", typeName) } if filter == nil { return nil, n.Fail(E_BAD_FILTER, "Invalid filter (nil)") } // Entire return space var rtn = make(map[int64]interface{}) // Look for matching records var total, _ = self.driver.Count(t) var query_offset = 0 var query_size = count var result_offset = 0 var match_count = 0 for match_count < count { // Find a new block var keys, err = self.driver.Keys(t, query_offset, query_size) if err != nil { return nil, n.Fail(E_DRIVER_FAILURE, err.Error()) } for _, k := range keys { var v, ve = self.driver.Get(t, k, props...) if ve != nil { return nil, n.Fail(E_DRIVER_FAILURE, err.Error()) } // Collect matching records if filter(v) { result_offset += 1 if result_offset > offset { rtn[k] = v match_count += 1 if match_count >= count { break } } } } query_offset += query_size if query_offset >= total { break } } // Cut result to sub-size return rtn, nil }
// Deserialize entire record if no specific props were requested func (self *recordSet) Get(key int64, props []string) (interface{}, error) { var kpath, ppaths = self.KeyPath(key) // Entire record if len(props) == 0 { var content, err = ioutil.ReadFile(kpath) if err != nil { return nil, err } var rtn = self.Deserialize(content, self.Type) return rtn, nil } // Only parts var rtn = reflect.New(self.Type).Interface() var vrtn = reflect.ValueOf(rtn) if vrtn.Kind() == reflect.Ptr || vrtn.Kind() == reflect.Interface { vrtn = vrtn.Elem() } for i := 0; i < len(props); i++ { path, found := ppaths[props[i]] if found { // Special case; if the field really actually doesn't exist, // load the original record instead. var field_content, ferr = ioutil.ReadFile(path) if ferr != nil { return self.Get(key, []string{}) } var field, fterr = self.Type.FieldByName(props[i]) if !fterr { return nil, n.Fail(1, "The given type does not have a property '%s'", props[i]) } var field_type = field.Type var field_value = self.Deserialize(field_content, field_type) var field_value_as_value = reflect.ValueOf(field_value) var field_pointer = vrtn.FieldByName(props[i]) if field_value_as_value.Kind() == reflect.Ptr || field_value_as_value.Kind() == reflect.Interface { field_value_as_value = field_value_as_value.Elem() } field_pointer.Set(field_value_as_value) } else { return nil, n.Fail(1, "Invalid property list: '%s' was not an object property", props[i]) } } return rtn, nil }
// Execute an sql 'exec' that returns 'insert ids' (api is stupid) func (self *sql) exec(query string, columns []string, values ...[]interface{}) (*rowset, error) { var output gsql.Result = nil var err error = nil // Pass params over if len(values) > 0 { output, err = self.db.Exec(query, values[0]...) } else { output, err = self.db.Exec(query) } if err != nil { return nil, n.Fail(1, "Error perfroming explicit SQL query \"%s\": %s", query, err.Error()) } // Process output var rtn = newRowset(nil).(*rowset) var id, id_err = output.LastInsertId() if id_err == nil { var record = map[string]interface{}{} for _, c := range columns { record[c] = id } rtn.Values.PushBack(record) } return rtn, err }
func (self *store) Set(typeName string, record interface{}, key ...int64) (int64, error) { // Bounds if n.IsNil(record) { return -1, n.Fail(E_BAD_RECORD, "Nil record cannot be saved") } // Find type var t, found = self.types[typeName] if !found { return -1, n.Fail(E_BAD_TYPE, "Invalid type '%s' is not known. Did you register it?", typeName) } // Invoke the driver var rkey, derr = self.driver.Set(t, record, key...) return rkey, derr }
func (self *store) Count(typeName string) (int, error) { var t, found = self.types[typeName] if !found { return 0, n.Fail(E_BAD_TYPE, "Invalid type '%s' is not known. Did you register it?", typeName) } var rtn, err = self.driver.Count(t) return rtn, err }
// Execute a query and return a rowset func (self *sql) Execute(query *nsql.Query) (nsql.Rowset, error) { switch { case query.Type == nsql.INSERT: return self.Insert(query) case query.Type == nsql.SELECT: return self.Select(query) } return nil, n.Fail(1, "Invalid query type; not supported") }
func (self *store) Delete(typeName string, key int64) error { // Find type var t, found = self.types[typeName] if !found { return n.Fail(E_BAD_TYPE, "Invalid type '%s' is not known. Did you register it?", typeName) } var err = self.driver.Delete(t, key) return err }
func (self *store) Register(t rf.Type, id string) error { for t.Kind() == rf.Ptr { t = t.Elem() } if t.Kind() != rf.Struct { return n.Fail(E_BAD_TYPE, "Invalid type; only struct types can be registered") } self.types[id] = t return nil }
func (self *store) Get(typeName string, key int64) (interface{}, error) { // Find type var t, found = self.types[typeName] if !found { return nil, n.Fail(E_BAD_TYPE, "Invalid type '%s' is not known. Did you register it?", typeName) } // Return instance var rtn, err = self.driver.Get(t, key) return rtn, err }
func (self *store) All(typeName string, offset int, count int) (map[int64]interface{}, error) { var t, found = self.types[typeName] if !found { return nil, n.Fail(E_BAD_TYPE, "Invalid type '%s' is not known. Did you register it?", typeName) } var keys, err = self.driver.Keys(t, offset, count) if err != nil { return nil, n.Fail(E_DRIVER_FAILURE, err.Error()) } var rtn = make(map[int64]interface{}) for _, k := range keys { var v, ve = self.driver.Get(t, k) if ve != nil { return nil, n.Fail(E_DRIVER_FAILURE, ve.Error()) } rtn[k] = v } return rtn, nil }
func (self *store) Clear(typeName string) error { var t, found = self.types[typeName] if !found { return n.Fail(E_BAD_TYPE, "Invalid type '%s' is not known. Did you register it?", typeName) } // Delete all keys var count, _ = self.driver.Count(t) var keys, _ = self.driver.Keys(t, 0, count) for _, k := range keys { self.driver.Delete(t, k) } return nil }
// Load a template and attach the given name to it. func (self *ControllerBase) loadTemplate(path string, id string) error { var template_path = _path.Join(self.templatePath, path) var raw, re = ioutil.ReadFile(template_path) if re != nil { // TODO: Controller common error handling. n.Log("\nError: failed to load template: %s", path) n.Log("%s", re.Error()) return n.Fail(1, "Invalid template") } var t *template.Template = self.templates if t == nil { var t, te = template.New(id).Parse(string(raw)) if te != nil { // TODO: Controller common error handling. n.Log("\nError: invalid template: %s", path) n.Log("%s", te.Error()) return n.Fail(1, "Invalid template") } else { self.templates = t } } else { var _, te = self.templates.New(id).Parse(string(raw)) if te != nil { // TODO: Controller common error handling. n.Log("\nError: invalid template: %s", path) n.Log("%s", te.Error()) return n.Fail(1, "Invalid template") } } // DEBUG // n.Log("Registered template id: %s -> %s", id, template_path) return nil }
// Execute an sql 'query' that returns 'rows' func (self *sql) query(query string, values ...[]interface{}) (*rowset, error) { var rows *gsql.Rows = nil var err error = nil // Pass params over if len(values) > 0 { rows, err = self.db.Query(query, values[0]...) } else { rows, err = self.db.Query(query) } if err != nil { return nil, n.Fail(1, "Error perfroming explicit SQL query \"%s\": %s", query, err.Error()) } // Generate output var rtn = newRowset(rows).(*rowset) return rtn, err }