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); }