<commit_before>package storagenode

func GetSchema() string {
	return schemaJson
}

// TODO: might as well make this a static struct var instantiation
const schemaJson string = `
{
  "databases": {
    "dataman_storage": {
      "name": "dataman_storage",
      "shard_instances": {
        "public": {
          "name": "public",
          "count": 1,
          "instance": 1,
          "collections": {
            "collection": {
              "name": "collection",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "shard_instance_id": {
                  "name": "shard_instance_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "shard_instance",
                    "field": "_id"
                  },
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_name_shard_instance_id_idx": {
                  "name": "collection_name_shard_instance_id_idx",
                  "fields": [
                    "name",
                    "shard_instance_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_pkey": {
                  "name": "collection_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_field": {
              "name": "collection_field",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "collection_id": {
                  "name": "collection_id",
                  "field_type": "_int",
                  "relation": {
                    "collection": "collection",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "default": {
                  "name": "default",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "field_type": {
                  "name": "field_type",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "not_null": {
                  "name": "not_null",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "parent_collection_field_id": {
                  "name": "parent_collection_field_id",
                  "field_type": "_int",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_field_pkey": {
                  "name": "collection_field_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                },
                "index_collection_field_collection_field_name": {
                  "name": "index_collection_field_collection_field_name",
                  "fields": [
                    "collection_id",
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_field_relation": {
              "name": "collection_field_relation",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "cascade_on_delete": {
                  "name": "cascade_on_delete",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "collection_field_id": {
                  "name": "collection_field_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_field",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "relation_collection_field_id": {
                  "name": "relation_collection_field_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_field",
                    "field": "_id"
                  },
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_field_relation_pkey": {
                  "name": "collection_field_relation_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_index": {
              "name": "collection_index",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "collection_id": {
                  "name": "collection_id",
                  "field_type": "_int",
                  "relation": {
                    "collection": "collection",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "primary": {
                  "name": "primary",
                  "field_type": "_bool",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "unique": {
                  "name": "unique",
                  "field_type": "_bool",
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_index_collection_id_primary_idx": {
                  "name": "collection_index_collection_id_primary_idx",
                  "fields": [
                    "collection_id",
                    "\"primary\""
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_index_name": {
                  "name": "collection_index_name",
                  "fields": [
                    "name",
                    "collection_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_index_pkey": {
                  "name": "collection_index_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_index_item": {
              "name": "collection_index_item",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "collection_field_id": {
                  "name": "collection_field_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_field",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "collection_index_id": {
                  "name": "collection_index_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_index",
                    "field": "_id"
                  },
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_index_item_collection_index_id_collection_field__idx": {
                  "name": "collection_index_item_collection_index_id_collection_field__idx",
                  "fields": [
                    "collection_index_id",
                    "collection_field_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_index_item_pkey": {
                  "name": "collection_index_item_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "database": {
              "name": "database",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "database_name_idx": {
                  "name": "database_name_idx",
                  "fields": [
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "database_pkey": {
                  "name": "database_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "field_type": {
              "name": "field_type",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "dataman_type": {
                  "name": "dataman_type",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "field_type_name_idx": {
                  "name": "field_type_name_idx",
                  "fields": [
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "field_type_pkey": {
                  "name": "field_type_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "field_type_constraint": {
              "name": "field_type_constraint",
              "fields": {
                "args": {
                  "name": "args",
                  "field_type": "_json",
                  "provision_state": 3
                },
                "constraint": {
                  "name": "constraint",
                  "field_type": "_string",
                  "not_null": true,
                  "provision_state": 3
                },
                "f": {
                  "name": "f",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "field_type_id": {
                  "name": "field_type_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "validation_error": {
                  "name": "validation_error",
                  "field_type": "_string",
                  "provision_state": 3
                }
              },
              "indexes": {
                "field_type_constraint_field_type_id_constraint_id_idx": {
                  "name": "field_type_constraint_field_type_id_constraint_id_idx",
                  "fields": [
                    "field_type_id",
                    "\"constraint\""
                  ],
                  "provision_state": 3
                },
                "field_type_constraint_pkey": {
                  "name": "field_type_constraint_pkey",
                  "fields": [
                    "f"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "shard_instance": {
              "name": "shard_instance",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "collection_shard": {
                  "name": "collection_shard",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "count": {
                  "name": "count",
                  "field_type": "_int",
                  "provision_state": 3
                },
                "database_id": {
                  "name": "database_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "database",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "database_shard": {
                  "name": "database_shard",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "instance": {
                  "name": "instance",
                  "field_type": "_int",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "shard_instance_database_id_count_instance_database_shard_co_idx": {
                  "name": "shard_instance_database_id_count_instance_database_shard_co_idx",
                  "fields": [
                    "database_id",
                    "count",
                    "instance",
                    "database_shard",
                    "collection_shard",
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "shard_instance_name_database_id_idx": {
                  "name": "shard_instance_name_database_id_idx",
                  "fields": [
                    "name",
                    "database_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "shard_instance_pkey": {
                  "name": "shard_instance_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            }
          },
          "provision_state": 3
        }
      },
      "provision_state": 3
    }
  },
  "field_types": {
    "_bool": {
      "name": "_bool",
      "dataman_type": "bool"
    },
    "_datetime": {
      "name": "_datetime",
      "dataman_type": "datetime"
    },
    "_document": {
      "name": "_document",
      "dataman_type": "document"
    },
    "_int": {
      "name": "_int",
      "dataman_type": "int"
    },
    "_json": {
      "name": "_json",
      "dataman_type": "json"
    },
    "_string": {
      "name": "_string",
      "dataman_type": "string"
    },
    "_text": {
      "name": "_text",
      "dataman_type": "text"
    }
  }
}
`
<commit_msg>Update schema<commit_after>package storagenode

func GetSchema() string {
	return schemaJson
}

// TODO: might as well make this a static struct var instantiation
const schemaJson string = `
{
  "databases": {
    "dataman_storage": {
      "name": "dataman_storage",
      "shard_instances": {
        "public": {
          "name": "public",
          "count": 1,
          "instance": 1,
          "collections": {
            "collection": {
              "name": "collection",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "shard_instance_id": {
                  "name": "shard_instance_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "shard_instance",
                    "field": "_id"
                  },
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_name_shard_instance_id_idx": {
                  "name": "collection_name_shard_instance_id_idx",
                  "fields": [
                    "name",
                    "shard_instance_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_pkey": {
                  "name": "collection_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_field": {
              "name": "collection_field",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "collection_id": {
                  "name": "collection_id",
                  "field_type": "_int",
                  "relation": {
                    "collection": "collection",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "default": {
                  "name": "default",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "field_type": {
                  "name": "field_type",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "not_null": {
                  "name": "not_null",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "parent_collection_field_id": {
                  "name": "parent_collection_field_id",
                  "field_type": "_int",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_field_pkey": {
                  "name": "collection_field_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                },
                "index_collection_field_collection_field_name": {
                  "name": "index_collection_field_collection_field_name",
                  "fields": [
                    "collection_id",
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_field_relation": {
              "name": "collection_field_relation",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "cascade_on_delete": {
                  "name": "cascade_on_delete",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "collection_field_id": {
                  "name": "collection_field_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_field",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "relation_collection_field_id": {
                  "name": "relation_collection_field_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_field",
                    "field": "_id"
                  },
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_field_relation_pkey": {
                  "name": "collection_field_relation_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_index": {
              "name": "collection_index",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "collection_id": {
                  "name": "collection_id",
                  "field_type": "_int",
                  "relation": {
                    "collection": "collection",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "primary": {
                  "name": "primary",
                  "field_type": "_bool",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "unique": {
                  "name": "unique",
                  "field_type": "_bool",
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_index_collection_id_primary_idx": {
                  "name": "collection_index_collection_id_primary_idx",
                  "fields": [
                    "collection_id",
                    "\"primary\""
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_index_name": {
                  "name": "collection_index_name",
                  "fields": [
                    "name",
                    "collection_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_index_pkey": {
                  "name": "collection_index_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "collection_index_item": {
              "name": "collection_index_item",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "collection_field_id": {
                  "name": "collection_field_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_field",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "collection_index_id": {
                  "name": "collection_index_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "collection_index",
                    "field": "_id"
                  },
                  "provision_state": 3
                }
              },
              "indexes": {
                "collection_index_item_collection_index_id_collection_field__idx": {
                  "name": "collection_index_item_collection_index_id_collection_field__idx",
                  "fields": [
                    "collection_index_id",
                    "collection_field_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "collection_index_item_pkey": {
                  "name": "collection_index_item_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "database": {
              "name": "database",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "database_name_idx": {
                  "name": "database_name_idx",
                  "fields": [
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "database_pkey": {
                  "name": "database_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "field_type": {
              "name": "field_type",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "dataman_type": {
                  "name": "dataman_type",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "field_type_name_idx": {
                  "name": "field_type_name_idx",
                  "fields": [
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "field_type_pkey": {
                  "name": "field_type_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "field_type_constraint": {
              "name": "field_type_constraint",
              "fields": {
                "args": {
                  "name": "args",
                  "field_type": "_json",
                  "provision_state": 3
                },
                "constraint": {
                  "name": "constraint",
                  "field_type": "_string",
                  "not_null": true,
                  "provision_state": 3
                },
                "f": {
                  "name": "f",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "field_type_id": {
                  "name": "field_type_id",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                },
                "validation_error": {
                  "name": "validation_error",
                  "field_type": "_string",
                  "provision_state": 3
                }
              },
              "indexes": {
                "field_type_constraint_field_type_id_constraint_id_idx": {
                  "name": "field_type_constraint_field_type_id_constraint_id_idx",
                  "fields": [
                    "field_type_id",
                    "\"constraint\""
                  ],
                  "provision_state": 3
                },
                "field_type_constraint_pkey": {
                  "name": "field_type_constraint_pkey",
                  "fields": [
                    "f"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            },
            "shard_instance": {
              "name": "shard_instance",
              "fields": {
                "_id": {
                  "name": "_id",
                  "field_type": "_serial",
                  "provision_state": 3
                },
                "collection_shard": {
                  "name": "collection_shard",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "count": {
                  "name": "count",
                  "field_type": "_int",
                  "provision_state": 3
                },
                "database_id": {
                  "name": "database_id",
                  "field_type": "_int",
                  "not_null": true,
                  "relation": {
                    "collection": "database",
                    "field": "_id"
                  },
                  "provision_state": 3
                },
                "database_shard": {
                  "name": "database_shard",
                  "field_type": "_bool",
                  "not_null": true,
                  "provision_state": 3
                },
                "instance": {
                  "name": "instance",
                  "field_type": "_int",
                  "provision_state": 3
                },
                "name": {
                  "name": "name",
                  "field_type": "_string",
                  "provision_state": 3
                },
                "provision_state": {
                  "name": "provision_state",
                  "field_type": "_int",
                  "not_null": true,
                  "provision_state": 3
                }
              },
              "indexes": {
                "shard_instance_database_id_count_instance_database_shard_co_idx": {
                  "name": "shard_instance_database_id_count_instance_database_shard_co_idx",
                  "fields": [
                    "database_id",
                    "count",
                    "instance",
                    "database_shard",
                    "collection_shard",
                    "name"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "shard_instance_name_database_id_idx": {
                  "name": "shard_instance_name_database_id_idx",
                  "fields": [
                    "name",
                    "database_id"
                  ],
                  "unique": true,
                  "provision_state": 3
                },
                "shard_instance_pkey": {
                  "name": "shard_instance_pkey",
                  "fields": [
                    "_id"
                  ],
                  "unique": true,
                  "primary": true,
                  "provision_state": 3
                }
              },
              "provision_state": 3
            }
          },
          "provision_state": 3
        }
      },
      "provision_state": 3
    }
  },
  "field_types": {
    "_bool": {
      "name": "_bool",
      "dataman_type": "bool"
    },
    "_datetime": {
      "name": "_datetime",
      "dataman_type": "datetime"
    },
    "_document": {
      "name": "_document",
      "dataman_type": "document"
    },
    "_int": {
      "name": "_int",
      "dataman_type": "int"
    },
    "_json": {
      "name": "_json",
      "dataman_type": "json"
    },
    "_serial": {
      "name": "_serial",
      "dataman_type": "serial"
    },
    "_string": {
      "name": "_string",
      "dataman_type": "string"
    },
    "_text": {
      "name": "_text",
      "dataman_type": "text"
    }
  }
}
`
<|endoftext|>


