GORM: Inserting *Big.Int into a NUMERIC column (postgresql) - postgresql

I'm having issues getting a database insert to work with gorm.
type T struct {
PoolAddress_ string `json:"pool_address" gorm:"column:pool_address"`
BlockNumber_ uint64 `json:"blockNumber" gorm:"column:block_number"`
TxHash_ string `json:"txnHashC" gorm:"column:transaction_hash"`
TransactionHash_ string `json:"transactionHash"`
OldPrice_ *big.Int `json:"old_price" gorm:"column:old_price"`
NewPrice_ *big.Int `json:"new_price" gorm:"column:new_price"`
KeeperAddress_ string `json:"keeper_address" gorm:"column:keeper_address"`
Source_ string `json:"source" gorm:"column:source"`
GasPrice_ uint64 `json:"gasPrice" gorm:"column:gas_price"`
GasTipCap_ uint64 `json:"GasTipCap" gorm:"column:gas_tip_cap"`
GasFeeCap_ uint64 `json:"GasFeeCap" gorm:"column:gas_fee_cap"`
GasUsed_ uint64 `json:"gasUsed" gorm:"column:gas_used"`
BlockTimestamp_ uint64 `json:"blockTimestamp" gorm:"column:block_timestamp"`
}
When GORM goes to handle it I get;
[debug] Inserting into table
{000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c42778b0248d4630b7a792dddea2af5094639e9b 4351477 0xc5d846bea7a43ce79ec5dfbe6ed8565e9d82753293300581eb57175b1cfd9f04 0xc5d846bea7a43ce79ec5dfbe6ed8565e9d82753293300581eb57175b1cfd9f04 46008860000000000000000000000000000000000 45868020000000000000000000000000000000000 0x1A5E4Fc790fa234954d9AD765314676dF79aB601 Arbitrum 50000000000 50000000000 50000000000 12500000 1631463094}
Failed to insert into the database! invalid field found for struct github.com/mycelium-ethereum/myc/types/ethereum/etl/log/ocr/Tracer/v1.T's field OldPrice_, need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface
This is really frustrating because I need these fields to be bigInts but GORM doesn't seem to want to let me even though I know the NUMERIC can hold the value on the database. I've looked at the valuer/scanner interfaces but they seem to want to return basic go types which obviously wouldn't work either.
I need the values to be a numeric, I cannot store this as text/bytes/etc.

Related

How do I use Hasura/postgres uuid with apollo-ios and swift

