Nativescript application-setting module: setString('attribute_name', default value) do not return default value after remove('attribute_name') - nativescript

I noticed this anomaly working with application-settings module on a
nativescript (8.1.2) /angular project.
Having this code:
import { getString} from '#nativescript/core/application-settings';
remove("attribute_name_string")
let attribute_name_string = getString("attribute_name_string","DEFAULT VALUE")
console.log("Print My Local Atribute = " + attribute_name_string)
I was expected the result to be:
Print My Local Atribute = DEFAULT VALUE
but it was
Print My Local Atribute =
The same for setNumber
import { setNumber} from '#nativescript/core/application-settings';
remove("attribute_name_number")
let attribute_name_number = getNumber("attribute_name_number", 121)
console.log("Print My Local Atribute Number = " + attribute_name_number)
I was expected the result to be:
Print My Local Atribute Number = 121
but it was
Print My Local Atribute Number = 0
Two questions here:
Why this strange behaviour (anomaly)?
How can I clear my variables and get the default value afterwards ?
Please take in consideration the official documentation:
A default value can be provided in case there is no existing value.
/**
* Gets a value (if existing) for a key as a String Object.
A default value can be provided in case there is no existing value.
* #param key The key to check for.
* #param defaultValue An optional value to be returned in case there is no existing value.
*/
export function getString(key: string, defaultValue?: string): string;
and
/**
* Removes a value (if existing) for a key.
* #param key The key to check for.
*/
export function remove(key: string): void;

Related

Office.SeriesTime TypeScript definition is missing the Properties only has Methods

Office.context.mailbox.item.recurrence.getAsync() returns an object but I'm unable to cast parts of it to other variables.
e.g. interface Office.SeriesTime only defines the GetXXX() methods
/**
* Gets the duration in minutes of a usual instance in a recurring appointment series.
*
* [Api set: Mailbox 1.7]
*
* #remarks
*
* **{#link https://learn.microsoft.com/office/dev/add-ins/outlook/understanding-outlook-add-in-permissions | Minimum permission level}**: `ReadItem`
*
* **{#link https://learn.microsoft.com/office/dev/add-ins/outlook/outlook-add-ins-overview#extension-points | Applicable Outlook mode}**: Compose or Read
*/
getDuration(): number;
e.g. This won't compile because interface Office.SeriesTime does not define the properties.
const fixedRecurrence: Office.SeriesTime = recurrence.seriesTime;
if (fixedRecurrence.endYear === 0) {
fixedRecurrence.endYear = fixedEndDate.getFullYear();
fixedRecurrence.endMonth = fixedEndDate.getMonth() + 1;
fixedRecurrence.endDay = fixedEndDate.getDate();
}
See the Office.SeriesTime interface members. It seems you need to use the getEndDate() method instead which allows to get the end date of a recurrence pattern in the following ISO 8601 date format: "YYYY-MM-DD".
// This example gets the end date of a recurring appointment series.
Office.context.mailbox.item.recurrence.getAsync(callback);
function callback(asyncResult) {
var context = asyncResult.context;
var recurrence = asyncResult.value;
var endDate = recurrence.seriesTime.getEndDate();
}

Jersey, #QueryParam List<String>

I want to take a list as a parameter, but the value of the list does not correspond to java version list. For example #QueryParam("orderBy") List orderBy)
This list has the value of [age, name] as an element.
Is it possible to have the value separately. Like 1st element age and 2nd element name.
`
#GET
#Path("/range")
#Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public Response searchForActivitiesWithRange(#QueryParam(value = "description")List<String> descriptions,
#QueryParam(value = "durationFrom") int durationFrom,
#QueryParam(value = "durationTo") int durationTo) {
List<Activity> activities = activityRepository.findByDescriptionandDuration(descriptions,durationFrom,durationTo);
if (activities == null || activities.size() == 0) {
return Response.status(Status.NOT_FOUND).build();
}
return Response.ok().entity(new GenericEntity<List<Activity>>(activities){}).build();
}`
Not automatically. Every query param is read by jersey as a String and, after, it tries to convert in the data type of the parameter you specified.
You have to split the param String or,client side, send multiple param with the same name and read them like a MultivaluedMap, in which the key is the param name and the value a list with all values.
Use objects. You can create an ActivitiesRequest class and then define your variables in the class. You can also do that for your response.

Laravel Eloquent - Update Enum type

I have an enum column in my table Schedule. I want to be update the column, but I cannot. My type consists of 3 options: common, template, revision.
This does NOT work. The process goes through fine, but the type does not change:
$schedule = Schedule::find($id);
$schedule->type = 'common';
$scehdule->save();
return $schedule;
But this DOES work:
$schedule = Schedule::find($id);
$schedule->fill(['type' => 'common']);
$scehdule->save();
return $schedule;
This also works:
$schedule = Schedule::find($id);
unset($schedule->type);
$schedule->type = 'common';
$scehdule->save();
return $schedule;
Problem is that I have validators that need to be satisfied if I were to use fill(). I only want to change one column, so I'd like to use the first approach.
Could someone advice?
I ran into the same problem with Laravel 5.3. When you are using an enum in the database you can set the enum by using an integer. 1 = common, 2 = template, 3 = revision.
$schedule = Schedule::find($id);
$schedule->type = 1;
$scehdule->save();
return $schedule;
This will set the schedule type to "common"