<commit_before>// Copyright 2016 Simon Eisenmann <simon@longsleep.org>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/longsleep/sunxi-disp-tool/disp2"
	"github.com/longsleep/sunxi-disp-tool/kernel"
)

func usage() {
	fmt.Println("Usage: sunxi-disp-tool [<global-options>] <command> [<args>]")
	fmt.Println("Global options:")
	fmt.Println("  -screen int")
	fmt.Println("          Screen ID (default 0)")
	fmt.Println("Available commands are:")
	fmt.Println("  switch   Switch HDMI output mode")
	fmt.Println("  init     Initialize HDMI output mode from Kernel args")
}

func main() {
	globalOptions := flag.NewFlagSet("global", flag.ContinueOnError)
	screenID := globalOptions.Int("screen", 0, "Screen ID")

	switchCommand := flag.NewFlagSet("switch", flag.ExitOnError)
	outputMode := switchCommand.Int("mode", disp2.DISP_TV_MOD_1080P_60HZ, "Set HDMI output mode by number")
	outputModeName := switchCommand.String("name", "", "Set HDMI output mode by name")

	initCommand := flag.NewFlagSet("init", flag.ExitOnError)
	initKernelArg := initCommand.String("kernelarg", "disp.screen0_output_mode", "Set HDMI output mode from Kernel arg")

	globalOptions.Parse(os.Args[1:])
	args := globalOptions.Args()

	if len(args) == 0 {
		usage()
		return
	}

	switch args[0] {
	case "switch":
		switchCommand.Parse(args[1:])
	case "init":
		initCommand.Parse(args[1:])
	case "-h":
		usage()
		return
	default:
		fmt.Printf("%q is not valid command.\n", args[0])
		os.Exit(1)
	}

	disp, err := disp2.New()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(2)

	}
	defer disp.Close()

	if switchCommand.Parsed() {
		if *outputModeName != "" {
			mode := disp2.GetTVModFromString(*outputModeName)
			if mode != disp2.DISP_TV_MODE_UNKOWN {
				*outputMode = mode
			}
		}

		err = disp.Switch(*screenID, disp2.DISP_OUTPUT_TYPE_HDMI, uint64(*outputMode))
	} else if initCommand.Parsed() {
		mode := disp2.DISP_TV_MODE_UNKOWN
		if *initKernelArg != "" {
			boot, ok := kernel.GetCmdlineParamValue(*initKernelArg)
			if ok {
				resolutions := strings.Split(boot, ":")
				mode := disp2.GetTVModFromString(resolutions...)
				if mode == disp2.DISP_TV_MODE_UNKOWN {
					// No or invalid mode set via kerne parameter. Do nothing.
					return
				}
			}
		}

		err = disp.Switch(*screenID, disp2.DISP_OUTPUT_TYPE_HDMI, uint64(mode))
	}

	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(3)
	}
}
<commit_msg>Fix init command so it actually works.<commit_after>// Copyright 2016 Simon Eisenmann <simon@longsleep.org>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/longsleep/sunxi-disp-tool/disp2"
	"github.com/longsleep/sunxi-disp-tool/kernel"
)

func usage() {
	fmt.Println("Usage: sunxi-disp-tool [<global-options>] <command> [<args>]")
	fmt.Println("Global options:")
	fmt.Println("  -screen int")
	fmt.Println("          Screen ID (default 0)")
	fmt.Println("Available commands are:")
	fmt.Println("  switch   Switch HDMI output mode")
	fmt.Println("  init     Initialize HDMI output mode from Kernel args")
}

func main() {
	globalOptions := flag.NewFlagSet("global", flag.ContinueOnError)
	screenID := globalOptions.Int("screen", 0, "Screen ID")

	switchCommand := flag.NewFlagSet("switch", flag.ExitOnError)
	outputMode := switchCommand.Int("mode", disp2.DISP_TV_MOD_1080P_60HZ, "Set HDMI output mode by number")
	outputModeName := switchCommand.String("name", "", "Set HDMI output mode by name")

	initCommand := flag.NewFlagSet("init", flag.ExitOnError)
	initKernelArg := initCommand.String("kernelarg", "disp.screen0_output_mode", "Set HDMI output mode from Kernel arg")

	globalOptions.Parse(os.Args[1:])
	args := globalOptions.Args()

	if len(args) == 0 {
		usage()
		return
	}

	switch args[0] {
	case "switch":
		switchCommand.Parse(args[1:])
	case "init":
		initCommand.Parse(args[1:])
	case "-h":
		usage()
		return
	default:
		fmt.Printf("%q is not valid command.\n", args[0])
		os.Exit(1)
	}

	disp, err := disp2.New()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(2)

	}
	defer disp.Close()

	if switchCommand.Parsed() {
		if *outputModeName != "" {
			mode := disp2.GetTVModFromString(*outputModeName)
			if mode != disp2.DISP_TV_MODE_UNKOWN {
				*outputMode = mode
			}
		}

		err = disp.Switch(*screenID, disp2.DISP_OUTPUT_TYPE_HDMI, uint64(*outputMode))
	} else if initCommand.Parsed() {
		mode := disp2.DISP_TV_MODE_UNKOWN
		if *initKernelArg != "" {
			boot, ok := kernel.GetCmdlineParamValue(*initKernelArg)
			if ok {
				resolutions := strings.Split(boot, ":")
				mode = disp2.GetTVModFromString(resolutions...)
				if mode == disp2.DISP_TV_MODE_UNKOWN {
					// No or invalid mode set via kerne parameter. Do nothing.
					return
				}
			}
		}

		err = disp.Switch(*screenID, disp2.DISP_OUTPUT_TYPE_HDMI, uint64(mode))
	}

	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(3)
	}
}
<|endoftext|>


<commit_before>package imgsvr

import (
	"errors"
	"fmt"
	l4g "github.com/alecthomas/log4go"
	"github.com/ctripcorp/cat"
	"github.com/ctripcorp/nephele/imgsvr/img4g"
	"github.com/ctripcorp/nephele/imgsvr/proc"
	"github.com/ctripcorp/nephele/imgsvr/storage"
	"github.com/ctripcorp/nephele/util"
	"net/http"
	"regexp"
	"strconv"
	"strings"
	"time"
)

var (
	legalUrl     = util.RegexpExt{regexp.MustCompile("^/images/(.*?)_(R|C|Z|W)_([0-9]+)_([0-9]+)(_R([0-9]+))?(_C([a-zA-Z]+))?(_Q(?P<n0>[0-9]+))?(_M((?P<wn>[a-zA-Z0-9]+)(_(?P<wl>[1-9]))?))?.(?P<ext>jpg|jpeg|gif|png|Jpg)$")}
	forbiddenUrl = util.RegexpExt{regexp.MustCompile("^/images/fd/([a-zA-Z]+)/([a-zA-Z0-9]+)/(.*?)_Source.(?P<ext>jpg|jpeg|gif|png|Jpg)$")}
	proxyPassUrl = util.RegexpExt{regexp.MustCompile("^/images/fd/([a-zA-Z]+)/([a-zA-Z0-9]+)/(.*?).(?P<ext>jpg|jpeg|gif|png|Jpg)$")}
)

