So I only want to get items from userSubscriptionLevel WHERE the id is anything but 4 or 6. What's the best way to give this exclusions?
function getUserLevelMapping() {
global $mysqli;
$userLevels = $mysqli->get('userSubscriptionLevel');
$userLevelMapping = array();
foreach($userLevels as $userLevel) {
$userLevelMapping[$userLevel['code']] = $userLevel['id'] ;
}
return $userLevelMapping;
}
Look at IN and NOT IN - both super useful methods for looking for (or excluding) specific records.
In your case, a NOT IN query is what you want, and it would look like so:
Select ... WHERE userSubscriptionLevel NOT IN(4, 6)
(query all records excluding userSubscriptionLevel that is 4 or 6)
Related
Below is the code written by my collegue who doesnt work in the firm anymore. I am inserting records in object with data loader and I can see success message but I do not see any records in my object. I am not able to understand what below trigger is doing.Please someone help me understand as I am new to salesforce.
trigger DataLoggingTrigger on QMBDataLogging__c (after insert) {
Map<string,Schema.RecordTypeInfo> recordTypeInfo = Schema.SObjectType.QMB_Initial_Letter__c.getRecordTypeInfosByName();
List<QMBDataLogging__c> logList = (List<QMBDataLogging__c>)Trigger.new;
List<Sobject> sobjList = (List<Sobject>)Type.forName('List<'+'QMB_Initial_Letter__c'+'>').newInstance();
Map<string, QMBLetteTypeToVfPage__c> QMBLetteTypeToVfPage = QMBLetteTypeToVfPage__c.getAll();
Map<String,QMBLetteTypeToVfPage__c> mapofLetterTypeRec = new Map<String,QMBLetteTypeToVfPage__c>();
set<Id>processdIds = new set<Id>();
for(string key : QMBLetteTypeToVfPage.keyset())
{
if(!mapofLetterTypeRec.containsKey(key)) mapofLetterTypeRec.put(QMBLetteTypeToVfPage.get(Key).Letter_Type__c, QMBLetteTypeToVfPage.get(Key));
}
for(QMBDataLogging__c log : logList)
{
Sobject logRecord = (sobject)log;
Sobject QMBLetterRecord = new QMB_Initial_Letter__c();
if(mapofLetterTypeRec.containskey(log.Field1__c))
{
string recordTypeId = recordTypeInfo.get(mapofLetterTypeRec.get(log.Field1__c).RecordType__c).isAvailable() ? recordTypeInfo.get(mapofLetterTypeRec.get(log.Field1__c).RecordType__c).getRecordTypeId() : recordTypeInfo.get('Master').getRecordTypeId();
string fieldApiNames = mapofLetterTypeRec.containskey(log.Field1__c) ? mapofLetterTypeRec.get(log.Field1__c).FieldAPINames__c : '';
//QMBLetterRecord.put('Letter_Type__c',log.Name);
QMBLetterRecord.put('RecordTypeId',tgh);
processdIds.add(log.Id);
if(string.isNotBlank(fieldApiNames) && fieldApiNames.contains(','))
{
Integer i = 1;
for(string fieldApiName : fieldApiNames.split(','))
{
string logFieldApiName = 'Field'+i+'__c';
fieldApiName = fieldApiName.trim();
system.debug('fieldApiName=='+fieldApiName);
Schema.DisplayType fielddataType = getFieldType('QMB_Initial_Letter__c',fieldApiName);
if(fielddataType == Schema.DisplayType.Date)
{
Date dateValue = Date.parse(string.valueof(logRecord.get(logFieldApiName)));
QMBLetterRecord.put(fieldApiName,dateValue);
}
else if(fielddataType == Schema.DisplayType.DOUBLE)
{
string value = (string)logRecord.get(logFieldApiName);
Double dec = Double.valueOf(value.replace(',',''));
QMBLetterRecord.put(fieldApiName,dec);
}
else if(fielddataType == Schema.DisplayType.CURRENCY)
{
Decimal decimalValue = Decimal.valueOf((string)logRecord.get(logFieldApiName));
QMBLetterRecord.put(fieldApiName,decimalValue);
}
else if(fielddataType == Schema.DisplayType.INTEGER)
{
string value = (string)logRecord.get(logFieldApiName);
Integer integerValue = Integer.valueOf(value.replace(',',''));
QMBLetterRecord.put(fieldApiName,integerValue);
}
else if(fielddataType == Schema.DisplayType.DATETIME)
{
DateTime dateTimeValue = DateTime.valueOf(logRecord.get(logFieldApiName));
QMBLetterRecord.put(fieldApiName,dateTimeValue);
}
else
{
QMBLetterRecord.put(fieldApiName,logRecord.get(logFieldApiName));
}
i++;
}
}
}
sobjList.add(QMBLetterRecord);
}
if(!sobjList.isEmpty())
{
insert sobjList;
if(!processdIds.isEmpty()) DeleteDoAsLoggingRecords.deleteTheProcessRecords(processdIds);
}
Public static Schema.DisplayType getFieldType(string objectName,string fieldName)
{
SObjectType r = ((SObject)(Type.forName('Schema.'+objectName).newInstance())).getSObjectType();
DescribeSObjectResult d = r.getDescribe();
return(d.fields.getMap().get(fieldName).getDescribe().getType());
}
}
You might be looking in the wrong place. Check if there's an unit test written for this thing (there should be one, especially if it's deployed to production), it should help you understand how it's supposed to be used.
You're inserting records of QMBDataLogging__c but then it seems they're immediately deleted in DeleteDoAsLoggingRecords.deleteTheProcessRecords(processdIds). Whether whatever this thing was supposed to do succeeds or not.
This seems to be some poor man's CSV parser or generic "upload anything"... that takes data stored in QMBDataLogging__c and creates QMB_Initial_Letter__c out of it.
QMBLetteTypeToVfPage__c.getAll() suggests you could go to Setup -> Custom Settings, try to find this thing and examine. Maybe it has some values in production but in your sandbox it's empty and that's why essentially nothing works? Or maybe some values that are there are outdated?
There's some comparison if what you upload into Field1__c can be matched to what's in that custom setting. I guess you load some kind of subtype of your QMB_Initial_Letter__c in there. Record Type name and list of fields to read from your log record is also fetched from custom setting based on that match.
Then this thing takes what you pasted, looks at the list of fields in from the custom setting and parses it.
Let's say the custom setting contains something like
Name = XYZ, FieldAPINames__c = 'Name,SomePicklist__c,SomeDate__c,IsActive__c'
This thing will look at first record you inserted, let's say you have the CSV like that
Field1__c,Field2__c,Field3__c,Field4__c
XYZ,Closed,2022-09-15,true
This thing will try to parse and map it so eventually you create record that a "normal" apex code would express as
new QMB_Initial_Letter__c(
Name = 'XYZ',
SomePicklist__c = 'Closed',
SomeDate__c = Date.parse('2022-09-15'),
IsActive__c = true
);
It's pretty fragile, as you probably already know. And because parsing CSV is an art - I expect it to absolutely crash and burn when text with commas in it shows up (some text,"text, with commas in it, should be quoted",more text).
In theory admin can change mapping in setup - but then they'd need to add new field anyway to the loaded file. Overcomplicated. I guess somebody did it to solve issue with Record Type Ids - but there are better ways to achieve that and still have normal CSV file with normal columns and strong type matching, not just chucking everything in as strings.
In theory this lets you have "jagged" csv files (row 1 having 5 fields, row 2 having different record type and 17 fields? no problem)
Your call whether it's salvageable or you'd rather ditch it and try normal loading of QMB_Initial_Letter__c records. (get back to your business people and ask for requirements?) If you do have variable number of columns at source - you'd need to standardise it or group the data so only 1 "type" of records (well, whatever's in that "Field1__c") goes into each file.
My question will seem quite simple, but I'm having a hard time understanding how certain queries work with ObjectBox and Flutter.
I have a List object. I would like to retrieve them all, but display only the first 5, sorted by ascending name.
I find many examples with filter queries in the documentation, but the getAll() does not allow to easily integrate the limit and I find very few examples. I think I'm doing it wrong. What is the best way to do this query ?
final boxListCoins = objectBoxDatabase.store.box<CoinsList>();
// final query = boxListCoins.getAll(); ?
final query = (boxListCoins.query()..order(CoinsList_.coinId, flags: Order.descending)).build();
query.limit = 5;
final coinsList = query.find();
I see that you want to get all your results but you want to display the first 5. So what I would do in your case is:
(1) get all your results(based on your query)
(2) then set another property equal to the top 5:)
** now you have a list of all your entries and you have your top 5 that you can display.
heres how I would code it up!
final boxListCoins = objectBoxDatabase.store.box<CoinsList>();
// final query = boxListCoins.getAll(); ?
final query = (boxListCoins.query()..order(CoinsList_.coinId, flags: Order.descending)).build();
// this is your list of all of the coins!
final coinsList = query.find();
// This is you list of the Top 5
var topFive = [];
if (coinsList.length >= 5) {
// take your top5 here :) also feel free to turn this iterable into what ever you want I just choose to keep it a list :)
topFive = coinsList.take(5).toList();
} else {
// if you length is not greater than 5 then you have your top automatically.
topFive = coinsList;
}
Hope this helps:)
Happy Coding, also I'm a developer #Pieces and if you need a place to store helpful code snippets, like this one, check it out here https://code.pieces.app/
I've got what seems to be a bug. I can add an entry to the database which has a single quote in the text.
However, when I search using QueryBuilder, for any text LIKE xyz, if xyz has a single quote in it, I get MySQL complaining about malformed SQL.
Other than parsing all strings myself, is there some method in Ormlite I can call to "santize" my strings?
Sample code is below:
public boolean isDuplicate () {
QueryBuilder<Company, Long> qb = getDao().queryBuilder() ;
Where<Company, Long> where = qb.where() ;
try {
if (Strings.isValid(name))
where.like("name", name) ;
if (Strings.isValid(regNo)) {
if (Strings.isValid(name))
where.or() ;
where.eq("regNo", regNo) ;
List<Company> res = where.query() ;
if (res != null && res.size() > 0)
return true ;
else
return false ;
}
} catch (SQLException e) {
GlobalConfig.log(e, true);
}
return false ;
}
This creates a SQL error if the company name has a single quote in it:
Creating default entries for Well Don't Delete Me 2 Please Pte Ltd.
[12-07-2013 13:45:42] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't Delete Me 2 Please Pte Ltd.' OR regNo = 'delete' )' at line 1
Any suggestions welcome.
Ok, I figured this out- I need to use the SelectArg method of querying the database.
So it now looks like this:
...
if (Strings.isValid(name))
{
SelectArg arg = new SelectArg () ; // Added
arg.setValue (name) ; / Added
where.like("name", arg) ; // Changed
}
if (Strings.isValid(regNo))
{
if (Strings.isValid(name))
where.or() ;
SelectArg arg = new SelectArg () ; // Added
arg.setValue (regNo) ; // Added
where.eq("regNo", arg) ; // Changed
List<Company> res = where.query() ;
if (res != null && res.size() > 0)
return true ;
else
return false ;
...
What I've learned is this: you must use one SelectArg PER item.
Now my question to Gray is why not make this a default behaviour? When I insert or update it seems to happen automatically, and to get the problem I found solved I have to add more
lines of code that could easily be part of the internal query handling.
I understand his concerns in this post but I agree with Dale. Maybe a halfway house is to have a flag to say which way Ormlite should treat parameters to the query methods.
I admire the flexibility and simplicity of the "programmable" SQL in Ormlite and in almost every case, Ormlite related code is concise, easy to follow and logical. This is one rare case where I feel it is more verbose than necessary, for no net benefit. Just my opinion.
I'm using ZendFramework 2 and TableGateway which is fine for normal select statements. But I can't seem to find how to get a max of a column using ZendFramework 2 select.
My select should look something like
SELECT MAX( `publication_nr` ) AS maxPubNr FROM `publications`
and my code looks like:
use Zend\Db\TableGateway\TableGateway;
class PublicationsTable
{
protected $tableGateway;
...
public function getMaxPubicationNr()
{
$rowset = $this->tableGateway->select(array('maxPubNr' => new Expression('MAX(publication_nr)')));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not retrieve max Publication nr");
}
return $row;
}
If you look at the TableGateway you will notice the parameters for the Select method are actually passed to the Where part of the Query, which is making your query incorrect.
You need to modify the Select Object directly as the TableGateway won't give you any proxy methods to do this.
You could try something like this:
public function getMaxPubicationNr()
{
$select = $this->tableGateway->getSql()->select();
$select->columns(array(
'maxPubNr' => new Expression('MAX(publication_nr)')
));
// If you need to add any where caluses you would need to do it here
//$select->where(array());
$rowset = $this->tableGateway->selectWith($select);
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not retrieve max Publication nr");
}
return $row;
}
I've not tested it, but that should just about get you there :)
You will probably bump into another issue though, and that will be due to the TableGateway trying to build you an object from the result, but you aren't bringing back a full row to build an object, you're just bringing back a single Column.
I would just add use the Db/Select objects to do this and not bother with the GateWay to be honest, I don't think it's supposed to be used like this.
I am using Zend Lucene Search:
......
$results = $test->fetchAll();
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');
Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());
foreach ($results as $result) {
$doc = new Zend_Search_Lucene_Document();
// add Fields
$doc->addField(
Zend_Search_Lucene_Field::Text('testid', $result->id));
$doc->addField(
Zend_Search_Lucene_Field::Keyword('testemail', strtolower(($result->email))));
$doc->addField(
Zend_Search_Lucene_Field::Text('testconfirmdate', $result->confirmdate));
$doc->addField(
Zend_Search_Lucene_Field::Text('testcreateddate', $result->createddate));
// Add document to the index
$index->addDocument($doc);
}
// Optimize index.
$index->optimize();
// Search by query
setlocale(LC_CTYPE, 'de_DE.iso-8859-1');
if(strlen($Data['name']) > 2){
//$query = Zend_Search_Lucene_Search_QueryParser::parse($Data['name'].'*');
$pattern = new Zend_Search_Lucene_Index_Term($Data['name'].'*');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$this->view->hits = $index->find(strtolower($query));
}
else{
$query = $Data['name'];
$this->view->hits = $index->find($query);
}
............
Works fine here:
It works when I give complete word, first 3 character, case insensitive words
My issues are:
When I search for email, i got error like "Wildcard search is supported only for non-multiple word terms "
When I search for number/date like "1234" or 09/06/2011, I got error like "At least 3 non-wildcard characters are required at the beginning of pattern"
I want to search date, email, number here.
In file zend/search/Lucene/search/search/query/wildcard a parameter is set,
private static $_minPrefixLength = 3;
chnage it and it may work..!
Based on NaanuManu's suggestion, I did a little more digging to figure this out - I posted my answer on a related question here, but repeating for convenience:
Taken directly from the Zend Reference documentation, you can use:
Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() to
query the minimum required prefix length and
use Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength() to
set it.
So my suggestion would be either of two things:
Set the prefixMinLength to 0 using Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength(0)
Validate all search queries using javascript or otherwise to ensure there is a minimum of Zend_Search_Lucene_Search_Query_Wildcard::getMinPrefixLength() before any wildcards used (I recommend querying that instead of assuming the default of "3" so the validation is flexible)