Is there a simpler way to decode this json in Go? - arrays

I am trying to parse some JSON from Jira to variables. This is using the go-jira package (https://godoc.org/github.com/andygrunwald/go-jira)
Currently I have some code to get the developer:
dev := jiraIssue.Fields.Unknowns["customfield_11343"].(map[string]interface{})["name"]
and team := jiraIssue.Fields.Unknowns["customfield_12046"].([]interface{})[0].(map[string]interface{})["value"]
to get the team they are a part of from.
Getting the team they are on is a bit gross, is there a cleaner way to get the team besides having to type assert, set the index, then type assert again?
Here is the complete json (modified but structure is same, its way too long):
{
"expand":"renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id":"136944",
"self":"https://jira.redacted.com/rest/api/2/issue/136944",
"key":"RM-2506",
"fields":{
"customfield_11343":{
"self":"https://redacted.com/rest/api/2/user?username=flast",
"name":"flast",
"key":"flast",
"emailAddress":"flast#redacted.com",
"displayName":"first last",
"active":true,
"timeZone":"Europe/London"
},
"customfield_12046":[
{
"self":"https://jira.redacted.com/rest/api/2/customFieldOption/12045",
"value":"diy",
"id":"12045"
}
],
}
Thanks

The way I go about problems like this is:
Copy some JSON with things I am interested in and paste it into https://mholt.github.io/json-to-go/
Remove fields that arenĀ“t of interest.
Just read the data and unmarshal.
You might end up with something like this given the two custom fields of interest, but you can cut the structure down further if you just need the name.
type AutoGenerated struct {
Fields struct {
Customfield11343 struct {
Self string `json:"self"`
Name string `json:"name"`
Key string `json:"key"`
EmailAddress string `json:"emailAddress"`
DisplayName string `json:"displayName"`
Active bool `json:"active"`
TimeZone string `json:"timeZone"`
} `json:"customfield_11343"`
Customfield12046 []struct {
Self string `json:"self"`
Value string `json:"value"`
ID string `json:"id"`
} `json:"customfield_12046"`
} `json:"fields"`
}
The effect you get is that all extra information in the feed is discarded, but you get the data you want very cleanly.

This is a tough one since the second one is in an array form. It makes it hard to use a map.
For the first one, it's simple enough to use:
type JiraCustomField struct {
Self string `json:"self"`
Name string `json:"name"`
Key string `json:"key"`
EmailAddress string `json:"emailAddress"`
DisplayName string `json:"displayName"`
Active bool `json:"active"`
TimeZone string `json:"timeZone"`
}
type JiraPayload struct {
Expand string `json:"expand"`
ID string `json:"id"`
Key string `json:"key"`
Fields map[string]JiraCustomField `json:"fields"`
}
https://play.golang.org/p/y8-g6r0kInV
Specifically this part Fields map[string]JiraCustomField for the second case it looks like you need it in an array form like Fields map[string][]JiraCustomField.
In a case like this, I think you'll need to make your own Unmarshaler. This is a good tutorial: https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
What you could do with your custom Unmarshal/marshaler, is use the Reflection package and check if it's an array or a struct. If it's a struct then put it into an array, and store it in Fields map[string][]JiraCustomField.

Related

Mapping an array of classes to remove whitespace from values swift

I have a struct and an array of my structs as follows
struct Products{
var ProductType: String
var ProductName: String
var ProductLink: String
}
var CleaningProductsArray = [Products]()
When I write to my array of structs the ProductName Variable inside it sometimes can be written by the user with trailing whitespaces. I would like to return a version of the CleaningProductsArray but with all instances of ProductName having any trailing whitespaces removed. I have been trying to achieve with map as below but does not return what I would like it to. What is the most efficient way to do this?
let trimmed = CleaningProductsArray.map{ $0.ProductName.trimmingCharacters(in: .whitespaces) }
Quick answer is:
let trimmed: [Products] = CleaningProductsArray.map { product in
var adjusted = product
adjusted.ProductName = product.ProductName.trimmingCharacters(in: .whitespaces)
return adjusted
}
As it was correctly mentioned in the comments, there are things you can improve in your overall code design.
You could start with converting your model to meet Swift naming standards, which means not using plural for Products since the objects of this type describe a single product, and removing the product prefix from properties since its obvious from the context that they describe a "Product". Ideally you would also make the properties immutable, to make passing them around safer (google "Benefits of immutability"). You should create some other object responsible for collecting all the data for your product objects.
struct Product {
let type: String
let name: String
let link: String
}
Also, you should never use uppercased names for your variables/constants/properties/functions in Swift, so it's best to replace the CleaningProductsArray with cleaningProductsArray for the sake of readability. Uppercased names are reserved for types. Also you might want to drop the Array suffix since it's obvious from the type that it is an array
var cleaningProducts = [Product]()
let trimmed: [Product] = cleaningProducts.map {
Product(
type: $0.type,
name: $0.name.trimmingCharacters(in: .whitespaces),
link: $0.link
)
}

Using go-pg to retrieve virtual columns from Postgres

I'm using go-pg (https://github.com/go-pg/pg) and this code:
type Book struct {
id int
name string
}
var books []Book
err := db.Model(&books).Select()
and everything works good but I need to add a "virtual" column like this:
concat ('info:', 'id:', id, '...') AS info
and I tried to use:
query.ColumnExpr("concat ('info:', 'id:', id, '...') AS info")
but:
go-pg complains with: error="pg: can't find column=info in model=Book (try discard_unknown_columns)"
go-pg doesn't include anymore columns id and name in query: concat... ONLY!
I can understand that because now go-pg doesn't know how to bind data, but I really need that string which I can retrieve from DB only.
Is there a way?
Can I use a custom type like this below?
type CustomBook struct {
Info string
Book
}
Does this make sense?
this approach could work for you:
type Book struct {
ID int
Name string
Info string `pg:"-"`
}
...
db.Model(&books).ColumnExpr("book.*").ColumnExpr("CONCAT('id:', id, 'name:', name) AS info").Select()
pg:"-" ignores the struct field and it is not created nor it produces any errors
this ignored column is documented here: https://pg.uptrace.dev/models/
another approach, depending on your requirements could be like this:
var r []struct {
Name string
Info string
}
db.Model((*Book)(nil)).Column("name").ColumnExpr("CONCAT('id:', id, 'name:', name) AS info").Select(&r)
this second one is documented here: https://pg.uptrace.dev/queries/

How do I encode an array of Byte32 values for Web3j to pass to my smart contract?

Contract function is defined as:
function createAggregate (string memory key, bytes32[2] memory part_array) public returns (bytes32)
and have incoming a list of parts, defined as...
List<Bytes32> elements
so was trying to use:
List<Type> items = new ArrayList<Type>();
items.add(...); // user reference
items.add(new DynamicArray<>(elements));
final Function function = new Function("createAggregate",
items,
Arrays.asList(new TypeReference<Bytes32>() {})
);
...
But this does not work, seems to be an encoding issue - what is the right what of encoding the Bytes32 ? (This seems to work fine for an array of strings)
Sort of solved this with the following (although was really looking for a more dynamic size solution)
new StaticArray2(Bytes32.class, Utils.typeMap(elements, Bytes32.class));

Decimal type in Go and Postgresql with gorm

So i'm creating an API and I needed to store the price of something.
I'm using gorm and gormigrate for my database migration.
I'm just wondering what proper type should I use for storing decimals. I've red somewhere that I shouldn't use floats when storing currencies.
type MyStruct struct {
Name string `json:"name" gorm:"not null"`
Description string `json:"description" gorm:"null"`
Price <what type should be here> `json:"price"`
}
So, based on the suggestion of #ain, I used shopspring/decimal. But it's giving me an error when I do automigrate.
It turns out that I only needed to set the type to numeric using a gorm tag to make it work:
type MyStruct struct {
Name string `json:"name" gorm:"not null"`
Description string `json:"description" gorm:"null"`
Price decimal.Decimal `json:"price" gorm:"type:numeric"`
}

How to parse SQL record to Enum

Is there a way to parse enum value from table record. For example, I have class which contains user data, and on of them is Enum type. The data is passed from DataRow, but I have trouble parsing enum value.
I tried something like this,
uType= (EType) Enum.TryParse(typeof(row["userType"]));
but it wouldn't compile. Any tip?
Thanks.
try with this code
uType = (EType) Enum.Parse(typeof(EType), row["userType"].ToString(), true);
Enum.TryParse returns a boolean that indicates if the value could be parsed successfully.
Assuming that userType is a string in the DataTable:
EType eType;
bool canParse = Enum.TryParse(row.Field<String>("userType"), out eType);

Resources