type Handler struct {
	ChainBuilder *ProcChainBuilder
}

func (handler *Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	Cat := cat.Instance()
	handler.ChainBuilder = &ProcChainBuilder{Cat}
	uri := request.URL.String()
	tran := Cat.NewTransaction("URL", getShortUri(uri))
	var (
		err       error
		isSuccess bool = true
	)
	defer func() {
		p := recover()
		if p != nil {
			l4g.Error("%s; rcv(url:%s)", p, uri)
			Cat.LogPanic(p)
			tran.SetStatus(p)
		}

		if isSuccess {
			tran.SetStatus("0")
			tran.Complete()
		} else {
			tran.SetStatus(err)
			tran.Complete()
		}
		if p != nil || err != nil {
			http.Error(writer, http.StatusText(404), 404)
		}
	}()

	LogEvent(Cat, "URL", "URL.client", map[string]string{
		"clientip": GetClientIP(request),
		"serverip": GetIP(),
		"proto":    request.Proto,
		"referer":  request.Referer(),
		//"agent":    request.UserAgent(),
	})

	LogEvent(Cat, "URL", "URL.method", map[string]string{
		"Http": request.Method + " " + uri,
	})

	LogEvent(Cat, "UpstreamProcess", JoinString(GetIP(), ":", WorkerPort), nil)

	params, ok1 := legalUrl.FindStringSubmatchMap(uri)
	if !ok1 {
		err = errors.New("uri.parseerror")
		l4g.Error("%s; rcv(url:%s)", err, uri)
		LogErrorEvent(Cat, "uri.parseerror", "")
		return
	}
	//parse storage from url parameters
	store, storagetype, err1 := FindStorage(params, Cat)
	if err1 != nil {
		err = errors.New("storage.parseerror")
		l4g.Error("%s; rcv(url:%s)", err1, uri)
		LogErrorEvent(Cat, "storage.parseerror", err1.Error())
		return
	}
	//parse handlers chain from url parameters
	chain, buildErr := handler.ChainBuilder.Build(params)
	if buildErr != nil {
		err = errors.New(buildErr.Type())
		l4g.Error("%s; rcv(url:%s)", buildErr.Error(), uri)
		LogErrorEvent(Cat, buildErr.Type(), buildErr.Error())
		return
	}
	//download image from storage
	var bts []byte
	func() {
		type storageError interface {
			Error() string
			Normal() bool 	//is normal error?
			Type() string	//error type
		}

		var err1 error
		getimagetran := Cat.NewTransaction("Storage", storagetype)
		defer func() {
			if err1 != nil {
				l4g.Error("%s -- %s; rcv(url:%s)", "getimage", err1.Error(), uri)
			        e, ok := err1.(storageError)
				if ok && e.Normal() {
					err = errors.New(fmt.Sprintf("%v.%v", storagetype, e.Type()))
					LogErrorEvent(Cat, fmt.Sprintf("%v.%v", storagetype, e.Type()), e.Error())
				} else {
					err = errors.New(storagetype + ".UnExpectedError")
					LogErrorEvent(Cat, err.Error(), err1.Error())
					isSuccess = false
				}
			} else if len(bts) == 0 {
				err = errors.New(storagetype + ".ImgLenZero")
				LogErrorEvent(Cat, err.Error(), "recv image length is 0")
				l4g.Error("%s -- %s; rcv(url:%s)", "getimage", "recv image length is 0", uri)
			}
			getimagetran.SetStatus(err)
			getimagetran.Complete()
		}()
		bts, err1 = store.GetImage()
	}()
	if err != nil {
		return
	}
	size := len(bts)
	sizestr := strconv.Itoa(size)
	tran.AddData("size", sizestr)
	Cat.LogEvent("Size", GetImageSizeDistribution(size))

	l4g.Debug("get image length(%d) rcv(url:%s)", size, request.URL.String())
	format, _ := params["ext"]
	img := &img4g.Image{Blob: bts, Format: format}

	rspChan := make(chan bool, 1)
	task := &nepheleTask{inImg:img, chain:chain, rspChan:rspChan, CatInstance:Cat, canceled:false}
	taskChan <- task

	select {
	case ok := <- rspChan:
		if !ok {
			err = errors.New("processerror")
			isSuccess = false
			l4g.Error("%s; rcv(url:%s)", err, uri)
			return
		}
	case <-time.After(time.Second * 5):
		task.SetCanceled()
		err = errors.New("processtimeout")
		l4g.Error("%s; rcv(url:%s)", err, uri)
		isSuccess = false
		LogErrorEvent(Cat, "processtimeout", "")
		return
	}

	writer.Header().Set("Content-Type", "image/"+format)
	writer.Header().Set("Content-Length", strconv.Itoa(len(img.Blob)))
	writer.Header().Set("Last-Modified", "2015/1/1 01:01:01")
	l4g.Debug("final size->>>" + strconv.Itoa(len(img.Blob)))
	if _, err1 = writer.Write(img.Blob); err1 != nil {
		l4g.Error(err1)
		err = errors.New("response.writeerror")
		LogErrorEvent(Cat, "response.writeerror", err1.Error())
		isSuccess = false
	}
}

func CycleHandleImage() {
	defer func() {
		if err := recover(); err != nil {
			l4g.Error("%s -- %s", "handleimage.recovererror", err)
			LogErrorEvent(CatInstance, "handleimage.recovererror", fmt.Sprintf("%v", err))
			go CycleHandleImage()
		}
	}()

	for {
		status := true
		//get a task from task chan
		task := <- taskChan
		if task.GetCanceled() {
			continue
		}
		chain := task.chain
		image := task.inImg
		if err := chainProcImg(task.CatInstance, chain, image); err != nil {
			l4g.Error("%s -- %s", "processerror", err)
			LogErrorEvent(task.CatInstance, "processerror", err.Error())
			status = false
		}
		task.rspChan <- status
	}
}

func chainProcImg(catinstance cat.Cat, chain *proc.ProcessorChain, img *img4g.Image) (err error) {
	defer func() {
		if r := recover(); r != nil {
			l4g.Error("%s -- %s", "processimage.recovererror", err)
			LogErrorEvent(catinstance, "processimage.recovererror", fmt.Sprintf("%v", r))
		}
	}()
	defer func() {
		tran := catinstance.NewTransaction("Command", "DestoryImgWand")
		defer func() {
			tran.SetStatus("0")
			tran.Complete()
		}()
		img.DestoryWand()
	}()
	func(){
		tran := catinstance.NewTransaction("Command", "CreateImgWand")
		defer func() {
			tran.SetStatus(err)
			tran.Complete()
		}()
		err = img.CreateWand()
	}()
	if err != nil { return }
	if err = chain.Process(img); err != nil {
		return
	}
	func() {
		tran := catinstance.NewTransaction("Command", "WriteImgToBlob")
		defer func() {
			tran.SetStatus(err)
			tran.Complete()
		}()
		err = img.WriteImageBlob()
	}()
	return
}

func FindStorage(params map[string]string, Cat cat.Cat) (storage.Storage, string, error) {
	srcPath, ok := params[":1"]
	if !ok {
		return nil, "", errors.New("Url.UnExpected")
	}
	format, ok := params["ext"]
	if !ok {
		return nil, "", errors.New("Image.Ext.Invalid()")
	}
	sourceType, _, path := ParseUri(srcPath)
	s, err := GetStorage(sourceType, path+"."+format, Cat)
	return s, sourceType, err
}

func getShortUri(uri string) string {
	arr := strings.Split(uri, "/")
	if len(arr) < 4 {
		return uri
	}
	if arr[2] == "fd" || arr[2] == "t1" {
		return JoinString("/", arr[1], "/", arr[2], "/", arr[3])
	} else {
		return JoinString("/", arr[1], "/", arr[2])
	}
}
<commit_msg>modify: if the image is not eixst, the storage transaction is success<commit_after>package imgsvr

import (
	"errors"
	"fmt"
	l4g "github.com/alecthomas/log4go"
	"github.com/ctripcorp/cat"
	"github.com/ctripcorp/nephele/imgsvr/img4g"
	"github.com/ctripcorp/nephele/imgsvr/proc"
	"github.com/ctripcorp/nephele/imgsvr/storage"
	"github.com/ctripcorp/nephele/util"
	"net/http"
	"regexp"
	"strconv"
	"strings"
	"time"
)

var (
	legalUrl     = util.RegexpExt{regexp.MustCompile("^/images/(.*?)_(R|C|Z|W)_([0-9]+)_([0-9]+)(_R([0-9]+))?(_C([a-zA-Z]+))?(_Q(?P<n0>[0-9]+))?(_M((?P<wn>[a-zA-Z0-9]+)(_(?P<wl>[1-9]))?))?.(?P<ext>jpg|jpeg|gif|png|Jpg)$")}
	forbiddenUrl = util.RegexpExt{regexp.MustCompile("^/images/fd/([a-zA-Z]+)/([a-zA-Z0-9]+)/(.*?)_Source.(?P<ext>jpg|jpeg|gif|png|Jpg)$")}
	proxyPassUrl = util.RegexpExt{regexp.MustCompile("^/images/fd/([a-zA-Z]+)/([a-zA-Z0-9]+)/(.*?).(?P<ext>jpg|jpeg|gif|png|Jpg)$")}
)

type Handler struct {
	ChainBuilder *ProcChainBuilder
}

