How can I encode a rule tree of multiple depths in Dhall? - directed-acyclic-graphs

I'm trying to move some error prone YAML into Dhall to make some system configuration simpler. I have a tree that looks like:
composite:
condition: And
rules:
- composite:
condition: And
rules:
- leaf:
static: true
- leaf:
exists: some-property-to-lookup
- composite:
condition: Or
rules:
- composite:
condition: And
rules:
- leaf:
static: true
- leaf:
exists: some-property-to-lookup
I'm trying to encode this in Dhall and I can't seem to provide the compiler the right information. My latest try looks like:
let Field
: Type
= < B : { static : Bool } | S : { exists : Text } >
let Condition
: Type
= < And | Or | Not >
let Node
: Type
= ∀(Node : Type) →
∀(Leaf : { leaf : Field }) →
∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
Node
let example
: Node
= ∀(Node : Type) →
∀(Leaf : { leaf : Field }) →
∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
Branch
{ composite =
{ condition = Condition.And
, rules =
[ Branch
{ composite =
{ condition = Condition.And
, rules = [ Leaf { leaf = Field.S { exists = "hi" } } ]
}
}
, Branch
{ composite =
{ condition = Condition.Or
, rules = [ Leaf { leaf = Field.S { static = true } } ]
}
}
, Branch
{ composite =
{ condition = Condition.And
, rules =
[ Branch
{ composite =
{ condition = Condition.And
, rules =
[ Leaf { leaf = Field.S { exists = "hi" } } ]
}
}
, Branch
{ composite =
{ condition = Condition.Or
, rules =
[ Leaf { leaf = Field.S { static = true } } ]
}
}
]
}
}
]
}
}
in example
But I get Error: Not a function. Any pointers would be appreciated.
I also tried w/ the Graph module, but I can't seem to convert that to YAML directly.

