Trying to pass a string back from a function in PowerShell - function

function ExtractLocations([ref]$lp_Locations) {
$lp_Locations.Value = "A STRING VALUE"
return 0
}
...
$Locations = ""
if (#(ExtractLocations([ref]$Locations)) -ne 0) {
RecordErrorThenExit
}
$Locations always ends up as a blank string.

Apart from what #mklemen0 said, to set the value, you need not to do it like $Variable.Value = 'Something' , its just $Variable = 'Something'
With the #() expression, you are converting the output to an array which is not what you need here. Declaring functions similar to methods in c# is not suggested in PowerShell. You could do it like below.
function ExtractLocations{
Param([ref]$lp_Locations)
$lp_Locations = "A STRING VALUE"
return 0
}
ExtractLocations -lp_Locations ([ref]$Locations)

Could not get it working with parameters no matter what I tried so returned the value as a string and that works:
function ExtractLocations
{
....
return $lp_Locations
}
$Locations = ExtractLocations
write "MODIFY $TABLE TO REORGANIZE WITH LOCATION = ($($Locations.value)) \p\g" | sql $SQLFLAGS $TARGETDB

Related

Invalid argument supplied for foreach() issue in laravel

My query in controller page
$d= "DB::table('users')->where('gender',$gender)";
if(!empty($age)){
$d.= "->where('age','>',$age)";
}
$d.="->paginate(20)";
if age is not empty that time only want add age to the query. but query showing Invalid argument supplied for foreach() error. Without double quotes query running but unable to avoid empty age variable.
Shorter version
$d = DB::table('users')->where('gender',$gender);
$d = empty($age) ? $d->paginate(20) : $d->where('age','>',$age)->paginate(20);
Please try it:
$d = DB::table('users')->where('gender',$gender);
if(! empty($age)) {
$d = $d->where('age','>',$age);
}
$d = $d->paginate(20);

PowerShell - "RETURN" in function returns values two times INSTEAD of just one

I was assuming that "return" in PowerShell function will return the value and exit the function, but instead of that I am getting the values for two times!!!!???
Please assist me.
I have a default value, I have logic for retreiving the real value (if exists) but instead I am getting two fules as output - but I do not want that! I need just one value.
Thank you in advance!!!
function GetTenantTagValue($TAG_SET_NAME) {
Write-Host("Tag Set Name:"+$TAG_SET_NAME)
$TAG_SET_VALUE = "N/A"
$TENANT_TAGS = "Customer Code/HEDGE"
$TENANT_TAGS | ForEach-Object {
$TAG_NAME = $_.split("/")[0]
$TAG_VALUE = $_.split("/")[1]
if ($TAG_NAME -eq $TAG_SET_NAME) {
# $TAG_SET_VALUE = $TAG_VALUE
Write-Host("Tag Value:"+$TAG_VALUE)
Write-Host("#########################")
return $TAG_VALUE
}
}
Write-Host("Tag Set Value:"+$TAG_SET_VALUE)
return $TAG_SET_VALUE
}
I invoke the function with:
GetTenantTagValue "Customer Code"

Strange behaviour from MySQL in Powershell