func (handler *Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	Cat := cat.Instance()
	handler.ChainBuilder = &ProcChainBuilder{Cat}
	uri := request.URL.String()
	tran := Cat.NewTransaction("URL", getShortUri(uri))
	var (
		err       error
		isSuccess bool = true
	)
	defer func() {
		p := recover()
		if p != nil {
			l4g.Error("%s; rcv(url:%s)", p, uri)
			Cat.LogPanic(p)
			tran.SetStatus(p)
		}

		if isSuccess {
			tran.SetStatus("0")
			tran.Complete()
		} else {
			tran.SetStatus(err)
			tran.Complete()
		}
		if p != nil || err != nil {
			http.Error(writer, http.StatusText(404), 404)
		}
	}()

	LogEvent(Cat, "URL", "URL.client", map[string]string{
		"clientip": GetClientIP(request),
		"serverip": GetIP(),
		"proto":    request.Proto,
		"referer":  request.Referer(),
		//"agent":    request.UserAgent(),
	})

	LogEvent(Cat, "URL", "URL.method", map[string]string{
		"Http": request.Method + " " + uri,
	})

	LogEvent(Cat, "UpstreamProcess", JoinString(GetIP(), ":", WorkerPort), nil)

	params, ok1 := legalUrl.FindStringSubmatchMap(uri)
	if !ok1 {
		err = errors.New("uri.parseerror")
		l4g.Error("%s; rcv(url:%s)", err, uri)
		LogErrorEvent(Cat, "uri.parseerror", "")
		return
	}
	//parse storage from url parameters
	store, storagetype, err1 := FindStorage(params, Cat)
	if err1 != nil {
		err = errors.New("storage.parseerror")
		l4g.Error("%s; rcv(url:%s)", err1, uri)
		LogErrorEvent(Cat, "storage.parseerror", err1.Error())
		return
	}
	//parse handlers chain from url parameters
	chain, buildErr := handler.ChainBuilder.Build(params)
	if buildErr != nil {
		err = errors.New(buildErr.Type())
		l4g.Error("%s; rcv(url:%s)", buildErr.Error(), uri)
		LogErrorEvent(Cat, buildErr.Type(), buildErr.Error())
		return
	}
	//download image from storage
	var bts []byte
	func() {
		type storageError interface {
			Error() string
			Normal() bool 	//is normal error?
			Type() string	//error type
		}

		var err1 error
		getimagetran := Cat.NewTransaction("Storage", storagetype)
		defer func() {
			if err1 != nil {
				l4g.Error("%s -- %s; rcv(url:%s)", "getimage", err1.Error(), uri)
			        e, ok := err1.(storageError)
				if ok && e.Normal() {
					err = errors.New(fmt.Sprintf("%v.%v", storagetype, e.Type()))
					LogErrorEvent(Cat, fmt.Sprintf("%v.%v", storagetype, e.Type()), e.Error())
				} else {
					err = errors.New(storagetype + ".UnExpectedError")
					LogErrorEvent(Cat, err.Error(), err1.Error())
					isSuccess = false
				}
			} else if len(bts) == 0 {
				err = errors.New(storagetype + ".ImgLenZero")
				LogErrorEvent(Cat, err.Error(), "recv image length is 0")
				l4g.Error("%s -- %s; rcv(url:%s)", "getimage", "recv image length is 0", uri)
			}
			if isSuccess {
				getimagetran.SetStatus("0")
			} else {
				getimagetran.SetStatus(err)
			}
			getimagetran.Complete()
		}()
		bts, err1 = store.GetImage()
	}()
	if err != nil {
		return
	}
	size := len(bts)
	sizestr := strconv.Itoa(size)
	tran.AddData("size", sizestr)
	Cat.LogEvent("Size", GetImageSizeDistribution(size))

	l4g.Debug("get image length(%d) rcv(url:%s)", size, request.URL.String())
	format, _ := params["ext"]
	img := &img4g.Image{Blob: bts, Format: format}

	rspChan := make(chan bool, 1)
	task := &nepheleTask{inImg:img, chain:chain, rspChan:rspChan, CatInstance:Cat, canceled:false}
	taskChan <- task

	select {
	case ok := <- rspChan:
		if !ok {
			err = errors.New("processerror")
			isSuccess = false
			l4g.Error("%s; rcv(url:%s)", err, uri)
			return
		}
	case <-time.After(time.Second * 5):
		task.SetCanceled()
		err = errors.New("processtimeout")
		l4g.Error("%s; rcv(url:%s)", err, uri)
		isSuccess = false
		LogErrorEvent(Cat, "processtimeout", "")
		return
	}

	writer.Header().Set("Content-Type", "image/"+format)
	writer.Header().Set("Content-Length", strconv.Itoa(len(img.Blob)))
	writer.Header().Set("Last-Modified", "2015/1/1 01:01:01")
	l4g.Debug("final size->>>" + strconv.Itoa(len(img.Blob)))
	if _, err1 = writer.Write(img.Blob); err1 != nil {
		l4g.Error(err1)
		err = errors.New("response.writeerror")
		LogErrorEvent(Cat, "response.writeerror", err1.Error())
		isSuccess = false
	}
}

func CycleHandleImage() {
	defer func() {
		if err := recover(); err != nil {
			l4g.Error("%s -- %s", "handleimage.recovererror", err)
			LogErrorEvent(CatInstance, "handleimage.recovererror", fmt.Sprintf("%v", err))
			go CycleHandleImage()
		}
	}()

	for {
		status := true
		//get a task from task chan
		task := <- taskChan
		if task.GetCanceled() {
			continue
		}
		chain := task.chain
		image := task.inImg
		if err := chainProcImg(task.CatInstance, chain, image); err != nil {
			l4g.Error("%s -- %s", "processerror", err)
			LogErrorEvent(task.CatInstance, "processerror", err.Error())
			status = false
		}
		task.rspChan <- status
	}
}

func chainProcImg(catinstance cat.Cat, chain *proc.ProcessorChain, img *img4g.Image) (err error) {
	defer func() {
		if r := recover(); r != nil {
			l4g.Error("%s -- %s", "processimage.recovererror", err)
			LogErrorEvent(catinstance, "processimage.recovererror", fmt.Sprintf("%v", r))
		}
	}()
	defer func() {
		tran := catinstance.NewTransaction("Command", "DestoryImgWand")
		defer func() {
			tran.SetStatus("0")
			tran.Complete()
		}()
		img.DestoryWand()
	}()
	func(){
		tran := catinstance.NewTransaction("Command", "CreateImgWand")
		defer func() {
			tran.SetStatus(err)
			tran.Complete()
		}()
		err = img.CreateWand()
	}()
	if err != nil { return }
	if err = chain.Process(img); err != nil {
		return
	}
	func() {
		tran := catinstance.NewTransaction("Command", "WriteImgToBlob")
		defer func() {
			tran.SetStatus(err)
			tran.Complete()
		}()
		err = img.WriteImageBlob()
	}()
	return
}

func FindStorage(params map[string]string, Cat cat.Cat) (storage.Storage, string, error) {
	srcPath, ok := params[":1"]
	if !ok {
		return nil, "", errors.New("Url.UnExpected")
	}
	format, ok := params["ext"]
	if !ok {
		return nil, "", errors.New("Image.Ext.Invalid()")
	}
	sourceType, _, path := ParseUri(srcPath)
	s, err := GetStorage(sourceType, path+"."+format, Cat)
	return s, sourceType, err
}

func getShortUri(uri string) string {
	arr := strings.Split(uri, "/")
	if len(arr) < 4 {
		return uri
	}
	if arr[2] == "fd" || arr[2] == "t1" {
		return JoinString("/", arr[1], "/", arr[2], "/", arr[3])
	} else {
		return JoinString("/", arr[1], "/", arr[2])
	}
}
<|endoftext|>


<commit_before>package kingpin

import (
	"bytes"
	"fmt"
	"go/doc"
	"io"
	"strings"

	"github.com/alecthomas/template"
)

var (
	preIndent = "  "
)

func formatTwoColumns(w io.Writer, indent, padding, width int, rows [][2]string) {
	// Find size of first column.
	s := 0
	for _, row := range rows {
		if c := len(row[0]); c > s && c < 30 {
			s = c
		}
	}

	indentStr := strings.Repeat(" ", indent)
	offsetStr := strings.Repeat(" ", s+padding)

	for _, row := range rows {
		buf := bytes.NewBuffer(nil)
		doc.ToText(buf, row[1], "", preIndent, width-s-padding-indent)
		lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
		fmt.Fprintf(w, "%s%-*s%*s", indentStr, s, row[0], padding, "")
		if len(row[0]) >= 30 {
			fmt.Fprintf(w, "\n%s%s", indentStr, offsetStr)
		}
		fmt.Fprintf(w, "%s\n", lines[0])
		for _, line := range lines[1:] {
			fmt.Fprintf(w, "%s%s%s\n", indentStr, offsetStr, line)
		}
	}
}

// Usage writes application usage to w. It parses args to determine
// appropriate help context, such as which command to show help for.
func (a *Application) Usage(args []string) {
	context, err := a.parseContext(true, args)
	a.FatalIfError(err, "")
	if err := a.UsageForContextWithTemplate(context, 2, a.usageTemplate); err != nil {
		panic(err)
	}
}

func formatAppUsage(app *ApplicationModel) string {
	s := []string{app.Name}
	if len(app.Flags) > 0 {
		s = append(s, app.FlagSummary())
	}
	if len(app.Args) > 0 {
		s = append(s, app.ArgSummary())
	}
	return strings.Join(s, " ")
}