I have a table defined in Hasura (Postgres) using native uuid as the field datatype. My goal is to create an update mutation from Swift but the uuid type is not mapped implicitly from Postgres through Hasura and Apollo to Swift. The Hasura documentation states that the uuid type supports using String but when I define the variables, in the update mutation, as a String!,
mutation RedeemMagicLinkCode($code: String!, $iosIdentifierForVendor: String!) {
__typename
update_entityname(where: {code: {_eq: $code}, iosIdentifierForVendor: {_is_null: true}}, _set: {iosIdentifierForVendor: $iosIdentifierForVendor}) {
returning {
id
}
}
}
I get an error from the Apollo code gen build step that Variable "$code" of type "String!" used in position expecting type "uuid".. When I change that to uuid!,
mutation RedeemMagicLinkCode($code: uuid!, $iosIdentifierForVendor: uuid!) {
__typename
update_en...
The code gen step completes, producing API.swift, but several instances of the compile error Use of undeclared type 'uuid' raise and are now coming from a failure during compile of the Apollo generated API.swift.
/// API.swift
...
public let operationName = "RedeemMagicLinkCode"
public var code: uuid
public var iosIdentifierForVendor: uuid
...
Can someone point me in the right direction for letting Swift know what a uuid is or defining my query so that I can pass a String as a parameter through the Apollo managed mutation? Thanks so much!
OM(Goodness), I might need to blush at how simple this solution was.
I considered the error Use of undeclared type 'uuid' plus the documentation that Hasura will accept a String for this custom scalar...
/// API+typealias.swift
public typealias uuid = String
I placed the above type alias code in a file all by itself in the folder where my GraphQL files are and voila, it worked great!
I'm not thrilled with this public type alias now hanging out at the global scope but I am thrilled with a working data service

C++Builder - cannot cast from 'AnsiString' to 'TObject'

I have a problem with converting a string variable to TObject.
I have a query that returns two columns to me. In the first column I have varchar values that I translate into strings, and in the second column I have int values.
I want to fill a ComboBox in this way with these values:
cbx1-> AddItem (DataSet1->DataSet->Fields->Field[0]->AsString, (TObject *) (int) DataSet1->DataSet->Fields->Field[1];
As I refer to the second value which is int type, I receive some bushes, e.g., xD, etc.
By trying to convert this value to string, eg:
String temp = IntToStr (DataSet1->DataSet->Fields->Field[1]);
cbx1-> AddItem (DataSet1->DataSet->Fields->Field[0]->AsString, (TObject *) temp;
I receive an error message:
cannot cast from 'AnsiString' to 'TObject'
I do not know what further I can do to convert this value.
You cannot cast an AnsiString value to a TObject* pointer. You can only cast an integer value, or a pointer value, to a TObject* pointer. AnsiString is neither of those.
You are not retrieving the int value from the 2nd field correctly anyway. Field[1] is a pointer to an actual TField object in the Fields collection. That pointer is what you are trying to store in your ComboBox, NOT the int value that the TField represents.
You need to call Fields[1]->AsInteger to get the int value of the 2nd field, similar to how you use Fields[0]->AsString to get the string value of the 1st field:
cbx1->AddItem(
DataSet1->DataSet->Fields->Field[0]->AsString,
(TObject*) DataSet1->DataSet->Fields->Field[1]->AsInteger
// in C++, using reinterpret_cast is preferred over C-style casting:
// reinterpret_cast<TObject*>(DataSet1->DataSet->Fields->Field[1]->AsInteger)
);
This is no different than the code in your previous question:
cbx1->AddItem("one",(TObject*)1);
You are now just placing the literals "one" and 1 with runtime variables of equivalent types.

Get nested object in structure in gorm

I have two structures:
type GoogleAccount struct {
Id uint64
Token string
}
It represent my custom PostgreSQL object type (i created myself):
CREATE TYPE GOOGLE_ACCOUNT AS
(
id NUMERIC,
token TEXT
);
And next structure is table in DB:
type Client struct {
IdClient uint64 `gorm:"primary_key"`
Name string
PhotoUrl string
ApprovalNumber uint16
Phone string
Password string
HoursOfNotice int8
Google GoogleAccount
}
And my custom object nested in type Client and named as google. I've tried to read data by the next way:
var users model.Client
db.First(&users)
But unfortunately I can't read field google (have a default value). I don't want to create separate table with google_account, or make this structure as separated fields in client table or packed it as json (created separate entity, because this structure used not only in this table and I'm searching new ways, that get the same result, but more gracefully). The task is not to simplify the presentation of data in the table. I need to make the correct mapping of the object from postgres to the entity.
Right now I found one solution - implement Scanner to GoogleAccount. But value in the input method is []uint8. As I can suppose, []uint8 can cast to string, and after that I can parse this string. This string (that keep in db) look like (x,x) - where x - is value. Is the right way, to parse string and set value to object? Or is way to get this result by ORM?
Is the possible way, to read this data as nested structure object?
It looks like you'll want to do two things with what you have: (1) update the model so you have the right relationship binding, and (2) use the .Preload() method if you're trying to get it to associate the data on read.
Model Changes
Gorm automatically infers relationships based on the name of the attributes in your struct and the name of the referenced struct. The problem is that Google attribute of type GoogleAccount isn't associating because gorm is looking for a type Google struct.
You're also missing a foreign key on GoogleAccount. How would the ORM know which GoogleAccount to associate with which Client? You should add a ClientId to your GoogleAccount struct definition.
Also, I would change the primary keys you're using to type uint since that's what gorm defaults to (unless you have a good reason not to use it)
If I were you, I would change my struct definitions to the following:
type Client struct {
IdClient uint `gorm:"primary_key"`
Name string
PhotoUrl string
ApprovalNumber uint16
Phone string
Password string
HoursOfNotice int8
GoogleAccount GoogleAccount // Change this to `GoogleAccount`, the same name of your struct
}
type GoogleAccount struct {
Id uint
ClientId uint // Foreign key
Token string
}
For more information on this, take a look at the associations documentation here: http://gorm.io/associations.html#has-one
Preloading associations
Now that you actually have them properly related, you can .Preload() get the nested object you want:
db.Preload("GoogleAccount").First(&user)
Using .Preload() will populate the user.GoogleAccount attribute with the correctly associated GoogleAccount based on the ClientId.
For more information on this, take a look at the preloading documentation: http://gorm.io/crud.html#preloading-eager-loading
Right now I found one solution - implement Scanner to GoogleAccount. At input of the Scan method I got []uint8, that I cast to string and parse in the end. This string (that keeping in db) look like (x,x) - where x - is value. Of course, it is not correct way to achieve my goal. But I couldn't found other solution.
I highly recommended use classical binding by relationship or simple keeping these fields in table as simplest value (not as object).
But if you would like to experiment with nested object in table, you can look at my realization, maybe it would be useful for you:
type Client struct {
// many others fields
Google GoogleAccount `json:"google"`
}
type GoogleAccount struct {
Id uint64 `json:"id"`
Token string `json:"token"`
}
func (google GoogleAccount) Value() (driver.Value, error) {
return "(" + strconv.FormatUint(google.Id, 10) + "," + google.Token + ")", nil
}
func (google *GoogleAccount) Scan(value interface{}) error {
values := utils.GetValuesFromObject(value)
google.Id, _ = strconv.ParseUint(values[0], 10, 64)
google.Token = values[1]
return nil
}

Ext-gwt (gxt) TextField getFieldValue() problem

I have an TextField with datatype Integer, so I am trying to getFieldValue() and write it to Integer field. So in runtime I have an error here:
TextField<Integer> priceField = new TextField<Integer>();
Integer newPriceFieldValue = priceField.getValue(); //here is an error in runtime
So I cant understand whats the problem - proceField.getValue() should be Integer, why string? Maybe I should another type of Field?
java.lang.ClassCastException: java.lang.String cannot be cast to
java.lang.Integer
at
ru.braginini.client.ProductForm$2.componentSelected(ProductForm.java:64)
at
ru.braginini.client.ProductForm$2.componentSelected(ProductForm.java:1)
If you are expecting only numbers to be used in this field NumberField may be the better choice.
NumberField field = new NumberField();
field.setPropertyEditorType(Integer.class);
It will ensure only numbers are entered, and save you some casting & error handling on the getValue() call.
getValue returns a String!
You want to assign this String to an Integer which causes an CastException (like it would in any Type oriented Programming language.
Try
Integer newPriceFieldValue = Integer.parseInt(priceField.getValue());
Regards,
Stefan

int to string in Entity Framework

How do you convert an int to a string in Link to EF?
The clr cant imagine casting an int to a string and Entity framework cant figure out what SQL snippet to translate .ToString() into.
So how do you write a linq statement that returns a string instead of an int?
Sadly EF does not know how to convert .ToString(). You must use the embedded function SqlFunctions.StringConvert: http://msdn.microsoft.com/en-us/library/dd466292.aspx
Also there is no overload for int so you must typecast to double :-(
var vendors =
from v in Vendors
select new
{
Code = SqlFunctions.StringConvert((double)v.VendorId)
};