This validation block works for a single input variable.
variable "mytestname" {
validation {
condition = length(regexall("test$", var.mytestname)) > 0
error_message = "Should end in test"
}
}
I need it to work inside a for_each - or have some workaround to accomplish this. The issue is that there is a restriction on the condition statement - the condition HAS to take in the input variable itself (i.e. - it cannot accept an each.value)
variable "mytestnames" {
listnames = split(",",var.mytestnames)
for_each = var.listnames
validation {
condition = length(regexall("test$", each.value)) > 0
error_message = "Should end in test"
}
}
The above snippet does not work. I need a way I can iterate over a list of values and validate each of them. It looks like the newly introduced 'validation block' does not work on lists of input variables. There must be a way to do this without a validation block...??
I believe it will not work. The attributes that can be defined in the variable block are type, description, and default. So how could we define additional attribute such as "listnames" dynamically...
variable "mytestnames" {
listnames = split(",",var.mytestnames)
}
$ terraform validate
Error: Unsupported argument
on hoge.tf line 3, in variable "mytestnames":
3: listnames = split(",",var.mytestnames)
An argument named "listnames" is not expected here.
we can validate a loop
variable "mytestnames" {
type = string
description = "comma separated list of names"
# default = "nametest,name1test,name2test"
default = "nametest,nametest1,nametest2"
validation {
condition = alltrue([
for n in split(",", var.mytestnames) :
can(regex("test$", n)) # can't use a local var 'can only refer to the variable itself'
])
error_message = "Should end in test" # can't use local var here either
}
}
│ Error: Invalid value for variable
│
│ on main.tf line 5:
│ 5: variable "mytestnames" {
│ ├────────────────
│ │ var.mytestnames is "nametest,nametest1,nametest2"
│
│ Should end in test
│
... but, we can do better by using an output
locals { name_regex = "test$" }
output "mytestnames_valid" {
value = "ok" # we can output whatever we want
precondition {
condition = alltrue([
for n in split(",", var.mytestnames) :
can(regex(local.name_regex, n)) # in an output we can use a local var
])
error_message = format("invalid names: %s",
join(",", [
for n in split(",", var.mytestnames) :
n if !can(regex(local.name_regex, n)) # we can reference local AND make a list of bad names
]
)
)
}
}
│ Error: Module output value precondition failed
│
│ on main.tf line 23, in output "mytestnames":
│ 23: condition = alltrue([
│ 24: for n in split(",", var.mytestnames) :
│ 25: can(regex(local.name_regex, n)) # an an output we can use a local var
│ 26: ])
│ ├────────────────
│ │ local.name_regex is "test$"
│ │ var.mytestnames is "nametest,nametest1,nametest2"
│
│ invalid names: nametest1,nametest2
Related
This is what I have so far:
m_dest_set_sel = maya.api.OpenMaya.MSelectionList()
m_dest_set_sel.add('lambert4SG')
m_dest_set_obj = m_dest_set_sel.getDependNode(0)
m_dest_set = maya.api.OpenMaya.MFnSet(m_dest_set_obj)
ss = maya.api.OpenMaya.MSelectionList()
ss.add('pCube3.f[2]')
m_dest_set.addMembers(ss)
And it gives me this error:
# Error: Cannot add the following items to the set since they would break the exclusivity constraint: pCube3.f[2] #
# Error: RuntimeError: file <maya console> line 1: (kFailure): Unexpected Internal Failure #
i tried removing it from the "initialShadingGroup" to no avail:
m_dest_set_sel = maya.api.OpenMaya.MSelectionList()
m_dest_set_sel.add('initialShadingGroup')
m_dest_set_obj = m_dest_set_sel.getDependNode(0)
m_dest_set = maya.api.OpenMaya.MFnSet(m_dest_set_obj)
ss = maya.api.OpenMaya.MSelectionList()
ss.add('pCube3.f[2]')
m_dest_set.removeMembers(ss)
# Error: RuntimeError: file <maya console> line 8: (kInvalidParameter): Cannot find item of required type #
This works for me:
import maya.api.OpenMaya as om2
m_dest_set_sel = om2.MSelectionList()
m_dest_set_sel.add('initialShadingGroup')
m_dest_set_obj = m_dest_set_sel.getDependNode(0)
m_dest_set = om2.MFnSet(m_dest_set_obj)
ss = om2.MSelectionList()
ss.add('pCubeShape1')
m_dest_set.removeMembers(ss)
m_dest_set_sel = om2.MSelectionList()
m_dest_set_sel.add('lambert2SG')
m_dest_set_obj = m_dest_set_sel.getDependNode(0)
m_dest_set = om2.MFnSet(m_dest_set_obj)
ss = om2.MSelectionList()
ss.add('pCube1.f[2]')
m_dest_set.addMembers(ss)
I imported the database of ontime airlines from here https://clickhouse.com/docs/en/getting-started/example-datasets/ontime/
Then I created a dictionary mapping the 2 digit airplane codes to company names like this:
id,code,company
1,UA,United Airlines
2,HA,Hawaiian Airlines
3,OO,SkyWest
4,B6,Jetblue Airway
5,QX,Horizon Air
6,YX,Republic Airway
7,G4,Allegiant Air
...
..
I used this query to generate it and it seems to be working:
CREATE DICTIONARY airlinecompany
(
id UInt64,
code String,
company String
)
PRIMARY KEY id
SOURCE(FILE(path '/var/lib/clickhouse/user_files/airlinenames.csv' format 'CSVWithNames'))
LAYOUT(FLAT())
LIFETIME(3600)
In the main database (ontime) Looks like this:
SELECT Reporting_Airline AS R_air
FROM ontime
GROUP BY R_air
LIMIT 4
┌─R_air─┐
│ UA │
│ HA │
│ OO │
│ B6 │
└───────┘
What I want to do is have a table that uses R_air's 2 code value and then checks it against the airlinecompany dict to create a mapping ie
R_Air Company
UA | United Airlines
HA | Hawaiian Airlines
00 | SkyWest
...
..
But I cant seem to form this query correctly:
SELECT
Reporting_Airline AS R_Air,
dictGetString('airlinecompany', 'company', R_Air) AS company
FROM ontime
GROUP BY R_Air
Received exception from server (version 22.3.3):
Code: 6. DB::Exception: Received from localhost:9000. DB::Exception: Cannot parse string 'UA' as UInt64: syntax error at begin of string. Note: there are toUInt64OrZero and toUInt64OrNull functions, which returns zero/NULL instead of throwing exception.: while executing 'FUNCTION dictGetString('airlinecompany' :: 1, 'company' :: 2, Reporting_Airline :: 0) -> dictGetString('airlinecompany', 'company', Reporting_Airline) String : 4'. (CANNOT_PARSE_TEXT)
What am I missing? I dont know why it thinks UA is a UInt64
LAYOUT = COMPLEX_KEY_HASHED
CREATE DICTIONARY airlinecompany
(
id UInt64,
code String,
company String
)
PRIMARY KEY code
SOURCE(FILE(path '/var/lib/clickhouse/user_files/airlinenames.csv' format 'CSVWithNames'))
LAYOUT(COMPLEX_KEY_HASHED())
LIFETIME(3600)
SELECT dictGet('airlinecompany', 'company', tuple('UA'))
┌─dictGet('airlinecompany', 'company', tuple('UA'))─┐
│ United Airlines │
└───────────────────────────────────────────────────┘
SELECT Reporting_Airline AS R_air,
dictGetString('airlinecompany', 'company', tuple(R_Air)) AS company
FROM ontime
LIMIT 4;
┌─R_Air─┬─company───────────┐
│ B6 │ Jetblue Airway │
│ G4 │ Allegiant Air │
│ HA │ Hawaiian Airlines │
│ OO │ SkyWest │
└───────┴───────────────────┘
LOAD CSV WITH HEADERS FROM
'file:///epl_mataches.csv' as row
MATCH (c1:Club {name:row.`Team1`}), (c2:Club {name:row.`Team2`})
MERGE (c1) -[f:FEATURED{
round:toInteger(row.Round),
date:row.Date,
homeTeamFTScore: toInteger(split(row.FT,"-" [0])),
awayTeamFTScore: toInteger(split(row.FT,"-" [1])),
homeTeamHTScore: toInteger(split(row.HT,"-" [0])),
awayTeamHTScore: toInteger(split(row.HT,"-" [1]))
}] -> (c2)
The error is present when I try to create the relationships and to pull through the required information from the data file.
Neo.ClientError.Statement.SyntaxError
Type mismatch: expected List<T> but was String (line 7, column 45 (offset: 248))
" homeTeamFTScore: toInteger(split(row.FT,"-" [0])),"
There is a typo on your script, so instead of
homeTeamFTScore: toInteger(split(row.FT,"-" [0])),
Use below
homeTeamFTScore: toInteger(split(row.FT,"-") [0])
Notice the parenthesis before [0] and NOT after it.
For example:
RETURN toInteger(split("2-test","-") [0]) as sample
result:
╒════════╕
│"sample"│
╞════════╡
│ 2 │
└────────┘
I am sendind files from js to my golang server:
for (var value of formData.values()) {
console.log(value);
}
// File {name: 'img/<hash_key>.png', lastModified: 1635043863231, lastModifiedDate: Sat Oct 23 2021 23:51:03 GMT-0300 (Brasilia Standard Time), webkitRelativePath: '', size: 969, …}
// ...
var request = new Request( serverEndpoint, { body: formData, method: "POST", ... })
return fetch(request).then(response => { ... })
In my golang server, I am using the following code to deal with multipart form data from a request to read files
if err := r.ParseMultipartForm(32 << 20); err != nil {
...
}
for _, fileHeader := range r.MultipartForm.File["files"] {
...
}
I expected to read the files in Go with the same filenames, like img/<hash_key>.png
but my server is reading multipart-form to the following struct:
f = {*mime/multipart.Form | 0xc000426090}
├── Value = {map[string][]string}
└── File = {map[string][]*mime/multipart.FileHeader}
├── 0 = files -> len:1, cap:1
│ ├── key = {string} "files"
│ └── value = {[]*mime/multipart.FileHeader} len:1, cap:1
│ └── 0 = {*mime/multipart.FileHeader | 0xc000440000}
│ ├── Filename = {string} "<hash_key>.png" // notice how FileName is missing 'img/' prefix
│ └── ...
└── ...
I am trying to figure out how this is happening and how to prevent this strip prefix as I need this prefix to correctly resolve upload path for my files
Edit:
Closer inspection revealed that my server IS in fact getting the files with the correct name. After calling r.ParseMultipartForm(32 << 20), I get the following in r.Body.src.R.buf:
------WebKitFormBoundary1uanPdXqZeL8IPUH
Content-Disposition: form-data; name="files"; filename="img/upload.svg"
---- notice the img/ prefix
Content-Type: image/svg+xml
<svg height="512pt" viewBox= ...
However, in r.MultipartForm.File["files"][0].FileName, it shows as upload.svg
The directory is removed in in Part.FileName():
// RFC 7578, Section 4.2 requires that if a filename is provided, the
// directory path information must not be used.
return filepath.Base(filename)
Workaround Part.FileName() by parsing the content disposition header directly.
for _, fileHeader := range r.MultipartForm.File["files"] {
_, params, _ := mime.ParseMediaType(fileHeader.Header.Get("Content-Disposition"))
filename := params["filename"]
if filename == "" {
// TODO: Handle unexpected content disposition
// header (missing header, parse error, missing param).
}
I have tried to use grammar defined in grammars-v4 project(https://github.com/antlr/grammars-v4/tree/master/javascript/jsx) to parse jsx file.
When I parse the code snippet below,
let str =
`${dsName}${parameterStr ? `( ${parameterStr} )` : ""}${returns ? `{
${returns}}` : ""}`;
it shows the following error
line 2:32 at [#8,42:42='(',<8>,2:32]:no viable alternative at input '('
https://astexplorer.net/ shows it is a TemplateLiteral with conditionalExpression inside, any thoughts for parsing such grammar?
Thanks in advance.
Edit:
Thanks #Bart, it works.
It works fine on the following code.
const href1 = `https://example.com/lib/downloads_${page}.htm?joinSource=${joinSource}${inviter?`&inviter=${inviter}`: ''}`;
const href2 = `https://example.com/act/kol/detail_${this.props.values.list.res.rows && this.props.values.list.res.rows[0].id}_${page}.htm?joinSource=${joinSource}${inviter?`&inviter=${inviter}`: ''}`;
Given Mike's observation that it's the template string that is messing things up, here's a quick solution:
Changes:
JavaScriptLexerBase.java
Add the instance variable:
// Keeps track of the the current depth of nested template string backticks.
// E.g. after the X in:
//
// `${a ? `${X
//
// templateDepth will be 2. This variable is needed to determine if a `}` is a
// plain CloseBrace, or one that closes an expression inside a template string.
protected int templateDepth = 0;
JavaScriptLexer.g4
// Place TemplateCloseBrace above CloseBrace!
TemplateCloseBrace: {this.templateDepth > 0}? '}' -> popMode;
...
// Remove (or comment) TemplateStringLiteral
// TemplateStringLiteral: '`' ('\\`' | ~'`')* '`';
BackTick
: '`' {this.templateDepth++;} -> pushMode(TEMPLATE)
;
...
// Place at the end of the file:
mode TEMPLATE;
BackTickInside
: '`' {this.templateDepth--;} -> type(BackTick), popMode
;
TemplateStringStartExpression
: '${' -> pushMode(DEFAULT_MODE)
;
TemplateStringAtom
: ~[`]
;
JavaScriptParser.g4
singleExpression
: ...
| singleExpression templateStringLiteral # TemplateStringExpression // ECMAScript 6
| ...
;
literal
: ...
| templateStringLiteral
| ...
;
templateStringLiteral
: BackTick templateStringAtom* BackTick
;
templateStringAtom
: TemplateStringAtom
| TemplateStringStartExpression singleExpression TemplateCloseBrace
;
I did not fully test my solution, but it parses your example input successfully:
A quick look at the ANTLR grammar shows:
// TODO: `${`tmp`}`
TemplateStringLiteral: '`' ('\\`' | ~'`')* '`'
So, apparently, it’s on the “TODO List”. Allowing nested “`” string interpolation is surprising (to say the least), and will be “non-trivial” for the ANTLR Lexer (So, I would not "hold my breather" waiting on a fix for this).
Have you tried: (replacing the nested “`”s with “‘s?).
let str =
`${dsName}${parameterStr ? “( ${parameterStr} )” : ""}${returns ? “{
${returns}}” : ""}`;