func formatCmdUsage(app *ApplicationModel, cmd *CmdModel) string {
	s := []string{app.Name, cmd.String()}
	if len(app.Flags) > 0 {
		s = append(s, app.FlagSummary())
	}
	if len(app.Args) > 0 {
		s = append(s, app.ArgSummary())
	}
	return strings.Join(s, " ")
}

func formatFlag(haveShort bool, flag *FlagModel) string {
	flagString := ""
	if flag.Short != 0 {
		flagString += fmt.Sprintf("-%c, --%s", flag.Short, flag.Name)
	} else {
		if haveShort {
			flagString += fmt.Sprintf("    --%s", flag.Name)
		} else {
			flagString += fmt.Sprintf("--%s", flag.Name)
		}
	}
	if !flag.IsBoolFlag() {
		flagString += fmt.Sprintf("=%s", flag.FormatPlaceHolder())
	}
	return flagString
}

type templateParseContext struct {
	SelectedCommand *CmdModel
	*FlagGroupModel
	*ArgGroupModel
}

type templateContext struct {
	App     *ApplicationModel
	Width   int
	Context *templateParseContext
}

// UsageForContext displays usage information from a ParseContext (obtained from
// Application.ParseContext() or Action(f) callbacks).
func (a *Application) UsageForContext(context *ParseContext) error {
	return a.UsageForContextWithTemplate(context, 2, a.usageTemplate)
}

// UsageForContextWithTemplate is the base usage function. You generally don't need to use this.
func (a *Application) UsageForContextWithTemplate(context *ParseContext, indent int, tmpl string) error {
	width := guessWidth(a.writer)
	funcs := template.FuncMap{
		"Indent": func(level int) string {
			return strings.Repeat(" ", level*indent)
		},
		"Wrap": func(indent int, s string) string {
			buf := bytes.NewBuffer(nil)
			indentText := strings.Repeat(" ", indent)
			doc.ToText(buf, s, indentText, indentText, width-indent)
			return buf.String()
		},
		"FormatFlag": formatFlag,
		"FlagsToTwoColumns": func(f []*FlagModel) [][2]string {
			rows := [][2]string{}
			haveShort := false
			for _, flag := range f {
				if flag.Short != 0 {
					haveShort = true
					break
				}
			}
			for _, flag := range f {
				if !flag.Hidden {
					rows = append(rows, [2]string{formatFlag(haveShort, flag), flag.Help})
				}
			}
			return rows
		},
		"RequiredFlags": func(f []*FlagModel) []*FlagModel {
			requiredFlags := []*FlagModel{}
			for _, flag := range f {
				if flag.Required == true {
					requiredFlags = append(requiredFlags, flag)
				}
			}
			return requiredFlags
		},
		"OptionalFlags": func(f []*FlagModel) []*FlagModel {
			optionalFlags := []*FlagModel{}
			for _, flag := range f {
				if flag.Required == false {
					optionalFlags = append(optionalFlags, flag)
				}
			}
			return optionalFlags
		},
		"ArgsToTwoColumns": func(a []*ArgModel) [][2]string {
			rows := [][2]string{}
			for _, arg := range a {
				s := "<" + arg.Name + ">"
				if !arg.Required {
					s = "[" + s + "]"
				}
				rows = append(rows, [2]string{s, arg.Help})
			}
			return rows
		},
		"FormatTwoColumns": func(rows [][2]string) string {
			buf := bytes.NewBuffer(nil)
			formatTwoColumns(buf, indent, indent, width, rows)
			return buf.String()
		},
		"FormatTwoColumnsWithIndent": func(rows [][2]string, indent, padding int) string {
			buf := bytes.NewBuffer(nil)
			formatTwoColumns(buf, indent, padding, width, rows)
			return buf.String()
		},
		"FormatAppUsage":     formatAppUsage,
		"FormatCommandUsage": formatCmdUsage,
		"IsCumulative": func(value Value) bool {
			_, ok := value.(remainderArg)
			return ok
		},
		"Char": func(c rune) string {
			return string(c)
		},
	}
	t, err := template.New("usage").Funcs(funcs).Parse(tmpl)
	if err != nil {
		return err
	}
	var selectedCommand *CmdModel
	if context.SelectedCommand != nil {
		selectedCommand = context.SelectedCommand.Model()
	}
	ctx := templateContext{
		App:   a.Model(),
		Width: width,
		Context: &templateParseContext{
			SelectedCommand: selectedCommand,
			FlagGroupModel:  context.flags.Model(),
			ArgGroupModel:   context.arguments.Model(),
		},
	}
	return t.Execute(a.writer, ctx)
}
<commit_msg>don't rely on signature, actually call into the function<commit_after>package kingpin

import (
	"bytes"
	"fmt"
	"go/doc"
	"io"
	"strings"

	"github.com/alecthomas/template"
)

var (
	preIndent = "  "
)

func formatTwoColumns(w io.Writer, indent, padding, width int, rows [][2]string) {
	// Find size of first column.
	s := 0
	for _, row := range rows {
		if c := len(row[0]); c > s && c < 30 {
			s = c
		}
	}

	indentStr := strings.Repeat(" ", indent)
	offsetStr := strings.Repeat(" ", s+padding)

	for _, row := range rows {
		buf := bytes.NewBuffer(nil)
		doc.ToText(buf, row[1], "", preIndent, width-s-padding-indent)
		lines := strings.Split(strings.TrimRight(buf.String(), "\n"), "\n")
		fmt.Fprintf(w, "%s%-*s%*s", indentStr, s, row[0], padding, "")
		if len(row[0]) >= 30 {
			fmt.Fprintf(w, "\n%s%s", indentStr, offsetStr)
		}
		fmt.Fprintf(w, "%s\n", lines[0])
		for _, line := range lines[1:] {
			fmt.Fprintf(w, "%s%s%s\n", indentStr, offsetStr, line)
		}
	}
}

// Usage writes application usage to w. It parses args to determine
// appropriate help context, such as which command to show help for.
func (a *Application) Usage(args []string) {
	context, err := a.parseContext(true, args)
	a.FatalIfError(err, "")
	if err := a.UsageForContextWithTemplate(context, 2, a.usageTemplate); err != nil {
		panic(err)
	}
}

func formatAppUsage(app *ApplicationModel) string {
	s := []string{app.Name}
	if len(app.Flags) > 0 {
		s = append(s, app.FlagSummary())
	}
	if len(app.Args) > 0 {
		s = append(s, app.ArgSummary())
	}
	return strings.Join(s, " ")
}

func formatCmdUsage(app *ApplicationModel, cmd *CmdModel) string {
	s := []string{app.Name, cmd.String()}
	if len(app.Flags) > 0 {
		s = append(s, app.FlagSummary())
	}
	if len(app.Args) > 0 {
		s = append(s, app.ArgSummary())
	}
	return strings.Join(s, " ")
}

func formatFlag(haveShort bool, flag *FlagModel) string {
	flagString := ""
	if flag.Short != 0 {
		flagString += fmt.Sprintf("-%c, --%s", flag.Short, flag.Name)
	} else {
		if haveShort {
			flagString += fmt.Sprintf("    --%s", flag.Name)
		} else {
			flagString += fmt.Sprintf("--%s", flag.Name)
		}
	}
	if !flag.IsBoolFlag() {
		flagString += fmt.Sprintf("=%s", flag.FormatPlaceHolder())
	}
	return flagString
}

type templateParseContext struct {
	SelectedCommand *CmdModel
	*FlagGroupModel
	*ArgGroupModel
}

type templateContext struct {
	App     *ApplicationModel
	Width   int
	Context *templateParseContext
}

// UsageForContext displays usage information from a ParseContext (obtained from
// Application.ParseContext() or Action(f) callbacks).
func (a *Application) UsageForContext(context *ParseContext) error {
	return a.UsageForContextWithTemplate(context, 2, a.usageTemplate)
}

// UsageForContextWithTemplate is the base usage function. You generally don't need to use this.
func (a *Application) UsageForContextWithTemplate(context *ParseContext, indent int, tmpl string) error {
	width := guessWidth(a.writer)
	funcs := template.FuncMap{
		"Indent": func(level int) string {
			return strings.Repeat(" ", level*indent)
		},
		"Wrap": func(indent int, s string) string {
			buf := bytes.NewBuffer(nil)
			indentText := strings.Repeat(" ", indent)
			doc.ToText(buf, s, indentText, indentText, width-indent)
			return buf.String()
		},
		"FormatFlag": formatFlag,
		"FlagsToTwoColumns": func(f []*FlagModel) [][2]string {
			rows := [][2]string{}
			haveShort := false
			for _, flag := range f {
				if flag.Short != 0 {
					haveShort = true
					break
				}
			}
			for _, flag := range f {
				if !flag.Hidden {
					rows = append(rows, [2]string{formatFlag(haveShort, flag), flag.Help})
				}
			}
			return rows
		},
		"RequiredFlags": func(f []*FlagModel) []*FlagModel {
			requiredFlags := []*FlagModel{}
			for _, flag := range f {
				if flag.Required == true {
					requiredFlags = append(requiredFlags, flag)
				}
			}
			return requiredFlags
		},
		"OptionalFlags": func(f []*FlagModel) []*FlagModel {
			optionalFlags := []*FlagModel{}
			for _, flag := range f {
				if flag.Required == false {
					optionalFlags = append(optionalFlags, flag)
				}
			}
			return optionalFlags
		},
		"ArgsToTwoColumns": func(a []*ArgModel) [][2]string {
			rows := [][2]string{}
			for _, arg := range a {
				s := "<" + arg.Name + ">"
				if !arg.Required {
					s = "[" + s + "]"
				}
				rows = append(rows, [2]string{s, arg.Help})
			}
			return rows
		},
		"FormatTwoColumns": func(rows [][2]string) string {
			buf := bytes.NewBuffer(nil)
			formatTwoColumns(buf, indent, indent, width, rows)
			return buf.String()
		},
		"FormatTwoColumnsWithIndent": func(rows [][2]string, indent, padding int) string {
			buf := bytes.NewBuffer(nil)
			formatTwoColumns(buf, indent, padding, width, rows)
			return buf.String()
		},
		"FormatAppUsage":     formatAppUsage,
		"FormatCommandUsage": formatCmdUsage,
		"IsCumulative": func(value Value) bool {
			r, ok := value.(remainderArg)
			return ok && r.IsCumulative()
		},
		"Char": func(c rune) string {
			return string(c)
		},
	}
	t, err := template.New("usage").Funcs(funcs).Parse(tmpl)
	if err != nil {
		return err
	}
	var selectedCommand *CmdModel
	if context.SelectedCommand != nil {
		selectedCommand = context.SelectedCommand.Model()
	}
	ctx := templateContext{
		App:   a.Model(),
		Width: width,
		Context: &templateParseContext{
			SelectedCommand: selectedCommand,
			FlagGroupModel:  context.flags.Model(),
			ArgGroupModel:   context.arguments.Model(),
		},
	}
	return t.Execute(a.writer, ctx)
}
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2016 Maciej Borzecki

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package site

