Good Day,
Not sure the most appropriate method for handling this question, but scouring Google has yet to pay off.
I effectively have a PSQL query (using the “pg” shard) that builds a query in a rather dynamic fashion.
Now this is rather awful indeed to build the hash out in this fashion. However, the types of what is to be returned is entirely unknown. Basically I need to return some data from any table based off of the object_id and the model_name.
Thus I cannot build out a struct as I do not know the data types, therefore, this is the best I can come up with.
def fetch_subject_if_exists(model_name, object_id)
if object_id.not_nil! && model_name.not_nil!
pg_db.query "SELECT * FROM #{model_name} WHERE id = '#{object_id}' LIMIT 1" do |data|
dataHash = Hash(String, Array(PG::BoolArray) | Array(PG::CharArray) | Array(PG::Float32Array) | Array(PG::Float64Array) | Array(PG::Int16Array) | Array(PG::Int32Array) | Array(PG::Int64Array) | Array(PG::NumericArray) | Array(PG::StringArray) | Array(PG::TimeArray) | Bool | Char | Float32 | Float64 | Int16 | Int32 | Int64 | JSON::PullParser | PG::Geo::Box | PG::Geo::Circle | PG::Geo::Line | PG::Geo::LineSegment | PG::Geo::Path | PG::Geo::Point | PG::Geo::Polygon | PG::Interval | PG::Numeric | Slice(UInt8) | String | Time | UInt32 | UUID | Nil).new
data.each {
data.each_column { |c| dataHash.merge!({"#{c}" => data.read}) }
}
return dataHash
end
else
return {} of Int32 => Int32
end
end
The primary issue here is that some of the values are of type JSON::PullParser when I want them to effectively be a JSON blob or Hash. I have read through the documentation here multiple times:
https://crystal-lang.org/api/1.2.2/JSON/PullParser.html
However, it is entirely unhelpful in providing any insights as to what might be a decent method of converting the type into something useful.
If I attempt to determine the type of the object within the data.each loop the following occurs:
data.each {
value = data.read
if value.class == JSON::PullParser
puts value.read_raw
end
data.each_column { |c| dataHash.merge!({"#{c}" => data.read}) }
}
Effectively the compiler is treating every object of any of the types within the Hash starting with a Array(PG::BoolArray) which obviously does not have the methods of a JSON::PullParser object.
So the problem seems multi-fold. With the abstract/random data types I will get back from the query above I cannot build something like a struct to contain the data. Additionally, using the above to build a hash of the data I do get back, I cannot do anything with the JSON::PullParser objects in order to get them into something usable.
Any assistance is most greatly appreciated. Now this is the first time I have written any code in Crystal (Starting Friday) and I am at an impasse here as well as lacking knowledge.
Thus, I am very open to better ways of doing this.
Cheers!