This works:
let Field
: Type
= < B : { static : Bool } | S : { exists : Text } >
let Condition
: Type
= < And | Or | Not >
let Node
: Type
= ∀(Node : Type) →
∀(Leaf : { leaf : Field } → Node) →
∀(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
Node
let example
: Node
= λ(Node : Type) →
λ(Leaf : { leaf : Field } → Node) →
λ(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
Branch
{ composite =
{ condition = Condition.And
, rules =
[ Branch
{ composite =
{ condition = Condition.And
, rules = [ Leaf { leaf = Field.S { exists = "hi" } } ]
}
}
, Branch
{ composite =
{ condition = Condition.Or
, rules = [ Leaf { leaf = Field.B { static = True } } ]
}
}
, Branch
{ composite =
{ condition = Condition.And
, rules =
[ Branch
{ composite =
{ condition = Condition.And
, rules =
[ Leaf { leaf = Field.S { exists = "hi" } } ]
}
}
, Branch
{ composite =
{ condition = Condition.Or
, rules =
[ Leaf { leaf = Field.B { static = True } } ]
}
}
]
}
}
]
}
}
in example
Here is the diff between the two:
12,13c12,13
< ∀(Leaf : { leaf : Field }) →
< ∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
---
> ∀(Leaf : { leaf : Field } → Node) →
> ∀(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
18,20c18,20
< = ∀(Node : Type) →
< ∀(Leaf : { leaf : Field }) →
< ∀(Branch : { composite : { condition : Condition, rules : List Node } }) →
---
> = λ(Node : Type) →
> λ(Leaf : { leaf : Field } → Node) →
> λ(Branch : { composite : { condition : Condition, rules : List Node } } → Node) →
34c34
< , rules = [ Leaf { leaf = Field.S { static = true } } ]
---
> , rules = [ Leaf { leaf = Field.B { static = True } } ]
52c52
< [ Leaf { leaf = Field.S { static = true } } ]
---
> [ Leaf { leaf = Field.B { static = True } } ]

Related

Terraform: De-duping a map object

I'm creating a map object by looping through a list of elements. How do I enforce unique keys in the map such that there are no duplicates?
For example, I have something like below but I get the error: │ Local value local.uri_bucket_map cannot use its own result as part of its expression.
locals {
inference = [
{ "data_uri" : "s3://my_bucket/model.tar.gz",
"model_uri": "account_num.dkr.ecr.us-west-2.amazonaws.com/my_container:latest"
},
{ "data_uri" : "s3://my_bucket/model.tar.gz",
"model_uri": "account_num.dkr.ecr.us-west-2.amazonaws.com/my_container2:latest"
},
{ "data_uri" : "s3://my_bucket_3/model.tar.gz" ,
"model_uri": "account_num.dkr.ecr.us-west-2.amazonaws.com/my_container3:latest"
}
]
uri_bucket_map = {
for x in local.inference : x.data_uri =>
split("/", split("//", x.data_uri)[1])[0]
}
}
Expected Map:
{
"s3://my_bucket/model.tar.gz" -> "my_bucket"
"s3://my_bucket_3/model.tar.gz" -> "my_bucket_3"
}
Without much changes to you original code, you can obtain what you want as follows:
uri_bucket_map = {
for x in distinct(local.inference[*].data_uri) : x =>
split("/", split("//", x)[1])[0]
}

Terraform aws_cloudfront_cache_policy pass multiple cookies to cookies_config

I can't seem to pass multiple cookies in the "items" list when in "cookies_config -> cookies"
Here is my variable:
variable "cache_policy_defaults" {
type = object({
name = string
comment = string
default_ttl = number
max_ttl = number
min_ttl = number
cookie_behavior = string
cookies_to_forward = optional(list(string))
header_behavior = string
headers_to_forward = optional(list(string))
query_string_behavior = string
query_strings_to_forward = optional(list(string))
}
)
default = {
name = ""
comment = ""
default_ttl = 60
max_ttl = 60
min_ttl = 60
cookie_behavior = "none"
cookies_to_forward = []
header_behavior = "none"
headers_to_forward = []
query_string_behavior = "none"
query_strings_to_forward = []
}
}
Here are my locals:
locals {
origin_id = "origin_${local.origin_config.domain_name}"
origin_config = merge(var.origin_defaults, var.origin_settings)
restrictions = merge(var.restrictions_defaults, var.restrictions_settings)
default_cache_behavior = merge(var.default_cache_behavior_defaults, var.default_cache_behavior_settings)
cache_policy = merge(var.cache_policy_defaults, var.cache_policy_settings)
cache_policy_name = "cache_policy_${var.name}"
}
Here is my tfvars:
"cache_policy_settings": {
"min_ttl": 30,
"max_ttl": 30,
"default_ttl": 30,
"cookie_behavior": "whitelist",
"cookies_to_forward": ["123", "456"]
}
Here is my main.tf:
resource "aws_cloudfront_cache_policy" "this" {
name = lookup(local.cache_policy, local.cache_policy.name, local.cache_policy_name)
comment = local.cache_policy.comment
default_ttl = local.cache_policy.default_ttl
max_ttl = local.cache_policy.max_ttl
min_ttl = local.cache_policy.min_ttl
parameters_in_cache_key_and_forwarded_to_origin {
cookies_config {
cookie_behavior = local.cache_policy.cookie_behavior
dynamic "cookies" {
for_each = local.cache_policy.cookies_to_forward != null ? local.cache_policy.cookies_to_forward : null
content {
items = local.cache_policy.cookies_to_forward
}
}
}
headers_config {
header_behavior = local.cache_policy.header_behavior
dynamic "headers" {
for_each = local.cache_policy.headers_to_forward != null ? local.cache_policy.headers_to_forward : null
content {
items = local.cache_policy.headers_to_forward
}
}
}
query_strings_config {
query_string_behavior = local.cache_policy.query_string_behavior
dynamic "query_strings" {
for_each = local.cache_policy.query_strings_to_forward != null ? local.cache_policy.query_strings_to_forward : null
content {
items = local.cache_policy.query_strings_to_forward
}
}
}
}
}
The docs state
items: (Required) A list of item names (cookies, headers, or query strings).
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_cache_policy#items
However, the list does not accept multiple items.
Error: Too many list items
on main.tf line 57, in resource "aws_cloudfront_cache_policy" "this":
57: cookies_config {
Attribute supports 1 item maximum, but config has 2 declared.
It seems that I should just be able to pass a list of items? If I change the my input list to only contain a single value, then it works.
Here is the trick:
for_each = local.cache_policy.cookies_to_forward != null ? [1] : null
This tells Terraform to create exactly one block by making the true value of the ternary [1].
Thanks Jason for putting me on the right track.

How can i replace little part of profilepic url path in all documents by running single query in mongodb

{
"_id" : ObjectId("5bd6ed6a49ba281f5c54f185"),
"AvatarSet" : {
"Avatar" : [
{
"IsPrimaryAvatar" : true,
"ProfilePictureUrl" : "https://blob.blob.core.windows.net/avatarcontainer/avatardba36759-3e8e-4666-bc2b-e53ffb527716.jpeg?version=8b1b58b3-94f8-4608-b4db-05746eea8bfe"
}
]
}
Here I need to Replace only https://blob.blob.core.windows.net to every candidateID present in the database please help me how to write MongoDB Query for this?
I'm using Query but it's not working
db.getCollection("candidate-staging")
.find({},{"AvatarSet":[0]})..forEach(function(e) {
e.ProfilePictureUrl= e.ProfilePictureUrl.replace("https://blob.blob.core.windows.net", "https://blob123.blob.core.windows.net");
db.candidate-staging.save(e);
});
The problem in your script is that the ProfilePictureUrl is not properly referred, using dot notation like in the example below should solve the problem.
In your code e.ProfilePictureUrl points to a missing field in the top level document, while doc.AvatarSet.Avatar[0].ProfilePictureUrl in the following example points to the ProfilePictureUrl field for the first element in the Avatar array under the AvatarSet field from the main document.
db.test.find({}).forEach(function(doc) {
doc.AvatarSet.Avatar[0].ProfilePictureUrl= doc.AvatarSet.Avatar[0].ProfilePictureUrl.replace("https://blob.blob.core.windows.net", "https://blob123.blob.core.windows.net");
db.test.save(doc);
});
Local test:
mongos> db.test.find()
{ "_id" : ObjectId("5bdb5e3c553c271478a9a006"), "AvatarSet" : { "Avatar" : [ { "IsPrimaryAvatar" : true, "ProfilePictureUrl" : "https://blob.blob.core.windows.net/avatarcontainer/avatardba36759-3e8e-4666-bc2b-e53ffb527716.jpeg?version=8b1b58b3-94f8-4608-b4db-05746eea8bfe" } ] } }
{ "_id" : ObjectId("5bdb5e3e553c271478a9a007"), "AvatarSet" : { "Avatar" : [ { "IsPrimaryAvatar" : true, "ProfilePictureUrl" : "https://blob.blob.core.windows.net/avatarcontainer/avatardba36759-3e8e-4666-bc2b-e53ffb527716.jpeg?version=8b1b58b3-94f8-4608-b4db-05746eea8bfe" } ] } }
mongos> db.test.find({}).forEach(function(doc) {
doc.AvatarSet.Avatar[0].ProfilePictureUrl= doc.AvatarSet.Avatar[0].ProfilePictureUrl.replace("https://blob.blob.core.windows.net", "https://blob123.blob.core.windows.net");
db.test.save(doc); });
mongos> db.test.find()
{ "_id" : ObjectId("5bdb5e3c553c271478a9a006"), "AvatarSet" : { "Avatar" : [ { "IsPrimaryAvatar" : true, "ProfilePictureUrl" : "https://blob123.blob.core.windows.net/avatarcontainer/avatardba36759-3e8e-4666-bc2b-e53ffb527716.jpeg?version=8b1b58b3-94f8-4608-b4db-05746eea8bfe" } ] } }
{ "_id" : ObjectId("5bdb5e3e553c271478a9a007"), "AvatarSet" : { "Avatar" : [ { "IsPrimaryAvatar" : true, "ProfilePictureUrl" : "https://blob123.blob.core.windows.net/avatarcontainer/avatardba36759-3e8e-4666-bc2b-e53ffb527716.jpeg?version=8b1b58b3-94f8-4608-b4db-05746eea8bfe" } ] } }
In this code contains objects of an array of the object In this code reach AvatarSetArray points to a missing field in the top-level document because we need to access objects within the Another Array so we need to write another loop for 'Avatar' Array like e.AvatarSet.Avatar.forEach its really works. it's work for me.
db.getCollection("test").find({}).forEach(function(e,i) {
e.AvatarSet.Avatar.forEach(function(url, j) {
url.ProfilePictureUrl = url.ProfilePictureUrl.replace("https://blob.blob.core.windows.net", "https://blob123.blob.core.windows.net");
e.AvatarSet.Avatar[j] = url;
});
db.getCollection("test").save(e);
eval(printjson(e));
})
thanks!! manfonton and stackoverflow

how we find and replace array dictionary value in swift 3

My array has this dictionary I want to find and replace where dictionary h
attendance = "" and attendance = "A" and replace with attendance = "P"
I am using this:
checkedArray = [[String : AnyObject]]()
let index = find(checkedArray) { $0["attendance"] == "P" }
if let index = index {
checkedArray[index] = newDictionary
}
// Do any additional setup after loading the view.
}
func find<C: CollectionType>(collection: C, predicate: (C.Generator.Element) -> Bool) -> C.Index? {
for index in collection.startIndex ..< collection.endIndex {
if predicate(collection[index]) {
return index
}
}
return nil
}
[
{"studentID":"12","name":"panky","roll":"","attendance":"P"},
{"studentID":"14","name":"a","roll":"","attendance":""},
{"studentID":"4","name":"akshay","roll":"1","attendance":"E"},
{"studentID":"6","name":"anki","roll":"11","attendance":"P"},
{"studentID":"1","name":"mohit","roll":"2","attendance":"M"},
{"studentID":"5","name":"yogi","roll":"22","attendance":"L"},
{"studentID":"3","name":"Neha","roll":"3","attendance":"A"}
]
let dic: [[String : Any]] = [
["studentID":"12","name":"panky","roll":"","attendance":"P"],
["studentID":"14","name":"a","roll":"","attendance":""],
["studentID":"4","name":"akshay","roll":"1","attendance":"E"],
["studentID":"6","name":"anki","roll":"11","attendance":"P"],
["studentID":"1","name":"mohit","roll":"2","attendance":"M"],
["studentID":"5","name":"yogi","roll":"22","attendance":"L"],
["studentID":"3","name":"Neha","roll":"3","attendance":"A"]
]
let result : [Any] = dic.map { dictionary in
var dict = dictionary
if let attendance = dict["attendance"] as? String, attendance == "" || attendance == "A" {
dict["attendance"] = "P"
}
return dict
}

How to find and replace unique field name on mongodb

I have 1.6 million documents in mongodb like this:
{
"_id" : ObjectId("57580c3f7e1a1469e772345b"),
"https://www.....com/vr/s1812227" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812227/....",
"partner" : null,
.........
}
.........
}
}
{
"_id" : ObjectId("57580c3f7e1a1469e772346d"),
"https://www.....com/vr/s1812358" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812358/....",
"partner" : null,
.........
}
.........
}
}
{
"_id" : ObjectId("57580c3f7e1a1469e772346d"),
"https://www.....com/vr/s1812358/unite/125" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812358/....",
"partner" : null,
.........
}
.........
}
}
I want like this:
{
"_id" : ObjectId("57580c3f7e1a1469e772345b"),
"products" : {
"suitability" : "children welcome",
"details" : {
"lookingCount" : 0,
"photoUrl" : "https://www.....com/vr/s1812227/....",
"partner" : null,
.........
}
.........
}
}
Edit content.... Thanks for your answer and interest in advance.
UPDATE
I'm trying this code but maximum 1200 documents insert to new collection. I have 1.5 million documents.
db.sourceColl.find().forEach(function(doc) {
for (var k in doc) {
if (k.match(/^https.*/) ) {
db.sourceColl.find({ "_id": doc._id });
db.getSiblingDB('targetdb')['targetColl'].insert({products: doc[k]});
}
}
});
After I'm try this and insert 20 documents to new collection. I'm so confused. how to rename and copy new collection all documents. UPDATE2: I use robomongo and I think there are limits in robomongo. This code works without problem in mongo shell. search, replace and copy new document.
var bulk = db.sourceColl.initializeOrderedBulkOp();
var counter = 0;
db.sourceColl.find().forEach(function(doc) {
for (var k in doc) {
if (k.match(/^https.*/) ) {
print(k)
bulk.find({ "_id": doc._id });
db.getSiblingDB('targetDB')['targetColl'].insert({products: doc[k]});
counter++;
}
}
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.sourceColl.initializeOrderedBulkOp();
}
});
if ( counter % 1000 != 0 )
bulk.execute();
I think there are limits in robomongo. This code works fine in mongo shell. search, replace and copy new collection.
var bulk = db.sourceColl.initializeOrderedBulkOp();
var counter = 0;
db.sourceColl.find().forEach(function(doc) {
for (var k in doc) {
if (k.match(/^https.*/) ) {
print(k)
bulk.find({ "_id": doc._id });
db.getSiblingDB('targetDB')['targetColl'].insert({products: doc[k]});
counter++;
}
}
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.sourceColl.initializeOrderedBulkOp();
}
});
if ( counter % 1000 != 0 )
bulk.execute();
I have modified this answer https://stackoverflow.com/a/25204168/6446251