Coldfusion Query broken column structure - coldfusion

A coldfusion query's column can be referenced like a 2D array from what I know of my past experience. Sometimes though I get this issue.
create query from spreadsheet
put column names into an array
only get first element when trying to access the row
have to use a workaround
//imports is a query object after this function
var imports = convertSpreadsheetWOHeaders(spreadsheet, 1);
//this is used to give name values in the json struct, not to access the query columns
var jsonHeaders = ListToArray("number,constructiontype,description,site_address,parcel,permit_date,note_Applicant,note_Contractor,valuation,note_Bld_Fees,note_Other_Fees");
//this gives me ["col_1","col_2","col_3",,,etc]. used to access query columns
var columnHeaders = imports.getColumnNames();
writeDump(imports[columnHeaders[1]]);
writeDump(imports);
I am left with just the first element in column one. And I get of course:
Message: You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members.
When trying to do this:
structInsert(jsonStruct,jsonHeaders[j],imports[columnHeaders[j]][i]);
However, this works:
writeDump(ListToArray(ArrayToList(imports[columnHeaders[1]],'|'),'|',true));
I first do a dump of imports["col_1"] and i get only the first element.
Then I do a dump of ListToArray(ArrayToList(imports["col_1"])) like you see in the above image and it gives me the whole column.
Why can I not access the column correctly in the first place?

The Real Problem:
I was originally trying to access the jsonHeaders list as an array without doing ListToArray() on it. After that my function worked.
BUT. This next part is helpful.
When attempting to access a query object, doing queryObject["columnName"] is considered a shortcut of queryObject["columnName"][1] so coldfusion will just give you the first element.
But when I said ListToArray(ArrayToList()) coldfusion sees that ArrayToList MUST take in an array so an exception is made and the column is returned as an array.
To get a column back as an array to work with you can do a couple things
ListToArray(ArrayToList(query["column"]));
ListToArray(valueList(query.column));
valueArray(query, "column");

Related

Custom Function Using Column As Parameter