I'm new to PowerShell and have a specific question about working with MySQL in PowerShell.
I got this function:
Function run-mySQLInsertQuery{
param(
$connection,
[string[]]$insertQuery
)
foreach ($command in $insertQuery){
$MySQLCommand = $connection.CreateCommand()
$MySQLCommand.CommandText = $command
$rowsInserted = $MySQLCommand.ExecuteNonQuery()
if ($rowsInserted) {
return $rowsInserted
} else {
return $false
}
}
}
With this version of the function i get the following Error:
Cause:
"The CommandText property has not been properly initialized."
Errorline:
$rowsInserted = $MySQLCommand.ExecuteNonQuery()
I searched for a solution and edited my function a bit to the following (for testing purpose):
Function run-mySQLInsertQuery{
param(
$connection,
[string[]]$insertQuery
)
$abcd = $insertQuery[1]
foreach ($command in $insertQuery){
$MySQLCommand = $connection.CreateCommand()
$MySQLCommand.CommandText = $abcd
$rowsInserted = $MySQLCommand.ExecuteNonQuery()
}
}
With this code, the function executes the query without a problem. My question now is, why? i cant really see a difference, because in $command should be the exact same query like it is in $abcd. Or am I getting something wrong?
EDIT:
As its asked it the comments, here is how i call the function:
[String[]]$statements = ""
foreach($key in $arrayStatus.Keys){
$item = $arrayStatus[$key]
$insertStatus = "INSERT INTO tx_tphbusinessofferings_domain_model_status (status_id, status) VALUES ('$key', '$item')"
$statements += $insertStatus
}
$Rows = run-mySQLInsertQuery -connection $mySQLconnection -insertQuery $statements
The problem is that you are initializing your array (the one you are passing in) with an empty string:
[String[]]$statements = ""
And then adding elements to it... so your first iteration of the passed array is an empty string, which won't work (it'll set the command text as empty, that's the error you are getting). It works on the second code because you are grabbing the second object of the array (which is your insert statement).
Initialize your array to empty and it should work:
[String[]]$statements = #()
Apart from that, your first script always returns on the first iteration, so it'll only work once (not for every insert you pass). Not sure what do you want to return if you are passing in more than one query, but that's up to your design decisions

Reason my subroutine won't recurse

