Example #1
0
func clearTable(tx transaction.Transaction, s *schema.Schema) error {
	if s.IsAbstract() {
		return nil
	}
	for _, schema := range schema.GetManager().Schemas() {
		if schema.ParentSchema == s {
			err := clearTable(tx, schema)
			if err != nil {
				return err
			}
		} else {
			for _, property := range schema.Properties {
				if property.Relation == s.Singular {
					err := clearTable(tx, schema)
					if err != nil {
						return err
					}
				}
			}
		}
	}
	resources, _, err := tx.List(s, nil, nil)
	if err != nil {
		return err
	}
	for _, resource := range resources {
		err = tx.Delete(s, resource.ID())
		if err != nil {
			return err
		}
	}
	return nil
}
Example #2
0
File: sql.go Project: vozhyk-/gohan
//GenTableDef generates create table sql
func (db *DB) GenTableDef(s *schema.Schema, cascade bool) string {
	schemaManager := schema.GetManager()
	cols, relations := db.genTableCols(s, cascade, nil)

	if s.Parent != "" {
		foreignSchema, _ := schemaManager.Schema(s.Parent)
		cascadeString := ""
		if cascade || s.OnParentDeleteCascade {
			cascadeString = "on delete cascade"
		}
		relations = append(relations, fmt.Sprintf("foreign key(`%s_id`) REFERENCES `%s`(id) %s",
			s.Parent, foreignSchema.GetDbTableName(), cascadeString))
	}

	if s.StateVersioning() {
		cols = append(cols, quote(configVersionColumnName)+"int not null default 1")
		cols = append(cols, quote(stateVersionColumnName)+"int not null default 0")
		cols = append(cols, quote(stateErrorColumnName)+"text not null default ''")
		cols = append(cols, quote(stateColumnName)+"text not null default ''")
		cols = append(cols, quote(stateMonitoringColumnName)+"text not null default ''")
	}

	cols = append(cols, relations...)
	tableSQL := fmt.Sprintf("create table `%s` (%s);\n", s.GetDbTableName(), strings.Join(cols, ","))
	log.Debug("Creating table: " + tableSQL)
	return tableSQL
}
Example #3
0
// ActionResource runs custom action on resource
func ActionResource(context middleware.Context, dataStore db.DB, identityService middleware.IdentityService,
	resourceSchema *schema.Schema, action schema.Action, resourceID string, data interface{},
) error {
	actionSchema := action.InputSchema
	context["input"] = data
	context["id"] = resourceID

	environmentManager := extension.GetManager()
	environment, ok := environmentManager.GetEnvironment(resourceSchema.ID)
	if !ok {
		return fmt.Errorf("No environment for schema")
	}

	if actionSchema != nil {
		err := resourceSchema.Validate(actionSchema, data)
		if err != nil {
			return ResourceError{err, fmt.Sprintf("Validation error: %s", err), WrongData}
		}
	}

	err := extension.HandleEvent(context, environment, action.ID)
	if err != nil {
		return err
	}

	if _, ok := context["response"]; ok {
		return nil
	}

	return fmt.Errorf("no response")
}
Example #4
0
func addFilterToQuery(s *schema.Schema, q sq.SelectBuilder, filter map[string]interface{}, join bool) sq.SelectBuilder {
	if filter == nil {
		return q
	}
	for key, value := range filter {
		property, err := s.GetPropertyByID(key)
		var column string
		if join {
			column = makeColumn(s, *property)
		} else {
			column = quote(key)
		}
		if err != nil {
			log.Notice(err.Error())
			continue
		}

		if property.Type == "boolean" {
			v := make([]bool, len(value.([]string)))
			for i, j := range value.([]string) {
				v[i], _ = strconv.ParseBool(j)
			}
			q = q.Where(sq.Eq{column: v})
		} else {
			q = q.Where(sq.Eq{column: value})
		}
	}
	return q
}
Example #5
0
File: sql.go Project: vozhyk-/gohan
//StateFetch fetches the state of the specified resource
func (tx *Transaction) StateFetch(s *schema.Schema, filter transaction.Filter) (state transaction.ResourceState, err error) {
	if !s.StateVersioning() {
		err = fmt.Errorf("Schema %s does not support state versioning.", s.ID)
		return
	}
	cols := makeStateColumns(s)
	q := sq.Select(cols...).From(quote(s.GetDbTableName()))
	q, _ = addFilterToQuery(s, q, filter, true)
	sql, args, err := q.ToSql()
	if err != nil {
		return
	}
	logQuery(sql, args...)
	rows, err := tx.transaction.Queryx(sql, args...)
	if err != nil {
		return
	}
	defer rows.Close()
	if !rows.Next() {
		err = fmt.Errorf("No resource found")
		return
	}
	data := map[string]interface{}{}
	rows.MapScan(data)
	err = decodeState(data, &state)
	return
}
Example #6
0
func getArgsAsMap(args []string, s *schema.Schema) (map[string]interface{}, error) {
	if len(args)%2 != 0 {
		return nil, fmt.Errorf("Parameters should be in [--param-name value]... format")
	}
	result := map[string]interface{}{}
	for i := 0; i < len(args); i += 2 {
		key := strings.TrimPrefix(args[i], "--")
		valueType := "string"
		if property, err := s.GetPropertyByID(key); err == nil {
			valueType = property.Type
		}
		rawValue := args[i+1]
		var value interface{}
		var err error
		if rawValue == "<null>" {
			value = nil
		} else {
			switch valueType {
			case "integer", "number":
				value, err = strconv.ParseInt(rawValue, 10, 64)
			case "boolean":
				value, err = strconv.ParseBool(rawValue)
			case "array", "object":
				err = json.Unmarshal([]byte(rawValue), &value)
			default:
				value = rawValue
			}
			if err != nil {
				return nil, fmt.Errorf("Error parsing parameter '%v': %v", key, err)
			}
		}
		result[key] = value
	}
	return result, nil
}
Example #7
0
File: sql.go Project: vozhyk-/gohan
func addFilterToQuery(s *schema.Schema, q sq.SelectBuilder, filter map[string]interface{}, join bool) (sq.SelectBuilder, error) {
	if filter == nil {
		return q, nil
	}
	for key, value := range filter {
		property, err := s.GetPropertyByID(key)

		if err != nil {
			return q, err
		}

		var column string
		if join {
			column = makeColumn(s.GetDbTableName(), *property)
		} else {
			column = quote(key)
		}

		queryValues, ok := value.([]string)
		if ok && property.Type == "boolean" {
			v := make([]bool, len(queryValues))
			for i, j := range queryValues {
				v[i], _ = strconv.ParseBool(j)
			}
			q = q.Where(sq.Eq{column: v})
		} else {
			q = q.Where(sq.Eq{column: value})
		}
	}
	return q, nil
}
Example #8
0
File: sql.go Project: vozhyk-/gohan
//Delete delete resource from db
func (tx *Transaction) Delete(s *schema.Schema, resourceID interface{}) error {
	sql, args, err := sq.Delete(quote(s.GetDbTableName())).Where(sq.Eq{"id": resourceID}).ToSql()
	if err != nil {
		return err
	}
	return tx.Exec(sql, args...)
}
Example #9
0
func (gohanClientCLI *GohanClientCLI) createResourcesTable(s *schema.Schema, buffer *bytes.Buffer, resources []interface{}) {
	table := tablewriter.NewWriter(buffer)
	if len(resources) == 0 {
		return
	}
	table.SetHeader(s.Titles())
	for _, rawResource := range resources {
		resourceSlice := []string{}
		resource := rawResource.(map[string]interface{})
		for _, property := range s.Properties {
			v := ""
			if val, ok := resource[property.ID]; ok && val != nil {
				switch property.Type {
				case "string":
					v = fmt.Sprint(val)
					if property.RelationProperty != "" {
						relatedResource := resource[property.RelationProperty].(map[string]interface{})
						v = relatedResource["name"].(string)
					}
				default:
					v = fmt.Sprint(val)
				}
			}
			resourceSlice = append(resourceSlice, v)
		}
		table.Append(resourceSlice)
	}
	table.Render()
}
Example #10
0
File: sql.go Project: vozhyk-/gohan
//DropTable drop table definition
func (db *DB) DropTable(s *schema.Schema) error {
	if s.IsAbstract() {
		return nil
	}
	sql := fmt.Sprintf("drop table if exists %s\n", quote(s.GetDbTableName()))
	_, err := db.DB.Exec(sql)
	return err
}
Example #11
0
//GenTableDef generates table create sql
func (db *DB) GenTableDef(s *schema.Schema, cascade bool) string {
	schemaManager := schema.GetManager()
	var cols []string
	var relations []string
	cascadeString := ""
	if cascade {
		cascadeString = "on delete cascade"
	}
	for _, property := range s.Properties {
		handler := db.handlers[property.Type]
		dataType := property.SQLType
		if db.sqlType == "sqlite3" {
			dataType = strings.Replace(dataType, "auto_increment", "autoincrement", 1)
		}
		if dataType == "" {
			dataType = handler.dataType(&property)
			if property.ID == "id" {
				dataType += " primary key"
			} else {
				if property.Nullable {
					dataType += " null"
				} else {
					dataType += " not null"
				}
				if property.Unique {
					dataType += " unique"
				}
			}
		}
		sql := "`" + property.ID + "`" + dataType

		cols = append(cols, sql)
		if property.Relation != "" {
			foreignSchema, _ := schemaManager.Schema(property.Relation)
			if foreignSchema != nil {
				relations = append(relations, fmt.Sprintf("foreign key(`%s`) REFERENCES `%s`(id) %s",
					property.ID, foreignSchema.GetDbTableName(), cascadeString))
			}
		}
	}
	if s.Parent != "" {
		foreignSchema, _ := schemaManager.Schema(s.Parent)
		relations = append(relations, fmt.Sprintf("foreign key(`%s_id`) REFERENCES `%s`(id) %s",
			s.Parent, foreignSchema.GetDbTableName(), cascadeString))
	}
	if s.StateVersioning() {
		cols = append(cols, quote(configVersionColumnName)+"int not null default 1")
		cols = append(cols, quote(stateVersionColumnName)+"int not null default 0")
		cols = append(cols, quote(stateErrorColumnName)+"text not null default ''")
		cols = append(cols, quote(stateColumnName)+"text not null default ''")
		cols = append(cols, quote(stateMonitoringColumnName)+"text not null default ''")
	}
	cols = append(cols, relations...)
	tableSQL := fmt.Sprintf("create table `%s` (%s);\n", s.GetDbTableName(), strings.Join(cols, ","))
	log.Debug("Creating table: " + tableSQL)
	return tableSQL
}
Example #12
0
File: sql.go Project: vozhyk-/gohan
func makeStateColumns(s *schema.Schema) (cols []string) {
	dbTableName := s.GetDbTableName()
	cols = append(cols, dbTableName+"."+configVersionColumnName+" as "+quote(configVersionColumnName))
	cols = append(cols, dbTableName+"."+stateVersionColumnName+" as "+quote(stateVersionColumnName))
	cols = append(cols, dbTableName+"."+stateErrorColumnName+" as "+quote(stateErrorColumnName))
	cols = append(cols, dbTableName+"."+stateColumnName+" as "+quote(stateColumnName))
	cols = append(cols, dbTableName+"."+stateMonitoringColumnName+" as "+quote(stateMonitoringColumnName))
	return cols
}
Example #13
0
func (db *DB) getTable(s *schema.Schema) []interface{} {
	rawTable, ok := db.data[s.GetDbTableName()]
	if ok {
		return rawTable.([]interface{})
	}
	newTable := []interface{}{}
	db.data[s.GetDbTableName()] = newTable
	return newTable
}
Example #14
0
//FilterFromQueryParameter makes list filter from query
func FilterFromQueryParameter(resourceSchema *schema.Schema,
	queryParameters map[string][]string) map[string]interface{} {
	filter := map[string]interface{}{}
	for key, value := range queryParameters {
		if _, err := resourceSchema.GetPropertyByID(key); err != nil {
			log.Info("Resource %s does not have %s property, ignoring filter.")
			continue
		}
		filter[key] = value
	}
	return filter
}
Example #15
0
// DeleteResource deletes the resource specified by the schema and ID
func DeleteResource(context middleware.Context,
	dataStore db.DB,
	resourceSchema *schema.Schema,
	resourceID string,
) error {
	context["id"] = resourceID
	environmentManager := extension.GetManager()
	environment, ok := environmentManager.GetEnvironment(resourceSchema.ID)
	if !ok {
		return fmt.Errorf("No environment for schema")
	}
	auth := context["auth"].(schema.Authorization)
	policy, err := loadPolicy(context, "delete", strings.Replace(resourceSchema.GetSingleURL(), ":id", resourceID, 1), auth)
	if err != nil {
		return err
	}
	context["policy"] = policy
	preTransaction, err := dataStore.Begin()
	if err != nil {
		return fmt.Errorf("cannot create transaction: %v", err)
	}
	tenantIDs := policy.GetTenantIDFilter(schema.ActionDelete, auth.TenantID())
	filter := transaction.IDFilter(resourceID)
	if tenantIDs != nil {
		filter["tenant_id"] = tenantIDs
	}
	resource, fetchErr := preTransaction.Fetch(resourceSchema, filter)
	preTransaction.Close()

	if resource != nil {
		context["resource"] = resource.Data()
	}

	if err := extension.HandleEvent(context, environment, "pre_delete"); err != nil {
		return err
	}
	if fetchErr != nil {
		return ResourceError{err, "", NotFound}
	}
	if err := InTransaction(
		context, dataStore,
		transaction.GetIsolationLevel(resourceSchema, schema.ActionDelete),
		func() error {
			return DeleteResourceInTransaction(context, resourceSchema, resourceID)
		},
	); err != nil {
		return err
	}
	if err := extension.HandleEvent(context, environment, "post_delete"); err != nil {
		return err
	}
	return nil
}
// UpdateResourceInTransaction updates resource in db in transaction
func UpdateResourceInTransaction(
	context middleware.Context,
	resourceSchema *schema.Schema, resourceID string,
	dataMap map[string]interface{}, tenantIDs []string) error {

	manager := schema.GetManager()
	mainTransaction := context["transaction"].(transaction.Transaction)
	environmentManager := extension.GetManager()
	environment, ok := environmentManager.GetEnvironment(resourceSchema.ID)
	if !ok {
		return fmt.Errorf("No environment for schema")
	}
	resource, err := mainTransaction.Fetch(
		resourceSchema, resourceID, tenantIDs)
	if err != nil {
		return ResourceError{err, err.Error(), WrongQuery}
	}
	err = resource.Update(dataMap)
	if err != nil {
		return ResourceError{err, err.Error(), WrongData}
	}
	context["resource"] = resource.Data()

	if err := handleEvent(context, environment, "pre_update_in_transaction"); err != nil {
		return err
	}

	dataMap, ok = context["resource"].(map[string]interface{})
	if !ok {
		return fmt.Errorf("Resource not JSON: %s", err)
	}
	resource, err = manager.LoadResource(resourceSchema.ID, dataMap)
	if err != nil {
		return fmt.Errorf("Loading Resource failed: %s", err)
	}

	err = mainTransaction.Update(resource)
	if err != nil {
		return ResourceError{err, fmt.Sprintf("Failed to store data in database: %v", err), UpdateFailed}
	}
	resourceSchema.HandleUpdate(resource)

	response := map[string]interface{}{}
	response[resourceSchema.Singular] = resource.Data()
	context["response"] = response

	if err := handleEvent(context, environment, "post_update_in_transaction"); err != nil {
		return err
	}

	return nil
}
Example #17
0
func makeJoin(s *schema.Schema, q sq.SelectBuilder) sq.SelectBuilder {
	manager := schema.GetManager()
	for _, property := range s.Properties {
		if property.RelationProperty == "" {
			continue
		}
		relatedSchema, _ := manager.Schema(property.Relation)
		q = q.LeftJoin(
			quote(relatedSchema.GetDbTableName()) + fmt.Sprintf(" on %s.%s = %s.id", s.GetDbTableName(), property.ID, relatedSchema.GetDbTableName()))
		q = makeJoin(relatedSchema, q)
	}
	return q
}
// ActionResource runs custom action on resource
func ActionResource(context middleware.Context, dataStore db.DB, identityService middleware.IdentityService,
	resourceSchema *schema.Schema, action schema.Action, resourceID string, data interface{},
) error {
	actionSchema := action.InputSchema
	context["input"] = data
	context["id"] = resourceID

	environmentManager := extension.GetManager()
	environment, ok := environmentManager.GetEnvironment(resourceSchema.ID)
	if !ok {
		return fmt.Errorf("No environment for schema")
	}

	err := resourceSchema.Validate(actionSchema, data)
	if err != nil {
		return ResourceError{err, fmt.Sprintf("Validation error: %s", err), WrongData}
	}

	if err := handleEvent(context, environment, fmt.Sprintf("pre_%s", action.ID)); err != nil {
		return err
	}

	if err := InTransaction(context, dataStore, func() error {
		return handleEvent(context, environment, fmt.Sprintf("pre_%s_in_transaction", action.ID))
	}); err != nil {
		return err
	}

	if err := handleEvent(context, environment, action.ID); err != nil {
		return err
	}

	if err := InTransaction(context, dataStore, func() error {
		return handleEvent(context, environment, fmt.Sprintf("post_%s_in_transaction", action.ID))
	}); err != nil {
		return err
	}

	if err := handleEvent(context, environment, fmt.Sprintf("post_%s", action.ID)); err != nil {
		return err
	}

	if rawResponse, ok := context["response"]; ok {
		if _, ok := rawResponse.(map[string]interface{}); ok {
			return nil
		}
		return fmt.Errorf("extension returned invalid JSON: %v", rawResponse)
	}

	return fmt.Errorf("no response")
}
Example #19
0
File: sql.go Project: vozhyk-/gohan
//RegisterTable creates table in the db
func (db *DB) RegisterTable(s *schema.Schema, cascade bool) error {
	if s.IsAbstract() {
		return nil
	}
	tableDef, err := db.AlterTableDef(s, cascade)
	if err != nil {
		tableDef = db.GenTableDef(s, cascade)
	}
	if tableDef == "" {
		return nil
	}
	_, err = db.DB.Exec(tableDef)
	return err
}
Example #20
0
// GetMultipleResources returns all resources specified by the schema and query parameters
func GetMultipleResources(context middleware.Context, dataStore db.DB, resourceSchema *schema.Schema, queryParameters map[string][]string) error {
	log.Debug("Start get multiple resources!!")
	auth := context["auth"].(schema.Authorization)
	policy, err := loadPolicy(context, "read", resourceSchema.GetPluralURL(), auth)
	if err != nil {
		return err
	}

	filter := FilterFromQueryParameter(resourceSchema, queryParameters)

	if policy.RequireOwner() {
		filter["tenant_id"] = policy.GetTenantIDFilter(schema.ActionRead, auth.TenantID())
	}
	filter = policy.RemoveHiddenProperty(filter)

	paginator, err := pagination.FromURLQuery(resourceSchema, queryParameters)
	if err != nil {
		return ResourceError{err, err.Error(), WrongQuery}
	}
	context["policy"] = policy

	environmentManager := extension.GetManager()
	environment, ok := environmentManager.GetEnvironment(resourceSchema.ID)
	if !ok {
		return fmt.Errorf("No environment for schema")
	}
	if err := extension.HandleEvent(context, environment, "pre_list"); err != nil {
		return err
	}
	if rawResponse, ok := context["response"]; ok {
		if _, ok := rawResponse.(map[string]interface{}); ok {
			return nil
		}
		return fmt.Errorf("extension returned invalid JSON: %v", rawResponse)
	}

	if err := GetResources(context, dataStore, resourceSchema, filter, paginator); err != nil {
		return err
	}

	if err := extension.HandleEvent(context, environment, "post_list"); err != nil {
		return err
	}

	if err := ApplyPolicyForResources(context, resourceSchema); err != nil {
		return err
	}

	return nil
}
Example #21
0
//Delete delete resource from db
func (tx *Transaction) Delete(s *schema.Schema, resourceID interface{}) error {
	db := tx.db
	db.load()
	table := db.getTable(s)
	newTable := []interface{}{}
	for _, rawDataInDB := range table {
		dataInDB := rawDataInDB.(map[string]interface{})
		if dataInDB["id"] != resourceID {
			newTable = append(newTable, dataInDB)
		}
	}
	db.data[s.GetDbTableName()] = newTable
	db.write()
	return nil
}
//GetSchema returns the schema filtered and trimmed for a specific user or nil when the user shouldn't see it at all
func GetSchema(s *schema.Schema, authorization schema.Authorization) (result *schema.Resource, err error) {
	manager := schema.GetManager()
	metaschema, _ := manager.Schema("schema")
	policy, _ := manager.PolicyValidate("read", s.GetPluralURL(), authorization)
	if policy == nil {
		return
	}
	originalRawSchema := s.RawData.(map[string]interface{})
	rawSchema := map[string]interface{}{}
	for key, value := range originalRawSchema {
		rawSchema[key] = value
	}
	originalSchema := originalRawSchema["schema"].(map[string]interface{})
	schemaSchema := map[string]interface{}{}
	for key, value := range originalSchema {
		schemaSchema[key] = value
	}
	rawSchema["schema"] = schemaSchema
	originalProperties := originalSchema["properties"].(map[string]interface{})
	schemaProperties := map[string]interface{}{}
	for key, value := range originalProperties {
		schemaProperties[key] = value
	}
	var schemaPropertiesOrder []interface{}
	if _, ok := originalSchema["propertiesOrder"]; ok {
		originalPropertiesOrder := originalSchema["propertiesOrder"].([]interface{})
		for _, value := range originalPropertiesOrder {
			schemaPropertiesOrder = append(schemaPropertiesOrder, value)
		}
	}
	var schemaRequired []interface{}
	if _, ok := originalSchema["required"]; ok {
		originalRequired := originalSchema["required"].([]interface{})
		for _, value := range originalRequired {
			schemaRequired = append(schemaRequired, value)
		}
	}
	schemaProperties, schemaPropertiesOrder, schemaRequired = policy.MetaFilter(schemaProperties, schemaPropertiesOrder, schemaRequired)
	schemaSchema["properties"] = schemaProperties
	schemaSchema["propertiesOrder"] = schemaPropertiesOrder
	schemaSchema["required"] = schemaRequired
	result, err = schema.NewResource(metaschema, rawSchema)
	if err != nil {
		log.Warning("%s %s", result, err)
		return
	}
	return
}
Example #23
0
File: sql.go Project: vozhyk-/gohan
func (tx *Transaction) decodeRows(s *schema.Schema, rows *sqlx.Rows, list []*schema.Resource) ([]*schema.Resource, error) {
	for rows.Next() {
		resourceData := map[string]interface{}{}
		data := map[string]interface{}{}
		rows.MapScan(data)

		var resource *schema.Resource
		tx.decode(s, s.GetDbTableName(), data, resourceData)
		resource, err := schema.NewResource(s, resourceData)
		if err != nil {
			return nil, fmt.Errorf("Failed to decode rows")
		}
		list = append(list, resource)
	}
	return list, nil
}
Example #24
0
// GetSingleResource returns the resource specified by the schema and ID
func GetSingleResource(context middleware.Context, dataStore db.DB, resourceSchema *schema.Schema, resourceID string) error {
	context["id"] = resourceID
	auth := context["auth"].(schema.Authorization)
	policy, err := loadPolicy(context, "read", strings.Replace(resourceSchema.GetSingleURL(), ":id", resourceID, 1), auth)
	if err != nil {
		return err
	}
	context["policy"] = policy

	environmentManager := extension.GetManager()
	environment, ok := environmentManager.GetEnvironment(resourceSchema.ID)
	if !ok {
		return fmt.Errorf("No environment for schema")
	}
	if err := extension.HandleEvent(context, environment, "pre_show"); err != nil {
		return err
	}
	if rawResponse, ok := context["response"]; ok {
		if _, ok := rawResponse.(map[string]interface{}); ok {
			return nil
		}
		return fmt.Errorf("extension returned invalid JSON: %v", rawResponse)
	}

	if err := InTransaction(
		context, dataStore,
		transaction.GetIsolationLevel(resourceSchema, schema.ActionRead),
		func() error {
			return GetSingleResourceInTransaction(context, resourceSchema, resourceID, policy.GetTenantIDFilter(schema.ActionRead, auth.TenantID()))
		},
	); err != nil {
		return err
	}

	if err := extension.HandleEvent(context, environment, "post_show"); err != nil {
		return err
	}
	if err := ApplyPolicyForResource(context, resourceSchema); err != nil {
		return ResourceError{err, "", NotFound}
	}
	return nil
}
Example #25
0
File: sql.go Project: vozhyk-/gohan
//AlterTableDef generates alter table sql
func (db *DB) AlterTableDef(s *schema.Schema, cascade bool) (string, error) {
	var existing []string
	rows, err := db.DB.Query(fmt.Sprintf("select * from `%s`;", s.GetDbTableName()))
	if err == nil {
		defer rows.Close()
		existing, err = rows.Columns()
	}

	if err != nil {
		return "", err
	}

	cols, relations := db.genTableCols(s, cascade, existing)
	cols = append(cols, relations...)
	if len(cols) == 0 {
		return "", nil
	}
	alterTable := fmt.Sprintf("alter table`%s` add (%s);\n", s.GetDbTableName(), strings.Join(cols, ","))
	log.Debug("Altering table: " + alterTable)
	return alterTable, nil
}
Example #26
0
func (gohanClientCLI *GohanClientCLI) handleRelationArguments(s *schema.Schema, args map[string]interface{}) (map[string]interface{}, error) {
	parsedArgs := map[string]interface{}{}
	for arg, value := range args {
		if arg == s.Parent {
			parentID, err := gohanClientCLI.getResourceIDForSchemaID(s.Parent, value.(string))
			if err != nil {
				return nil, err
			}
			parsedArgs[s.ParentSchemaPropertyID()] = parentID
			continue
		}
		property, _ := s.GetPropertyByID(arg)
		if property == nil {
			property, _ = s.GetPropertyByID(arg + "_id")
			if property != nil && property.Relation != "" {
				relatedID, err := gohanClientCLI.getResourceIDForSchemaID(property.Relation, value.(string))
				if err != nil {
					return nil, err
				}
				parsedArgs[property.ID] = relatedID
				continue
			}
		}
		parsedArgs[arg] = value
	}
	return parsedArgs, nil
}
Example #27
0
//GetSchema returns the schema filtered and trimmed for a specific user or nil when the user shouldn't see it at all
func GetSchema(s *schema.Schema, authorization schema.Authorization) (result *schema.Resource, err error) {
	manager := schema.GetManager()
	metaschema, _ := manager.Schema("schema")
	policy, _ := manager.PolicyValidate("read", s.GetPluralURL(), authorization)
	if policy == nil {
		return
	}
	if s.IsAbstract() {
		return
	}
	rawSchema := s.JSON()
	filteredSchema := util.ExtendMap(nil, s.JSONSchema)
	rawSchema["schema"] = filteredSchema
	schemaProperties, schemaPropertiesOrder, schemaRequired := policy.FilterSchema(
		util.MaybeMap(s.JSONSchema["properties"]),
		util.MaybeStringList(s.JSONSchema["propertiesOrder"]),
		util.MaybeStringList(s.JSONSchema["required"]))

	filteredSchema["properties"] = schemaProperties
	filteredSchema["propertiesOrder"] = schemaPropertiesOrder
	filteredSchema["required"] = schemaRequired

	result, err = schema.NewResource(metaschema, rawSchema)
	if err != nil {
		log.Warning("%s %s", result, err)
		return
	}
	return
}
Example #28
0
//RegisterTable creates table in the db
func (db *DB) RegisterTable(s *schema.Schema, cascade bool) error {
	if s.IsAbstract() {
		return nil
	}
	tableDef, indices, err := db.AlterTableDef(s, cascade)
	if err != nil {
		tableDef, indices = db.GenTableDef(s, cascade)
	}
	if tableDef == "" {
		return nil
	}
	_, err = db.DB.Exec(tableDef)
	if err != nil && indices != nil {
		for _, indexSql := range indices {
			_, err = db.DB.Exec(indexSql)
			if err != nil {
				return err
			}
		}
	}
	return err
}
Example #29
0
File: sql.go Project: vozhyk-/gohan
//List resources in the db
func (tx *Transaction) List(s *schema.Schema, filter transaction.Filter, pg *pagination.Paginator) (list []*schema.Resource, total uint64, err error) {
	cols := MakeColumns(s, s.GetDbTableName(), true)
	q := sq.Select(cols...).From(quote(s.GetDbTableName()))
	q, err = addFilterToQuery(s, q, filter, true)
	if err != nil {
		return nil, 0, err
	}
	if pg != nil {
		property, err := s.GetPropertyByID(pg.Key)
		if err == nil {
			q = q.OrderBy(makeColumn(s.GetDbTableName(), *property) + " " + pg.Order)
			if pg.Limit > 0 {
				q = q.Limit(pg.Limit)
			}
			if pg.Offset > 0 {
				q = q.Offset(pg.Offset)
			}
		}
	}
	q = makeJoin(s, s.GetDbTableName(), q)

	sql, args, err := q.ToSql()
	if err != nil {
		return
	}
	logQuery(sql, args...)
	rows, err := tx.transaction.Queryx(sql, args...)
	if err != nil {
		return
	}
	defer rows.Close()
	list, err = tx.decodeRows(s, rows, list)
	if err != nil {
		return nil, 0, err
	}
	total, err = tx.count(s, filter)
	return
}
Example #30
0
File: sql.go Project: vozhyk-/gohan
//count count all matching resources in the db
func (tx *Transaction) count(s *schema.Schema, filter transaction.Filter) (res uint64, err error) {
	q := sq.Select("Count(id) as count").From(quote(s.GetDbTableName()))
	//Filter get already tested
	q, _ = addFilterToQuery(s, q, filter, false)
	sql, args, err := q.ToSql()
	if err != nil {
		return
	}
	result := map[string]interface{}{}
	err = tx.transaction.QueryRowx(sql, args...).MapScan(result)
	if err != nil {
		return
	}
	count, _ := result["count"]
	decoder := &numberHandler{}
	decoded, decodeErr := decoder.decode(nil, count)
	if decodeErr != nil {
		err = fmt.Errorf("SQL List decoding error: %s", decodeErr)
		return
	}
	res = uint64(decoded.(int))
	return
}