import (
	"github.com/bboozzoo/q3stats/models"
	"github.com/gorilla/mux"
	"log"
	"net/http"
)

type matchViewWeaponStat struct {
	models.WeaponStat
	Accuracy uint
}

type matchViewPlayerData struct {
	PlayerID     uint
	Alias        string
	GeneralStats models.PlayerMatchStat
	Weapons      map[string]matchViewWeaponStat
	Items        map[string]models.ItemStat
}

func (s *Site) matchViewHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("site match view handler")
	id := mux.Vars(req)["id"]

	log.Printf("match ID: %s", id)

	m := s.m.GetMatchInfo(id)
	if m == nil {
		http.Error(w, "match not found", http.StatusNotFound)
	}

	data := struct {
		// data of all players
		Players []matchViewPlayerData
		Desc    *models.DescData
	}{
		make([]matchViewPlayerData, len(m.PlayerData)),
		models.GetItemDesc(),
	}

	// repack to a format expected by the template
	for i, pd := range m.PlayerData {
		mvpd := matchViewPlayerData{
			pd.Alias.PlayerID,
			pd.Alias.Alias,
			pd.Stats,
			make(map[string]matchViewWeaponStat),
			make(map[string]models.ItemStat),
		}
		for _, wd := range pd.Weapons {
			var acc uint = 0
			if wd.Shots != 0 {
				acc = (100 * wd.Hits) / wd.Shots
			}
			mvpd.Weapons[wd.Type] = matchViewWeaponStat{
				wd,
				acc,
			}
		}

		for _, itd := range pd.Items {
			mvpd.Items[itd.Type] = itd
		}
		data.Players[i] = mvpd
	}

	s.loadRenderOrError(w, data, "match.tmpl", "base.tmpl")
}
<commit_msg>models/matchview: dump Accuracty field, use model method instead<commit_after>// The MIT License (MIT)

// Copyright (c) 2016 Maciej Borzecki

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package site

import (
	"github.com/bboozzoo/q3stats/models"
	"github.com/gorilla/mux"
	"log"
	"net/http"
)

type matchViewWeaponStat struct {
	models.WeaponStat
}

type matchViewPlayerData struct {
	PlayerID     uint
	Alias        string
	GeneralStats models.PlayerMatchStat
	Weapons      map[string]matchViewWeaponStat
	Items        map[string]models.ItemStat
}

func (s *Site) matchViewHandler(w http.ResponseWriter, req *http.Request) {
	log.Printf("site match view handler")
	id := mux.Vars(req)["id"]

	log.Printf("match ID: %s", id)

	m := s.m.GetMatchInfo(id)
	if m == nil {
		http.Error(w, "match not found", http.StatusNotFound)
	}

	data := struct {
		// data of all players
		Players []matchViewPlayerData
		Desc    *models.DescData
	}{
		make([]matchViewPlayerData, len(m.PlayerData)),
		models.GetItemDesc(),
	}

	// repack to a format expected by the template
	for i, pd := range m.PlayerData {
		mvpd := matchViewPlayerData{
			pd.Alias.PlayerID,
			pd.Alias.Alias,
			pd.Stats,
			make(map[string]matchViewWeaponStat),
			make(map[string]models.ItemStat),
		}
		for _, wd := range pd.Weapons {
			mvpd.Weapons[wd.Type] = matchViewWeaponStat{
				wd,
			}
		}

		for _, itd := range pd.Items {
			mvpd.Items[itd.Type] = itd
		}
		data.Players[i] = mvpd
	}

	s.loadRenderOrError(w, data, "match.tmpl", "base.tmpl")
}
<|endoftext|>


<commit_before>package common

import (
	"errors"
)

// FindNextIndex analyses the specified sequence and tries to find the next occurence of id after the specified index (excluded)
// Therefore to find the first occurence of the id in the sequence, use -1 as the index
//
// If there is no occurence of id, then -1 is returned
//
// The sequence is supposed to be correct (in regards to its mathematical definition), and id is supposed to be a valid id for the sequence
func FindNextIndex(s []uint32, id uint32, index int) (int, error) {
	if index >= len(s) || index < -1 {
		return -1, errors.New("Index out of range")
	}

	for i := index + 1; i < len(s); i++ {
		if s[i] == id {
			return i, nil
		}
	}

	return -1, nil
}

// GetPendingSet analyses the specified sequence and computes the set of ids occuring between index (excluded) and the previous occurence of id
//
// The sequence is supposed to be correct (in regards to its mathematical definition), and id is supposed to be a valid id for the sequence
//
// If the index is not the one of the specified id in the sequence, the result still holds, but may be incomplete for your needs
// If the id is not valid for the specified sequence, the result will be the set of ids of the sequence
func GetPendingSet(s []uint32, id uint32, index int) ([]uint32, error) {
	res := []uint32{}

	if index >= len(s) || index < 0 {
		return res, errors.New("Index out of range")
	}

	curIndex := index - 1
	if curIndex < 0 {
		return res, nil
	}

	for curIndex > -1 && s[curIndex] != id {
		curID := s[curIndex]
		if !contains(res, curID) {
			res = append(res, curID)
		}
		curIndex--
	}

	return res, nil
}

// GetSendSet analyses the specified sequence and computes the set of ids occuring between index (excluded) and the next occurence of id
//
// The sequence is supposed to be correct (in regards to its mathematical definition), and id is supposed to be a valid id for the sequence
//
// If the index is not the one of the specified id in the sequence, the result still holds, but may be incomplete for your needs
// If the id is not valid for the specified sequence, the result will be the set of ids of the sequence
func GetSendSet(s []uint32, id uint32, index int) ([]uint32, error) {
	res := []uint32{}

	if index >= len(s) || index < 0 {
		return res, errors.New("Index out of range")
	}

	curIndex := index + 1
	if curIndex >= len(s) {
		return res, nil
	}

	for curIndex < len(s) && s[curIndex] != id {
		curID := s[curIndex]
		if !contains(res, curID) {
			res = append(res, curID)
		}
		curIndex++
	}

	return res, nil
}

// contains determines if s contains e
func contains(s []uint32, e uint32) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}

// GetAllButOne creates the slice of all sequence ids, except the one specified
func GetAllButOne(s []uint32, e uint32) []uint32 {
	var res = make([]uint32, 0)

	for i := 0; i < len(s); i++ {
		curID := s[i]
		if !contains(res, curID) && curID != e {
			res = append(res, curID)
		}
	}

	return res
}
<commit_msg>[c] Add function to remove from item set<commit_after>package common

import (
	"errors"
)

// FindNextIndex analyses the specified sequence and tries to find the next occurence of id after the specified index (excluded)
// Therefore to find the first occurence of the id in the sequence, use -1 as the index
//
// If there is no occurence of id, then -1 is returned
//
// The sequence is supposed to be correct (in regards to its mathematical definition), and id is supposed to be a valid id for the sequence
func FindNextIndex(s []uint32, id uint32, index int) (int, error) {
	if index >= len(s) || index < -1 {
		return -1, errors.New("Index out of range")
	}

	for i := index + 1; i < len(s); i++ {
		if s[i] == id {
			return i, nil
		}
	}

	return -1, nil
}

// GetPendingSet analyses the specified sequence and computes the set of ids occuring between index (excluded) and the previous occurence of id
//
// The sequence is supposed to be correct (in regards to its mathematical definition), and id is supposed to be a valid id for the sequence
//
// If the index is not the one of the specified id in the sequence, the result still holds, but may be incomplete for your needs
// If the id is not valid for the specified sequence, the result will be the set of ids of the sequence
func GetPendingSet(s []uint32, id uint32, index int) ([]uint32, error) {
	res := []uint32{}

	if index >= len(s) || index < 0 {
		return res, errors.New("Index out of range")
	}

	curIndex := index - 1
	if curIndex < 0 {
		return res, nil
	}

	for curIndex > -1 && s[curIndex] != id {
		curID := s[curIndex]
		if !contains(res, curID) {
			res = append(res, curID)
		}
		curIndex--
	}

	return res, nil
}