TYPO3: Calculate Cache identifier hash value?

In TYPO3 I want to remove a single page from the cache table with some GET values. I haven't found an extension, that will handle that or a TYPO3 method.
Is there a function, that I can hand over a URL or similar, that produces the cache hash identifier or removes the specific data from the caching tables?
If not, does anybody know, what the algorithm is, that calculates the hash identifier or in which file I might find it?
So any help will be appreciated.
My TYPO3 version: 4.5.x
You can create a function which clear the cache of a specified page, following code is needed:
TYPO3 6.0
public function clearCache($cacheCmd) {
/** #var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */
$tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance("TYPO3\\CMS\\Core\\DataHandling\\DataHandler");
$tce->stripslashes_values = 0;
$tce->start(array(), array());
switch($cacheCmd) {
case 'pages':
case 'all':
$tce->admin = 1;
}
$tce->clear_cacheCmd($cacheCmd);
unset($tce);
}
TYPO3 4.x
public function clearCache($cacheCmd) {
/** #var $tce t3lib_TCEmain */
$tce = t3lib_div::makeInstance("t3lib_TCEmain");
$tce->stripslashes_values = 0;
$tce->start(array(), array());
switch($cacheCmd) {
case 'pages':
case 'all':
$tce->admin = 1;
}
$tce->clear_cacheCmd($cacheCmd);
unset($tce);
}
And $cacheCmd can have following values:
/typo3/sysext/core/Classes/DataHandling/DataHandler.php:clear_cacheCmd (> 6.0) or /t3lib/class.t3lib_tcemain.php (4.x)
/**
* Clears the cache based on the command $cacheCmd.
*
* $cacheCmd='pages': Clears cache for all pages. Requires admin-flag to
* be set for BE_USER.
*
* $cacheCmd='all': Clears all cache_tables. This is necessary if
* templates are updated. Requires admin-flag to be set for BE_USER.
*
* $cacheCmd=[integer]: Clears cache for the page pointed to by $cacheCmd
* (an integer).
*
* $cacheCmd='cacheTag:[string]': Flush page and pagesection cache by given tag
*
* $cacheCmd='cacheId:[string]': Removes cache identifier from page and page section cache
*
* Can call a list of post processing functions as defined in
* $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc']
* (numeric array with values being the function references, called by
* \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction()).
*
* Note: The following cache_* are intentionally not cleared by
* $cacheCmd='all':
*
* - cache_md5params: RDCT redirects.
* - cache_imagesizes: Clearing this table would cause a lot of unneeded
* Imagemagick calls because the size informations have
* to be fetched again after clearing.
*
* #param string $cacheCmd The cache command, see above description
* #return void
*/
Call this with a userFunc if a given parameter is set in typoscript or create a simple extension by your own.
It's like this:
You need a proper TSFE object $GLOBALS['TSFE']
then you need the encryption key from the localconf $TYPO3_CONF_VARS['SYS']['encryptionKey']
and the URL parameters e.g. `tx_ttnews[tt_news]
then these steps
create an (sorted) array with the encryption key and the url parameters
Hand over this array to the property cHash_array of the TSFE object
Get the cHash value from the TSFE's getHash method
$arr = array(
'encryptionKey' => $TYPO3_CONF_VARS['SYS']['encryptionKey'],
'tx_ttnews[tt_news]' => $newsid,
// ...
)
ksort($array);
$GLOBALS['TSFE']->cHash_array = $array;
$chash = $GLOBALS['TSFE']->getHash();

How do I set a parameter to a list of values in a BIRT report?

I have a DataSet with a query like this:
select s.name, w.week_ending, w.sales
from store s, weekly_sales_summary w
where s.id=w.store_id and s.id = ?
I would like to modify the query to allow me to specify a list of store IDs, like:
select s.name, w.week_ending, w.sales
from store s, weekly_sales_summary w
where s.id=w.store_id and s.id IN (?)
How do I accomplish this in BIRT? What kind of parameter do I need to specify?
The easy part is the report parameter: set the display type to be List Box, then check the Allow Multiple Values option.
Now the hard part: unfortunately, you can't bind a multi-value report parameter to a dataset parameter (at least, not in version 3.2, which is what I'm using). There's a posting on the BIRT World blog here:
http://birtworld.blogspot.com/2009/03/birt-multi-select-statements.html
that describes how to use a code plug-in to bind multi-select report parameters to a report dataset.
Unfortunately, when I tried it, it didn't work. If you can get it to work, that's the method I would recommend; if you can't, then the alternative would be to modify the dataset's queryText, to insert all the values from the report parameter into the query at the appropriate point. Assuming s.id is numeric, here's a function that can be pasted into the beforeOpen event script for the datasource:
function fnMultiValParamSql ( pmParameterName, pmSubstituteString, pmQueryText )
{
strParamValsSelected=reportContext.getParameterValue(pmParameterName);
strSelectedValues="";
for (var varCounter=0;varCounter<strParamValsSelected.length;varCounter++)
{
strSelectedValues += strParamValsSelected[varCounter].toString()+",";
}
strSelectedValues = strSelectedValues.substring(0,strSelectedValues.length-1);
return pmQueryText.replace(pmSubstituteString,strSelectedValues);
}
which can then be called from the beforeOpen event script for the dataset, like this:
this.queryText = fnMultiValParamSql ( "rpID", "0 /*rpID*/", this.queryText );
assuming that your report parameter is called rpID. You will need to amend your query to look like this:
select s.name, w.week_ending, w.sales
from store s, weekly_sales_summary w
where s.id=w.store_id and s.id IN (0 /*rpID*/)
The 0 is included in the script so that the query script is valid at design time, and the dataset values will bind correctly to the report; at runtime, this hard-coded 0 will be removed.
However, this approach is potentially very dangerous, as it could make you vulnerable to SQL Injection attacks: http://en.wikipedia.org/wiki/SQL_injection , as demonstrated here: http://xkcd.com/327/ .
In the case of purely numeric values selected from a predefined picklist, a SQL injection attack should not be possible; however, the same approach is vulnerable where freeform entry strings for the parameter are allowed.
FYI: the BIRT World article should work (I wrote it) but that was an earlier solution to the problem.
We have created an open source plugin that you can add to BIRT that has a much cleaner solution to this problem. The Bind Parameters function in the birt-functions-lib provides a simple way to do multi-selects from multi-value parameters.
If you are still interested have a look at the birt-functions-lib project on Eclipse Labs.
Here's another one. Based on some hints I found elsewhere and extended to preserve the number of parameters in your data set SQL. This solution works with a JavaScript function that you call at OnBeforeOpen of the data set:
prepare(this);
function prepare(dataSet) {
while (dataSet.queryText.indexOf("#IN?")>=0) {
dataSet.queryText = dataSet.queryText.replace(
"#XYZ?",
"('"+params["products"].value.join("','")+"') or ?=0"
);
}
}
In your query, replace occurrences of (?) with #XYZ?. The method above makes sure that
the query has the actual values and still a parameter (so that the dataset editor and preview doesn't complain).
Note: Beware of SQL injection, e.g. by not allowing string values
I created a more general solution, which handles optional/required parameters behaviour too. When parameter is not required and user doesn't select any value, the IN-clause gets disabled. It also allows the user to select both real values and null value.
In report initialize script I add this code:
/** Fullfill IN-clause in a data set query,
* using a List box report parameter.
* Placeholder must be the parentheses after IN keyword with wathever you want inside.
* If required is false then the whole IN-clause in the query
* must be surrounded by parentheses.
* dataType and required refers to the parameter, they must be passed,
* but should be better to find a way to retrieve them inside this function
* (given parameter name).
*/
function fulfillInClause(dataSet, placeholder, param, dataType, required) {
if (dataSet.queryText.indexOf(placeholder)>=0) {
var paramValue = params[param].value;
var emptyParam = (paramValue==null || paramValue.length<=0);
//build the list of possible values
// paramValue==null check in ternary operators
// will prevent exceptions when user doesn't select any value
// (it will not affect the query if param is optional,
// while we will never arrive here if it is required)
var replacement = " (";
if (dataType == "string")
replacement += (emptyParam ? "''" : createList(paramValue, ",", "'", "varchar(10)") );
else if (dataType == "integer")
replacement += (emptyParam ? "0" : createList(paramValue, ",", "" , "int" ) );
else
//TODO implement more cases
return;
replacement += ") ";
//if param is not required and user doesn't select any value for it
//then nullify the IN clause with an always-true clause
if (!required && emptyParam)
replacement += " or 0=0 ";
//put replacement in the query
dataSet.queryText = dataSet.queryText.replace( placeholder, replacement );
//DEBUG
params["debug" + dataSet.name + "Query"]=dataSet.queryText;
}
}
/** Create a string list of array values,
* separated by separator and each of them surrounded by a pair surrounders
*/
function createList(array, separator, surrounder, sqlDataType){
var result = "";
for(var i=0; i<array.length; i++) {
if(result.length>0)
result += separator;
if(array[i]!=null)
result += surrounder + array[i] + surrounder;
else
result += "cast(null as " + sqlDataType + ")";
}
return result;
}
Usage example
In dataset query put your special IN-clause:
select F1, F2
from T1
where F3='Bubi'
and ( F4 in (''/*?customers*/) )
In beforeOpen script of the dataset with the IN-clause write:
fulfillInClause(this, "(''/*?customers*/)", "customers", "string", false);
Note that I used a placeholder which allows the query to run also before the replacement (eg. it has quotes as F4 is a varchar). You can build a placeholder that fits your case.

Resources