I have a custom function created in the Power Query Editor that accepts two parameters. One parameter should be dynamic based upon the value in a column. When tested with static parameters, the function works correctly as far as using a static parameters goes. However, if the table column is supplied (to provide the dynamic value needed), it produces a cyclical error. The function is invoked using "Invoke Custom Function". The first parameter selects a field, while the second parameter is set statically.
The Invoke Custom Function that produces a correct result:
= Table.AddColumn(#"Rounded Up", "qryProjectedDate", each qryProjectedDate(5, -1))
The Invoke Custom Function that produces an error:
= Table.AddColumn(#"Rounded Up", "qryProjectedDate", each qryProjectedDate([RemainingBudgetDays_RndUp], -1))
The qryProjectedDate:
(TotalLoops as number, Loop as number) =>
let
CurrentLoop = Loop + 1,
output =
if Calendar[IsWorkDay]{CurrentLoop} = 1
then
(if CurrentLoop = TotalLoops - 1
then Calendar[Date]{CurrentLoop}
else #qryProjectedDate(TotalLoops, CurrentLoop))
else #qryProjectedDate(TotalLoops + 1, CurrentLoop)
in output as date
This function produces a stack overflow error and a cyclical error messages.
Further testing of just inputting the column value as a parameter and returning that same value produces the value that I would expect. Therefore, I believe my issue is in how I have written the power query M function.
if function(5,-1) works then using function([column1],-1) will also work if column1 contains a numeric five
Are you sure the column is named RemainingBudgetDays_RndUp ? Spelling and capitalization of the column name matter. Try temporarily renaming that column and look at the output to see what powerquery thinks that column is named
Once that is set, is the column formatted as numeric or alpha? If not numeric, change the column type or use Number.From() in your function
Try calling your function using a table with a single row, and the contents of the RemainingBudgetDays_RndUp column equal to a numeric five. Does it work? Then the data needs cleaning on some of the rows
Are there any nulls, alpha characters, out of bound, or other data in the RemainingBudgetDays_RndUp column that will break your function? To guard against that, try adding a try and otherwise null before and after strategic points in the function

How do I Loop through a multi-value People Field or Lookup field in SharePoint 2013 designer using REST

I have a multi-valued people picker and a multi-valued Lookup field that I need to read all the entries in a 2013 workflow. I know how to create a workflow that retrieves the data and iterate through each list item using REST and a dictionary. Given I'm iterating through each item, I need to now iterate through each multi-valued field.
In the past, I have done this using a loop iterator and a second dictionary entry representing the data in the multi-valued field, but I don't have access to this code anymore. I can use a loop and use the find function parsing through my responseContent, but this is not reliable since my reponseContent will have multiple records in it and I know it can be done using a second dictionary entry.
My REST query is:
_api/lists/GetByTitle('EmailSetup')/Items?$select=EmailYN,EmailSubject,EmailBody,EmailTo/EMail,Emailcc/EMail,EmailToWorkflowPerson/Title,EmailccWorkflowPersons/Title&$filter=(Title%20eq%20%27BSM%20Review%27)%20and%20(WorkflowName%20eq%20%27ProcessBSMRequests%27)&$expand=EmailTo,Emailcc,EmailToWorkflowPerson,EmailccWorkflowPersons
Where my multi-valued fields are the Emailcc and EmailccWorkflowPerson, (people picker and lookup respectively).
I have my first dictionary as the following data structure that captures the requestHeaders
Accept String application/json;odata=verbose
Content-Type String application/json;odata=verbose
In my first loop I get all my attributes, but not certain how to get the multi-valued fields Emailcc and EmailccWorkflowPersons.
Yes, I can parse through my response, but there's a better way to somehow put these multi-value fields into a structure and then loop through these.
What I need is what is that structure (dictionary) and how do you get the data into that structure and then how do you loop through that structure.
The final result should be of the sort (psuedocode) where Index is which record I am on and Index2 is which multi-value I am on.
d/results([%Varaible: Index%])/Emailcc/Email[%Variable: Index2%])xxx
With a lot of debugging I have gotten half my answer and maybe someone can help me with the other half. The data structure of the data when it comes back via the REST looks like (some masking of our own data):
responseContent={"d":{"results":[{
"__metadata":{"id":"Web\/Lists(guid'c7bb71c8-a9dd-495f-aa5f-4dcacdf8db5c')\/Items(1)","uri":"https:\/\/xxxxx.xxxxxx.xxxxxxxxx.xxx\/hc\/teams\/MES\/_api\/Web\/Lists(guid'c7bb71c8-a9dd-495f-aa5f-4dcacdf8db5c')\/Items(1)","etag":"\"13\"","type":"SP.Data.EmailSetupListItem"},
"EmailTo":{"__metadata":{"id":"b493bee4-ec1a-4b76-a028-11766bdb7e5b","type":"SP.Data.UserInfoItem"},"EMail":"xyxee.dyff#homeward.com"},
"EmailToWorkflowPerson":{"__deferred":{"uri":"https:\/ \/xxxxx.xxxxxx.xxxxxxxxx.xxx\/hc\/teams\/MES\/_api\/Web\/Lists(guid'c7bb71c8-a9dd-495f-aa5f-4dcacdf8db5c')\/Items(1)\/EmailToWorkflowPerson"}},
"Emailcc":{"results":[{"__metadata":{"id":"790a690a-515b-4d07-bba3-73bf325fbbed","type":"SP.Data.UserInfoIt em"},"EMail":"xyxee.dyffns1#homeward.com"},{"__metadata":{"id":"3d77e75c-5fa8-4df6-937c-97e572714843","type":"SP.Data.UserInfoItem"},"EMail":"xyxee.dyffr#homeward.com"}]},
"EmailccWorkflowPersons":{"results":[{"__metadata":{"id":"06582ed9-09 10-4932-9b43-0cfb072942c7","type":"SP.Data.WorkflowPersonsListItem"},"Title":"Assistant Administrator"},{"__metadata":{"id":"13d03566-1703-4550-a21f-08ea286d4940","type":"SP.Data.WorkflowPersonsListItem"},"Title":"Initiator"}]},
"EmailYN":"No",
"EmailSubject":"BSM Request # %%ID%%",
"EmailBody":"<div class=\"ExternalClass645790473F7D4B62BE6224DD7B93990F\">%%IDLINK%%<br><\/div><div class=\"ExternalClass645790473F7D4B62BE6224DD7B93990F\">and the BSM# %%ID%%<br><\/div><div class=\"ExternalClass64 5790473F7D4B62BE6224DD7B93990F\"><br><\/div>"
}]}}
I created another dictionary variable, EmailResults just as the first one to store the multi-value emailcc addresses.
Then the following Get:
Get d/results([%variable: Index%)/Emailcc/results from Variable:responseContent (Output to Variable: EmailccResults)
To get the record count, I use Count Items in the EmailccResults
I set my second index to start at zero and loop through the number baseed on the count in EmailccResults.
To set my intermediate email address (getting one value at a time from the mult-value People picker).
Get d/results([%variable: Index%)/Emailcc/results(%Variable: Index2%)/EMail from Variable: responseContent (Output to Variable: EmailCc)
then I increment the Index2 variable and go to the next record. This works perfectly.
Now my problem is I have a multi-value Lookup that is included in this query (see what the results are above). I attempt the same logic and I am successfully getting the count, but not the Title fields.
My get is:
Get d/results([%variable: Index%)/EmailccWorkflowPersons/results from Variable:responseContent (Output to Variable: EmailccResults)
My actual assignment is:
Get d/results([%variable: Index%)/EmailccWorkflowPersons/results(%Variable: Index2%)/Title from Variable: responseContent (Output to Variable: tmpvar)
** the Lookup works exactly the same way. My problem was that my get above had some blank lines in the text box.

Inserting large BSON objects does not work

I am trying to write a program in C++ to read, manipulate, and update my database. I am having a problem inserting my data into mongo. So for my work flow, I get some type of request to update a document. I query the document, and update the data. I then try to do an update on the document.
I have a function that converts my class object to a BSONObj through a BSONObjBuilder. I seem to be having a problem with large arrays of sub-objects. For example, I have a field in my document called geo that looks like this:
geo: [{"postal": 10012},{"postal":10013},...,{"postal":90210}]
and is stored in C++ as:
std::vector<mongo::BSONObj> geo;
this field might have thousands of postal codes in it. When doing:
db.get()->update("db.collection",BSON("id"<<id_), BSON($set<<updateObj));
where updateObj is the obj I got from my BSONObjBuilder, nothing is updated in mongo. If I remove the geo field, everything is inserted.
I tried to just do
db.get()->update("db.collection",BSON("id"<<id_), BSON($set<<BSON("geo" << geo)));
thinking maybe it necessary to do separate queries due to the size of the obj and this also result in no update.
I was wondering if somehow I was hitting some sort of BSON size limit in C++.
The only reason I believe it is a size limit is because while trying to debug this problem, I tried to call updateObj.toString() in order to print out the object I was trying to insert and it threw an exception: Element extends past end of object. I assume that this means I hit some type of max size of an object/element.
Any insight into this problem will be greatly appreciated.
Thank you
I seemed to have figured it out. What happened was I got the geo field in one function, stored it in a vector and was using it in another. I did not used .Obj().copy() while storing the object in the vector, I just stored the .Obj() from the query results and when I went to insert I guess the invalid pointers blew up the BSONObj and caused an error.

mysql++ (mysqlpp): how to get number of rows in result prior to iteration using fetch_row through UseQueryResult

Is there an API call provided by mysql++ to get the number of rows returned by the result?
I have code structured as follows:
// ...
Query q = conn.query(queryString);
if(mysqlpp::UseQueryResult res = query.use()){
// some code
while(mysqlpp::Row row = res.fetch_row()){
}
}
My previous question here will be solved easily if a function that returns the number of rows of the result. I can use it to allocate memory of that size and fill in as I iterate row by row.
In case anyone runs into this:
I quote the user manual:
The most direct way to retrieve a result set is to use Query::store(). This returns a StoreQueryResult object,
which derives from std::vector, making it a random-access container of Rows. In turn,
each Row object is like a std::vector of String objects, one for each field in the result set. Therefore, you can
treat StoreQueryResult as a two-dimensional array: you can get the 5th field on the 2nd row by simply saying
result[1][4]. You can also access row elements by field name, like this: result[2]["price"].
AND
A less direct way of working with query results is to use Query::use(), which returns a UseQueryResult object.
This class acts like an STL input iterator rather than a std::vector: you walk through your result set processing
one row at a time, always going forward. You can’t seek around in the result set, and you can’t know how many
results are in the set until you find the end. In payment for that inconvenience, you get better memory efficiency,
because the entire result set doesn’t need to be stored in RAM. This is very useful when you need large result sets.
A suggestion found here: http://lists.mysql.com/plusplus/9047
is to use the COUNT(*) query and fetch that result and then use Query.use again. To avoid inconsistent count, one can wrap the two queries in one transaction as follows:
START TRANSACTION;
BEGIN;
SELECT COUNT(*) FROM myTable;
SELECT * FROM myTable;
COMMIT;

Is there a way to get each row's value from a database into an array?

Say I have a query like the one below. What would be the best way to put each value into an array if I don't know how many results there will be? Normally I would do this with a loop, but I have no idea how many results there are. Would I need run another query to count the results first?
<CFQUERY name="alllocations" DATASOURCE="#DS#">
SELECT locationID
FROM tblProjectLocations
WHERE projectID = '#ProjectName#'
</CFQUERY>
Depending on what you want to do with the array, you can just refer to the column directly for most array operations, eg:
i = arrayLen(alllocations["locationID"]);
Using that notation will work for most array operations.
Note that this doesn't "create an array", it's simply a matter that a query columns - a coldfusion.sql.QueryColumn object is close enough to a CFML array for CF to be able to convert it to one when an array is needed. Hence the column can be passed to an array function.
What one cannot do is this:
myArray = q["locationID"];
This is because by default CF will treat q["locationID"] as a string if it can, and the string value is what's in the first row of the locationID column in the q query. It's only when an array is actually required will CF convert it to an array instead. This is basically how loose-typing works.
So if you just need to pass your query column to some function that expects an array, you can use the syntax above. If you want to actually put the column into a variable, then you will need to do something like this:
myArray = listToArray(valueList(q.localtionID));
NB: make sure you use <cfqueryparam> on your filter values instead of hard-coding them into your SQL statement.
myquery.column.toArray() is also a good undocumented choice.
Since you're only retrieving 1 field value from the query, you could use ValueList() to convert the query results into a comma-delimited list of locationIds, then use listToArray() to change that list into an array.
If you were retrieving multiple field values from the query, then you'd want to loop through the query, copy all the field values from the given row into a struct, and then add that struct to an array using arrayAppend().
(If you're not familiar with these functions, you can look them up in the Adobe docs or on cfquickdocs.com).