// GetSendSet analyses the specified sequence and computes the set of ids occuring between index (excluded) and the next occurence of id
//
// The sequence is supposed to be correct (in regards to its mathematical definition), and id is supposed to be a valid id for the sequence
//
// If the index is not the one of the specified id in the sequence, the result still holds, but may be incomplete for your needs
// If the id is not valid for the specified sequence, the result will be the set of ids of the sequence
func GetSendSet(s []uint32, id uint32, index int) ([]uint32, error) {
	res := []uint32{}

	if index >= len(s) || index < 0 {
		return res, errors.New("Index out of range")
	}

	curIndex := index + 1
	if curIndex >= len(s) {
		return res, nil
	}

	for curIndex < len(s) && s[curIndex] != id {
		curID := s[curIndex]
		if !contains(res, curID) {
			res = append(res, curID)
		}
		curIndex++
	}

	return res, nil
}

// contains determines if s contains e
func contains(s []uint32, e uint32) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}

// GetAllButOne creates the slice of all sequence ids, except the one specified
func GetAllButOne(s []uint32, e uint32) []uint32 {
	var res = make([]uint32, 0)

	for i := 0; i < len(s); i++ {
		curID := s[i]
		if !contains(res, curID) && curID != e {
			res = append(res, curID)
		}
	}

	return res
}

// Remove an ID from the sequence
func Remove(s []uint32, e uint32) ([]uint32, error) {
	for i, a := range s {
		if a == e {
			return append(s[:i], s[i+1:]...), nil
		}
	}
	return s, errors.New("ID not in sequence")
}
<|endoftext|>


<commit_before>package zfs

import (
	"bytes"
	"fmt"
	"io"
	"os/exec"
	"strconv"
	"strings"
)

type command struct {
	Command string
	Stdin   io.Reader
	Stdout  io.Writer
}

func (c *command) Run(arg ...string) ([][]string, error) {

	cmd := exec.Command(c.Command, arg...)

	var stdout, stderr bytes.Buffer

	if c.Stdout == nil {
		cmd.Stdout = &stdout
	} else {
		cmd.Stdout = c.Stdout
	}

	if c.Stdin != nil {
		cmd.Stdin = c.Stdin

	}
	cmd.Stderr = &stderr

	debug := strings.Join([]string{cmd.Path, strings.Join(cmd.Args, " ")}, " ")
	err := cmd.Run()

	if err != nil {
		return nil, &Error{
			Err:    err,
			Debug:  debug,
			Stderr: stderr.String(),
		}
	}

	// assume if you passed in something for stdout, that you know what to do with it
	if c.Stdout != nil {
		return nil, nil
	}

	lines := strings.Split(stdout.String(), "\n")

	//last line is always blank
	lines = lines[0 : len(lines)-1]
	output := make([][]string, len(lines))

	for i, l := range lines {
		output[i] = strings.Split(l, "\t")
	}

	return output, nil
}

func setString(field *string, value string) {
	v := ""
	if value != "-" {
		v = value
	}
	*field = v
}

func setUint(field *uint64, value string) error {
	var v uint64
	if value != "-" {
		var err error
		v, err = strconv.ParseUint(value, 10, 64)
		if err != nil {
			return err
		}
	}
	*field = v
	return nil
}

func (ds *Dataset) parseLine(line []string) error {
	prop := line[1]
	val := line[2]

	switch prop {
	case "available":
		if err := setUint(&ds.Avail, val); err != nil {
			return err
		}
	case "compression":
		setString(&ds.Compression, val)
	case "mountpoint":
		setString(&ds.Mountpoint, val)
	case "quota":
		setUint(&ds.Quota, val)
	case "type":
		setString(&ds.Type, val)
	case "used":
		if err := setUint(&ds.Used, val); err != nil {
			return err
		}
	case "volsize":
		if err := setUint(&ds.Volsize, val); err != nil {
			return err
		}
	case "written":
		if err := setUint(&ds.Written, val); err != nil {
			return err
		}
	}
	return nil
}

func listByType(t, filter string) ([]*Dataset, error) {
	args := []string{"get", "all", "-t", t, "-rHp"}
	if filter != "" {
		args = append(args, filter)
	}
	out, err := zfs(args...)
	if err != nil {
		return nil, err
	}

	datasets := make([]*Dataset, 0)
	name := ""
	var ds *Dataset
	for _, line := range out {
		if name != line[0] {
			name = line[0]
			ds = &Dataset{Name: name}
			datasets = append(datasets, ds)
		}
		if err := ds.parseLine(line); err != nil {
			return nil, err
		}
	}

	return datasets, nil
}

func propsSlice(properties map[string]string) []string {
	args := make([]string, 0, len(properties)*3)
	for k, v := range properties {
		args = append(args, "-o")
		args = append(args, fmt.Sprintf("%s=%s", k, v))
	}
	return args
}

