Example #1
0
int main(int argc, char** argv)
{
  try
  {
    TCLAP::CmdLine cmd("Query tool", ' ');
    TCLAP::SwitchArg showArg("", "show", "Show fields and exit", false);
    TCLAP::ValueArg<std::string> selectArg("s", "select", "Comma separated list of field names to select, if omitted, all fields are selected", false, "", "Field selection");
    TCLAP::ValueArg<std::string> filterArg("f", "filter", "Filter expression in the form FIELDNAME=\"value\", filters selction", false, "", "Filter expression");
    TCLAP::ValueArg<std::string> orderArg("o", "order", "Comma separated list of field names with which to order a selection", false, "", "Order by");
    TCLAP::ValueArg<std::string> datastoreFileArg("d", "db", "JSON database file name to load or create", false, "db.json", "Database file");
    cmd.add(showArg);
    cmd.add(selectArg);
    cmd.add(filterArg);
    cmd.add(orderArg);
    cmd.add(datastoreFileArg);
    cmd.parse(argc, argv);

    DataStore::DatabasePtrH database =
      DataStore::DataStorageJson::Load(datastoreFileArg.getValue().c_str());

    DataStore::IFieldDescriptorConstListConstPtrH allFields =
      database->getScheme()->getFieldDescriptors();

    //
    // Show fields and exit?
    //
    if (showArg.isSet())
    {
      printFields(*(allFields.get()));
      return 0;
    }

    //
    // Parse selection (-s) into a list of field descriptors
    //

    DataStore::IFieldDescriptorConstListPtrH selectedFields;
    if (selectArg.isSet())
    {
      selectedFields = parseFieldNameList(selectArg.getValue(),
        *(allFields.get()));
    }

    //
    // Parse filter (-f) expression into a logical expression AST
    //

    DataStore::Predicate filter = DataStore::Predicate::AlwaysTrue();
    if (filterArg.isSet())
    {
      DataStore::IQualifierPtrH filterAst =
        parseFilterExpression(filterArg.getValue(), *(allFields.get()));
      filter = DataStore::Predicate(filterAst);
    }

    //
    // Parse order (-o) in to list of field descriptors, order is
    // always ascending.
    //

    DataStore::IFieldDescriptorConstListPtrH orderByFields;
    if (orderArg.isSet())
    {
      orderByFields = parseFieldNameList(orderArg.getValue(),
        *(allFields.get()));
    }

    //
    // Perform query, and print result
    //

    DataStore::IQueryResultConstPtrH result =
      database->query(selectedFields, &filter, orderByFields);
    printResult(*(result.get()));
  }
  catch (TCLAP::ArgException &e)
  {
    std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
    return 1;
  }
  catch (std::exception& ex)
  {
    std::cerr << "error: " << ex.what() << std::endl;
    return 1;
  }

	return 0;
}
void StyleParser::parseLayer(const std::string& id, const JSVal& value, util::ptr<StyleLayer>& layer) {
    if (layer) {
        // Skip parsing this again. We already have a valid layer definition.
        return;
    }

    // Make sure we have not previously attempted to parse this layer.
    if (std::find(stack.begin(), stack.end(), id) != stack.end()) {
        Log::Warning(Event::ParseStyle, "layer reference of '%s' is circular", id.c_str());
        return;
    }

    if (value.HasMember("ref")) {
        // This layer is referencing another layer. Recursively parse that layer.
        const JSVal& refVal = value["ref"];
        if (!refVal.IsString()) {
            Log::Warning(Event::ParseStyle, "layer ref of '%s' must be a string", id.c_str());
            return;
        }

        const std::string ref { refVal.GetString(), refVal.GetStringLength() };
        auto it = layersMap.find(ref);
        if (it == layersMap.end()) {
            Log::Warning(Event::ParseStyle, "layer '%s' references unknown layer %s", id.c_str(), ref.c_str());
            return;
        }

        // Recursively parse the referenced layer.
        stack.push_front(id);
        parseLayer(it->first,
                   it->second.first,
                   it->second.second);
        stack.pop_front();

        util::ptr<StyleLayer> reference = it->second.second;
        if (!reference) {
            return;
        }

        layer = reference->clone();
        layer->id = id;
        layer->ref = ref;

    } else {
        // Otherwise, parse the source/source-layer/filter/render keys to form the bucket.
        if (!value.HasMember("type")) {
            Log::Warning(Event::ParseStyle, "layer '%s' is missing a type", id.c_str());
            return;
        }

        const JSVal& typeVal = value["type"];
        if (!typeVal.IsString()) {
            Log::Warning(Event::ParseStyle, "layer '%s' has an invalid type", id.c_str());
            return;
        }

        std::string type { typeVal.GetString(), typeVal.GetStringLength() };
        StyleLayerType typeClass = StyleLayerTypeClass(type);
        layer = StyleLayer::create(typeClass);

        if (!layer) {
            Log::Warning(Event::ParseStyle, "unknown type '%s' for layer '%s'", type.c_str(), id.c_str());
            return;
        }

        layer->id = id;
        layer->type = typeClass;

        if (value.HasMember("source")) {
            const JSVal& value_source = value["source"];
            if (value_source.IsString()) {
                layer->source = { value_source.GetString(), value_source.GetStringLength() };
                auto source_it = sourcesMap.find(layer->source);
                if (source_it == sourcesMap.end()) {
                    Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", layer->source.c_str(), layer->id.c_str());
                }
            } else {
                Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", layer->id.c_str());
            }
        }

        if (value.HasMember("source-layer")) {
            const JSVal& value_source_layer = value["source-layer"];
            if (value_source_layer.IsString()) {
                layer->sourceLayer = { value_source_layer.GetString(), value_source_layer.GetStringLength() };
            } else {
                Log::Warning(Event::ParseStyle, "source-layer of layer '%s' must be a string", layer->id.c_str());
            }
        }

        if (value.HasMember("filter")) {
            layer->filter = parseFilterExpression(value["filter"]);
        }

        if (value.HasMember("minzoom")) {
            const JSVal& min_zoom = value["minzoom"];
            if (min_zoom.IsNumber()) {
                layer->minZoom = min_zoom.GetDouble();
            } else {
                Log::Warning(Event::ParseStyle, "minzoom of layer %s must be numeric", layer->id.c_str());
            }
        }

        if (value.HasMember("maxzoom")) {
            const JSVal& max_zoom = value["maxzoom"];
            if (max_zoom.IsNumber()) {
                layer->maxZoom = max_zoom.GetDouble();
            } else {
                Log::Warning(Event::ParseStyle, "maxzoom of layer %s must be numeric", layer->id.c_str());
            }
        }

        if (value.HasMember("layout")) {
            parseVisibility(*layer, value["layout"]);
            layer->parseLayout(value["layout"]);
        }
    }

    layer->parsePaints(value);
}