#!/usr/bin/perl
use strict;
use warnings;
use List::MoreUtils 'uniq';
my %functiontable =();
$functiontable{foo} = \&foo;
sub iterate {
my ($function, $iterations, $argument) = #_;
return $argument unless 0 < $iterations;
return $argument unless $function = $functiontable{$function};
my #functioned = $function->($argument);
my #refunctioned = ();
for my $i (0 .. #functioned - 1) {
push #refunctioned, iterate ($function, ($iterations - 1), $functioned[$i]);
}
return uniq #refunctioned;
}
sub foo {
my ($argument) = #_;
my #list = ($argument, $argument.'.', $argument.',');
return #list;
}
my #results = iterate 'foo', 2, 'the';
print "#results";
This prints the the. the,, i.e. it doesn't iterate (recurse). I would expect it to print the the. the, the.. the., the,. the,,.
(I used Smart::Comments to check whether it enters iterate a second time, and it does, but it doesn't seem to do everything in the function.)
I can't figure out why. Can someone please help me figure out why, or propose a fix?
This line:
return $argument unless $function = $functiontable{$function};
doesn't make sense. In your subroutine iterate, $function is a string and $functiontable{$function} is a reference to a subroutine. I am not sure what the purpose of this is: is it to compare against the stored function? is it to use the function referenced by the name $function?
Assuming the latter it would make more sense to simply pass in a reference to a function when you call iterate:
sub iterate {
my ($function, $iterations, $argument) = #_;
return $argument unless 0 < $iterations;
my #functioned = $function->($argument);
my #refunctioned = ();
for my $i (0 .. #functioned - 1) {
push #refunctioned, iterate ($function, ($iterations - 1), $functioned[$i]);
}
return uniq #refunctioned;
}
my #results = iterate($functiontable{foo}, 2, 'the');
print "#results";
output:
the the. the, the.. the., the,. the,,
The problem is this line.
return $argument unless $function = $functiontable{$function};
The variable $function is being repurposed and overwritten from a string (the function name) to a code reference (the function to be executed). Later, it's passed into iterate which faithfully ignores it.
Two things would improve this code and avoid that sort of problem. First is to not repurpose variables, use two variables.
return $argument unless $function_ref = $functiontable{$function_name};
Now the mistake cannot happen. One strong indicator that you're repurposing a variable is that it changes type, like from a string to a code reference.
Note that I threw out $function entirely because it's too generic in this context. Is that the function's name or the function's reference? Neither one is obvious, so make it obvious.
Finally, iterate can be made more flexible by eliminating the function table entirely. Pass in the code reference directly. If you want a function table, write a wrapper.
sub select_iteration {
my($iteration_type, $iterations, $argument) = #_;
my $iteration_code = $iteration_types{$iteration_type};
return iterate($iteration_code, $iterations, $argument);
}
The first time your subroutine iterate is called it translates the subroutine name in $function from a name to a subroutine reference
So the first time iterate calls itself it is passing the subroutine reference, and the line
return $argument unless $function = $functiontable{$function};
will stringify the reference and attempt to find an element of the hash using a key something like CODE(0x23e0838)
Clearly that element doesn't exist, so your unless fails and $argument is returned immediately without continuing the recursion
Update
I would write something like this
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.0;
my %functions = ( foo => \&foo );
sub iterate {
my ($func, $arg, $depth) = #_;
return $arg unless $depth;
map {iterate($func, $_, $depth - 1); } $functions{$func}->($arg);
}
sub foo {
my ($arg) = #_;
map "$arg$_", '', '.', ',';
}
my #results = iterate('foo', 'the', 2);
say "#results";
output
the the. the, the. the.. the., the, the,. the,,

JSON giving unwanted row index number - Active Record - Codeigniter

I don't know why when I echo json_encode a query result set I get the number of the result row before each object. I just want to count the number of total rows returns and have them displayed only once in the beginning of the JSON string and then just the rows returns afterwards. I.e. using the following code:
//...active record query
$result = $this->db->get();
$data = array();
$count = 1;
foreach($result->result() as $row)
{
$data['count'] = $count;
$entry = array();
$entry['firstname'] = $row->first_name;
$entry['lastname'] = $row->last_name;
$entry['jobtitle'] = $row->title;
$entry['dept'] = $row->dept_name;
$entry['deptid'] = $row->dept_no;
if($row->emp_no == null)
{
$entry['ismanager'] = 0;
}
else
{
$entry['ismanager'] = 1;
}
$data[] = $entry;
$count++;
}
return $data;
and then json_encode it in the controller, I get:
{"count":35,"0":{"firstname":"Georgi","lastname":"Facello","jobtitle":"Senior Engineer","dept":"Development","deptid":"d005","ismanager":0},"1":{"firstname":"Kirk","lastname":"Facello","jobtitle":"Senior Engineer","dept":"Development","deptid":"d005","ismanager":0},....rest of the query results
What I don't want is the "0" and "1" etc, before the row results. I already have the total count of the returned results so I don't need the individual row numbers.
If someone could kindly help me out I would appreciate it, thanks.
If you try to serialize an array as JSON, it would become something like this:
[elem1, elem2, elem3, ...]
But if that "array" have other fields then it will be serialized as an object:
{"field":value, "0":elem1, "1":elem2, "2":elem3, ...}
Since there's no way to serialize field using the array syntax, and json_encode can not simply discard it, then it uses the object syntax. As stated in the docs:
Note:
When encoding an array, if the keys are not a continuous numeric sequence starting from 0, all keys are encoded as strings, and specified explicitly for each key-value pair.
A possible workaround for this would be separating the count from the list of elements:
$data = array();
$list = array();
$data['list'] = list;
$count = 1;
foreach($result->result() as $row)
{
$data['count'] = $count;
$entry = array();
...
$list[] = $entry;
$count++;
}
That would serialize to something like:
{"count":35,"list":[{"firstname":"Georgi","lastname":"Facello","jobtitle":"Senior Engineer","dept":"Development","deptid":"d005","ismanager":0},{"firstname":"Kirk","lastname":"Facello","jobtitle":"Senior Engineer","dept":"Development","deptid":"d005","ismanager":0},....rest of the query results]}
It looks like you might be using JSON_FORCE_OBJECT on your json_encode which will always make your numerical index show up as a property. You should show your json_encode step in your question.
If you turn option off and go with a default encoding, you will still need to nest your numerically indexed array in its own property or the numerical indexes will show up as properties in order to make valid JSON. For perhaps do something like this when assigning your rows to the object:
$data['records'][] = $entry;