func (z *Zpool) parseLine(line []string) error {
	prop := line[1]
	val := line[2]
	switch prop {
	case "health":
		setString(&z.Health, val)
	case "allocated":
		if err := setUint(&z.Allocated, val); err != nil {
			return err
		}
	case "size":
		if err := setUint(&z.Size, val); err != nil {
			return err
		}
	case "free":
		if err := setUint(&z.Free, val); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Fix string split in command.Run(), use strings.Fields() instead of strings.Split()<commit_after>package zfs

import (
	"bytes"
	"fmt"
	"io"
	"os/exec"
	"strconv"
	"strings"
)

type command struct {
	Command string
	Stdin   io.Reader
	Stdout  io.Writer
}

func (c *command) Run(arg ...string) ([][]string, error) {

	cmd := exec.Command(c.Command, arg...)

	var stdout, stderr bytes.Buffer

	if c.Stdout == nil {
		cmd.Stdout = &stdout
	} else {
		cmd.Stdout = c.Stdout
	}

	if c.Stdin != nil {
		cmd.Stdin = c.Stdin

	}
	cmd.Stderr = &stderr

	debug := strings.Join([]string{cmd.Path, strings.Join(cmd.Args, " ")}, " ")
	err := cmd.Run()

	if err != nil {
		return nil, &Error{
			Err:    err,
			Debug:  debug,
			Stderr: stderr.String(),
		}
	}

	// assume if you passed in something for stdout, that you know what to do with it
	if c.Stdout != nil {
		return nil, nil
	}

	lines := strings.Split(stdout.String(), "\n")

	//last line is always blank
	lines = lines[0 : len(lines)-1]
	output := make([][]string, len(lines))

	for i, l := range lines {
		output[i] = strings.Fields(l)
	}

	return output, nil
}

func setString(field *string, value string) {
	v := ""
	if value != "-" {
		v = value
	}
	*field = v
}

func setUint(field *uint64, value string) error {
	var v uint64
	if value != "-" {
		var err error
		v, err = strconv.ParseUint(value, 10, 64)
		if err != nil {
			return err
		}
	}
	*field = v
	return nil
}

func (ds *Dataset) parseLine(line []string) error {
	prop := line[1]
	val := line[2]

	switch prop {
	case "available":
		if err := setUint(&ds.Avail, val); err != nil {
			return err
		}
	case "compression":
		setString(&ds.Compression, val)
	case "mountpoint":
		setString(&ds.Mountpoint, val)
	case "quota":
		setUint(&ds.Quota, val)
	case "type":
		setString(&ds.Type, val)
	case "used":
		if err := setUint(&ds.Used, val); err != nil {
			return err
		}
	case "volsize":
		if err := setUint(&ds.Volsize, val); err != nil {
			return err
		}
	case "written":
		if err := setUint(&ds.Written, val); err != nil {
			return err
		}
	}
	return nil
}

func listByType(t, filter string) ([]*Dataset, error) {
	args := []string{"get", "all", "-t", t, "-rHp"}
	if filter != "" {
		args = append(args, filter)
	}
	out, err := zfs(args...)
	if err != nil {
		return nil, err
	}

	datasets := make([]*Dataset, 0)
	name := ""
	var ds *Dataset
	for _, line := range out {
		if name != line[0] {
			name = line[0]
			ds = &Dataset{Name: name}
			datasets = append(datasets, ds)
		}
		if err := ds.parseLine(line); err != nil {
			return nil, err
		}
	}

	return datasets, nil
}

func propsSlice(properties map[string]string) []string {
	args := make([]string, 0, len(properties)*3)
	for k, v := range properties {
		args = append(args, "-o")
		args = append(args, fmt.Sprintf("%s=%s", k, v))
	}
	return args
}

func (z *Zpool) parseLine(line []string) error {
	prop := line[1]
	val := line[2]
	switch prop {
	case "health":
		setString(&z.Health, val)
	case "allocated":
		if err := setUint(&z.Allocated, val); err != nil {
			return err
		}
	case "size":
		if err := setUint(&z.Size, val); err != nil {
			return err
		}
	case "free":
		if err := setUint(&z.Free, val); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package healthcheck

import (
	"context"
	"net/http"
	"net/url"
	"sync"
	"time"

	"github.com/containous/traefik/log"
	"github.com/containous/traefik/safe"
	"github.com/vulcand/oxy/roundrobin"
)

var singleton *HealthCheck
var once sync.Once

// GetHealthCheck Get HealtchCheck Singleton
func GetHealthCheck() *HealthCheck {
	once.Do(func() {
		singleton = newHealthCheck()
	})
	return singleton
}

// BackendHealthCheck HealthCheck configuration for a backend
type BackendHealthCheck struct {
	Path           string
	Interval       time.Duration
	DisabledURLs   []*url.URL
	requestTimeout time.Duration
	lb             loadBalancer
}

var launch = false

//HealthCheck struct
type HealthCheck struct {
	Backends map[string]*BackendHealthCheck
	cancel   context.CancelFunc
}

type loadBalancer interface {
	RemoveServer(u *url.URL) error
	UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error
	Servers() []*url.URL
}

func newHealthCheck() *HealthCheck {
	return &HealthCheck{
		Backends: make(map[string]*BackendHealthCheck),
	}
}

// NewBackendHealthCheck Instantiate a new BackendHealthCheck
func NewBackendHealthCheck(Path string, interval time.Duration, lb loadBalancer) *BackendHealthCheck {
	return &BackendHealthCheck{
		Path:           Path,
		Interval:       interval,
		requestTimeout: 5 * time.Second,
		lb:             lb,
	}
}

//SetBackendsConfiguration set backends configuration
func (hc *HealthCheck) SetBackendsConfiguration(parentCtx context.Context, backends map[string]*BackendHealthCheck) {
	hc.Backends = backends
	if hc.cancel != nil {
		hc.cancel()
	}
	ctx, cancel := context.WithCancel(parentCtx)
	hc.cancel = cancel

	for backendID, backend := range hc.Backends {
		currentBackendID := backendID
		currentBackend := backend
		safe.Go(func() {
			hc.execute(ctx, currentBackendID, currentBackend)
		})
	}
}

func (hc *HealthCheck) execute(ctx context.Context, backendID string, backend *BackendHealthCheck) {
	log.Debugf("Initial healthcheck for currentBackend %s ", backendID)
	checkBackend(backend)
	ticker := time.NewTicker(backend.Interval)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			log.Debugf("Stopping all current Healthcheck goroutines")
			return
		case <-ticker.C:
			log.Debugf("Refreshing healthcheck for currentBackend %s ", backendID)
			checkBackend(backend)
		}
	}
}

func checkBackend(currentBackend *BackendHealthCheck) {
	enabledURLs := currentBackend.lb.Servers()
	var newDisabledURLs []*url.URL
	for _, url := range currentBackend.DisabledURLs {
		if checkHealth(url, currentBackend) {
			log.Debugf("HealthCheck is up [%s]: Upsert in server list", url.String())
			currentBackend.lb.UpsertServer(url, roundrobin.Weight(1))
		} else {
			log.Warnf("HealthCheck is still failing [%s]", url.String())
			newDisabledURLs = append(newDisabledURLs, url)
		}
	}
	currentBackend.DisabledURLs = newDisabledURLs

	for _, url := range enabledURLs {
		if !checkHealth(url, currentBackend) {
			log.Warnf("HealthCheck has failed [%s]: Remove from server list", url.String())
			currentBackend.lb.RemoveServer(url)
			currentBackend.DisabledURLs = append(currentBackend.DisabledURLs, url)
		}
	}
}

func checkHealth(serverURL *url.URL, backend *BackendHealthCheck) bool {
	client := http.Client{
		Timeout: backend.requestTimeout,
	}
	resp, err := client.Get(serverURL.String() + backend.Path)
	if err == nil {
		defer resp.Body.Close()
	}
	return err == nil && resp.StatusCode == 200
}
<commit_msg>Correct typo and use Godoc convention in comment.<commit_after>package healthcheck

import (
	"context"
	"net/http"
	"net/url"
	"sync"
	"time"

	"github.com/containous/traefik/log"
	"github.com/containous/traefik/safe"
	"github.com/vulcand/oxy/roundrobin"
)

var singleton *HealthCheck
var once sync.Once

// GetHealthCheck returns the health check which is guaranteed to be a singleton.
func GetHealthCheck() *HealthCheck {
	once.Do(func() {
		singleton = newHealthCheck()
	})
	return singleton
}

// BackendHealthCheck HealthCheck configuration for a backend
type BackendHealthCheck struct {
	Path           string
	Interval       time.Duration
	DisabledURLs   []*url.URL
	requestTimeout time.Duration
	lb             loadBalancer
}

var launch = false

//HealthCheck struct
type HealthCheck struct {
	Backends map[string]*BackendHealthCheck
	cancel   context.CancelFunc
}

type loadBalancer interface {
	RemoveServer(u *url.URL) error
	UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error
	Servers() []*url.URL
}

func newHealthCheck() *HealthCheck {
	return &HealthCheck{
		Backends: make(map[string]*BackendHealthCheck),
	}
}

// NewBackendHealthCheck Instantiate a new BackendHealthCheck
func NewBackendHealthCheck(Path string, interval time.Duration, lb loadBalancer) *BackendHealthCheck {
	return &BackendHealthCheck{
		Path:           Path,
		Interval:       interval,
		requestTimeout: 5 * time.Second,
		lb:             lb,
	}
}

//SetBackendsConfiguration set backends configuration
func (hc *HealthCheck) SetBackendsConfiguration(parentCtx context.Context, backends map[string]*BackendHealthCheck) {
	hc.Backends = backends
	if hc.cancel != nil {
		hc.cancel()
	}
	ctx, cancel := context.WithCancel(parentCtx)
	hc.cancel = cancel

	for backendID, backend := range hc.Backends {
		currentBackendID := backendID
		currentBackend := backend
		safe.Go(func() {
			hc.execute(ctx, currentBackendID, currentBackend)
		})
	}
}

func (hc *HealthCheck) execute(ctx context.Context, backendID string, backend *BackendHealthCheck) {
	log.Debugf("Initial healthcheck for currentBackend %s ", backendID)
	checkBackend(backend)
	ticker := time.NewTicker(backend.Interval)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			log.Debugf("Stopping all current Healthcheck goroutines")
			return
		case <-ticker.C:
			log.Debugf("Refreshing healthcheck for currentBackend %s ", backendID)
			checkBackend(backend)
		}
	}
}

func checkBackend(currentBackend *BackendHealthCheck) {
	enabledURLs := currentBackend.lb.Servers()
	var newDisabledURLs []*url.URL
	for _, url := range currentBackend.DisabledURLs {
		if checkHealth(url, currentBackend) {
			log.Debugf("HealthCheck is up [%s]: Upsert in server list", url.String())
			currentBackend.lb.UpsertServer(url, roundrobin.Weight(1))
		} else {
			log.Warnf("HealthCheck is still failing [%s]", url.String())
			newDisabledURLs = append(newDisabledURLs, url)
		}
	}
	currentBackend.DisabledURLs = newDisabledURLs

	for _, url := range enabledURLs {
		if !checkHealth(url, currentBackend) {
			log.Warnf("HealthCheck has failed [%s]: Remove from server list", url.String())
			currentBackend.lb.RemoveServer(url)
			currentBackend.DisabledURLs = append(currentBackend.DisabledURLs, url)
		}
	}
}

func checkHealth(serverURL *url.URL, backend *BackendHealthCheck) bool {
	client := http.Client{
		Timeout: backend.requestTimeout,
	}
	resp, err := client.Get(serverURL.String() + backend.Path)
	if err == nil {
		defer resp.Body.Close()
	}
	return err == nil && resp.StatusCode == 200
}
<|endoftext|>


<commit_before>package pattern

import (
	"math"

	"github.com/catorpilor/leetcode/utils"
)

func findPattern(nums []int) bool {
	return useBruteForce(nums)
}

// useBruteForce time complexity O(N^3), space complexity O(1)
func useBruteForce(nums []int) bool {
	n := len(nums)
	if n < 3 {
		return false
	}
	for i := 0; i < n-2; i++ {
		for j := i + 1; j < n-1; j++ {
			for k := j + 1; k < n; k++ {
				if nums[i] < nums[k] && nums[j] > nums[k] {
					return true
				}
			}
		}
	}
	return false
}

// useBetterBF time complexity O(N^2), space complexity O(1)
func useBetterBF(nums []int) bool {
	n := len(nums)
	if n < 3 {
		return false
	}
	// we choose nums[i] as the min value we met so far from [0..j)
	minI := math.MaxInt32
	for j := 0; j < n-1; j++ {
		minI = utils.Min(minI, nums[j])
		for k := j + 1; k < n; k++ {
			if nums[j] > nums[k] && nums[k] > minI {
				return true
			}
		}
	}
	return false
}
<commit_msg>solve 456 use stack<commit_after>package pattern

import (
	"math"

	"github.com/catorpilor/leetcode/utils"
)

func findPattern(nums []int) bool {
	return useBruteForce(nums)
}

// useBruteForce time complexity O(N^3), space complexity O(1)
func useBruteForce(nums []int) bool {
	n := len(nums)
	if n < 3 {
		return false
	}
	for i := 0; i < n-2; i++ {
		for j := i + 1; j < n-1; j++ {
			for k := j + 1; k < n; k++ {
				if nums[i] < nums[k] && nums[j] > nums[k] {
					return true
				}
			}
		}
	}
	return false
}

// useBetterBF time complexity O(N^2), space complexity O(1)
func useBetterBF(nums []int) bool {
	n := len(nums)
	if n < 3 {
		return false
	}
	// we choose nums[i] as the min value we met so far from [0..j)
	minI := math.MaxInt32
	for j := 0; j < n-1; j++ {
		minI = utils.Min(minI, nums[j])
		for k := j + 1; k < n; k++ {
			if nums[j] > nums[k] && nums[k] > minI {
				return true
			}
		}
	}
	return false
}

// useStack time complexity O(N), space complexity O(N)
func useStack(nums []int) bool {
	n := len(nums)
	if n < 3 {
		return false
	}
	mins := make([]int, n)
	mins[0] = nums[0]
	for i := 1; i < n; i++ {
		mins[i] = utils.Min(mins[i-1], nums[i])
	}
	// st store the possbile value for nums[k]
	st := make([]int, 0, n)
	for j := n - 1; j >= 0; j-- {
		if nums[j] > mins[j] {
			// a possible choice for nums[j]
			nst := len(st)
			for nst > 0 && mins[j] >= st[nst-1] {
				nst--
				st = st[:nst]
			}
			if nst > 0 && st[nst-1] < nums[j] {
				return true
			}
			// a possible nums[k]
			st = append(st, nums[j])
		}
	}
	return false
}
<|endoftext|>