coldfusion 9, params not found when using cfscript query - coldfusion-9

I am getting this error:
Parameter 'user_id AND league_id' not found in the list of parameters specified
I am passing them in, and I can see them in a dump placed inside the function.
here's whats going in...
ac = {
league_id = 1
,user_id = 3
,score1 = 14
,score2 = 10
};
this is the dump that is throwing the error....
writedump( Game.saveGame( argumentcollection = ac ) );
Here is the Game.saveGame function
public any function saveGame( required numeric league_id, required numeric user_id, required numeric score1, required numeric score2 ) {
// writeDump( var=arguments ); // this dump shows league_id & user_id...
var sql = '';
var tmp = '';
var r = '';
var q = new query();
q.setDatasource( this.dsn );
q.addParam(
name = 'league_id'
,value = '#val( arguments.league_id )#'
,cfsqltype = 'CF_SQL_BIGINT'
);
q.addParam(
name = 'user_id'
,value = '#val( arguments.user_id )#'
,cfsqltype = 'CF_SQL_BIGINT'
);
q.addParam(
name = 'score1'
,value = '#val( arguments.score1 )#'
,cfsqltype = 'CF_SQL_SMALLINT'
);
q.addParam(
name = 'score2'
,value = '#val( arguments.score2 )#'
,cfsqltype = 'CF_SQL_SMALLINT'
);
sql = 'INSERT INTO
games
(
user_id
,league_id
,score1
,score2
)
VALUES
(
:user_id
,:league_id
,:score1
,:score2
)
';
tmp = q.execute( sql = sql );
r = tmp.getPrefix( q );
q.clearParams();
return r;
}
Here is some history of the issue -
I am writing this locally and my system is running CF 11.2 - everything works fine... However, I had to host it on a CF 9.02 server, and that is when this error showed up - I cannot recreate it on my system although, I do recall seeing this error before, but for the life of me I cant find how I solved it then....
Any help or insight is appreciated.
Other params
Windows server, MySQL 5.5, Apache 2.2

Adam Wrote:
I can't spot what's wrong with your code, but you could perhaps clean
things up a bit. There's no need to set each "property" on the query
separately: blog.adamcameron.me/2014/01/
Following the ordinal param, instead of the named param, AND passing in the array of params in the condensed format, has solved my issue.
I may play with the name attribute and see if it is that, precisely.. or I may just deal with this as a solution.
Now, to change all my script queries!!!!!
(I wish his article came up on google, when I was looking into the query.cfc syntax. :(
Thanks a bunch Adam!

Related

ATG - How to override RQL for insert statements

I need to insert records to an Oracle DB table that already has records in it by using the table's sequence.
I tried using RQL which creates an auto-generated id for the primary key but sometimes those generated ids already exist in the database and as a result, a constraint violation error is thrown.
ATG documentation provides an alternative named Overriding RQL-Generated SQL but I didn't manage to make it work for insert statements.
GSARepository repo =
(GSARepository)request.resolveName("/examples/TestRepository");
RepositoryView view = repo.getView("canard");
Object params[] = new Object[4];
params[0] = new Integer (25);
params[1] = new Integer (75);
params[2] = "french";
params[3] = "greek";
Builder builder = (Builder)view.getQueryBuilder();
String str = "SELECT * FROM usr_tbl WHERE (age_col > 0 AND age_col < 1
AND EXISTS (SELECT * from subjects_tbl where id = usr_tbl.id AND subject
IN (2, 3)))";
RepositoryItem[] items =
view.executeQuery (builder.createSqlPassthroughQuery(str, params));
Is there any way to use table's sequence for insert statements via ATG Repository API?
Eventually, I did not manage to make it work but I found the following solution.
I retrieved the sequence number as below and then used it in the RQL insert statement.
RepositoryView view = getRestServiceDetailsRepository().getView("wsLog");
String sql = "select log_seq.nextval from dual";
Object[] params = {};
Builder builder = (Builder) view.getQueryBuilder();
Query query = builder.createSqlPassthroughQuery(sql, params);
RepositoryItem[] items = view.executeQuery(query);
if (items != null && items.length > 0) {
items[0].getRepositoryId();
}

Call dynamic method without naming parameters

I'm calling a method of a class dynamically like this, and it works:
CALL METHOD (gc_zcl_mapping_methods)=>(<ls_import_params>-attr_logic_method)
EXPORTING
iv_dats = <lv_value>
RECEIVING
rv_timestamp = <ls_import_params>-attr_value.
The problem is that I'm naming the two parameters iv_dats and rv_timestamp.
Not every method has these parameter names so I'm looking for a way to call them without naming the parameters.
I tried like this, but I get many syntax errors.
<ls_import_params>-attr_value = (gc_zcl_mapping_methods)=>(<ls_import_params>-attr_logic_method)(<lv_value>).
Is there a correct syntax for my goal to omit the parameter names?
Unfortunately, you have to name the returning parameter and other parameters too.
The full dynamic calling is explained here in the ABAP documentation
For your example code, that will give this code :
DATA(ptab) = VALUE abap_parmbind_tab(
( name = 'IV_DATS'
kind = cl_abap_objectdescr=>exporting
value = REF #( <lv_value> ) )
( name = 'RV_TIMESTAMP'
kind = cl_abap_objectdescr=>receiving
value = REF #( <ls_import_params>-attr_value ) ) ).
DATA(etab) = VALUE abap_excpbind_tab( ).
CALL METHOD (gc_zcl_mapping_methods)=>(<ls_import_params>-attr_logic_method)
PARAMETER-TABLE ptab
EXCEPTION-TABLE etab.
You may get the name of the returning parameter by using RTTI (here, I suppose that the class is global), you may also adapt it to get other parameter names:
DATA(rtti_class) = CAST cl_abap_objectdescr(
cl_abap_typedescr=>describe_by_name( '\CLASS=' && gc_zcl_mapping_methods ) ).
DATA(method) = rtti_class->methods[ name = <ls_import_params>-attr_logic_method ].
DATA(returning_parameter) = method-parameters[ parm_kind = cl_abap_objectdescr=>returning ].
DATA(returning_parameter_name) = returning_parameter-name.
I let you add the handling of exceptions.
ADDENDUM : Minimal, Complete, and Verifiable Example :
Let's say this static call is to be done dynamically :
DATA(result) = VALUE sychar01( ).
DATA(ltxttab) = VALUE rslinltab( ( kind = 'E' numb = 1 param = 'MSGID' value = 'MESSAGEGY9' )
( kind = 'E' numb = 1 param = 'PRAGMA' value = '##DUMMY' ) ).
cl_abap_syntax_message=>long_text_exists(
EXPORTING
p_kind = 'E'
p_number = 1
p_ltxttab = ltxttab
RECEIVING
p_result = result
EXCEPTIONS
message_not_found = 1 ).
Dynamic version (also, the RECEIVING parameter is being determined dynamically at runtime, but usually it's not needed because its name is known at compile time) :
DATA(rtti_class) = CAST cl_abap_objectdescr(
cl_abap_typedescr=>describe_by_name( '\CLASS=' && 'CL_ABAP_SYNTAX_MESSAGE' ) ).
DATA(method) = rtti_class->methods[ name = 'LONG_TEXT_EXISTS' ].
DATA(returning_parameter) = method-parameters[ parm_kind = cl_abap_objectdescr=>returning ].
DATA(returning_parameter_name) = returning_parameter-name.
ASSERT returning_parameter_name = 'P_RESULT'. " <=== just for the demo
DATA(ptab) = VALUE abap_parmbind_tab(
( name = 'P_KIND'
kind = cl_abap_objectdescr=>exporting
value = REF #( 'E' ) )
( name = 'P_NUMBER'
kind = cl_abap_objectdescr=>exporting
value = REF #( 1 ) )
( name = 'P_LTXTTAB'
kind = cl_abap_objectdescr=>exporting
value = REF #( ltxttab ) )
( name = returning_parameter_name
kind = cl_abap_objectdescr=>receiving
value = REF #( result ) ) ).
DATA(etab) = VALUE abap_excpbind_tab(
( name = 'MESSAGE_NOT_FOUND' value = 1 ) ).
CALL METHOD ('CL_ABAP_SYNTAX_MESSAGE')=>('LONG_TEXT_EXISTS')
PARAMETER-TABLE ptab
EXCEPTION-TABLE etab.

LINQ - query Where method error

I have the following code that I cannot make it work.
I am new using Linq and Entity framework.
I attach the code sample, and also, and image with the error.
What I am trying to do, is a piece of code where I can add "Where"s dynamically.
Imports System.Linq
Private cntx As New attmanager_bdEntities()
Dim query = (From persona In cntx.tblperson
Select
ATT_TYPE = persona.att_type,
ATT_RECOG = persona.att_recog,
APELLIDO = persona.surname,
NOMBRE = persona.name,
PERSONA_ID = persona.id,
DNI = persona.identification,
DIRECCION = persona.address,
PIN = persona.att_pin,
TIPOASISTENCIA = persona.att_type,
EMAIL = persona.email,
EXTRA = persona.extra,
TELEFONO = persona.phone,
FECHANACIMIENTO = persona.birth,
SEXO = persona.sex,
DELETED = persona.deleted,
AREA_ID = persona.tblarea.id,
AREA = persona.tblarea.name,
CIUDAD = persona.tblcity.name,
CIUDAD_ID = persona.tblcity_id,
PROVINCIA = persona.tblcity.tblstate.name,
PAIS = persona.tblcity.tblstate.tblcountry.name
Where (DELETED = 0))
query = query.Where(Function(a) a.AREA_ID = 1)
'Here I should put another "Where"s
dbgrid_listado.DataSource = query.ToList()
Error translation:
Unexpected exception trying to load "personas"
Details:
Could not invoke the method because could not call a 'Public Function Where ..........
......
......
......
...... with those arguments.
The parameter 'predicate' of the argument could not be converted to VB$AnonymousDelegate_0(Of Object,Object)' into 'String'
Why not this?
Dim query = (From persona In cntx.tblperson
Where persona.DELETED = 0
Select persona)
Now your type is "persona" instead of an anonymous type of 21 random properties.
query = query.Where(Function(a) a.AREA_ID = 1)
Working with anonymous types is always tricky. Also, I always put the select last...
You could always list out the properties in an anonymous type like this:
Dim query = (From persona In cntx.tblperson
Where persona.DELETED = 0
Select New With {
ATT_TYPE = persona.att_type,
ATT_RECOG = persona.att_recog,
APELLIDO = persona.surname,
NOMBRE = persona.name,
PERSONA_ID = persona.id,
DNI = persona.identification,
DIRECCION = persona.address,
PIN = persona.att_pin,
TIPOASISTENCIA = persona.att_type,
EMAIL = persona.email,
EXTRA = persona.extra,
TELEFONO = persona.phone,
FECHANACIMIENTO = persona.birth,
SEXO = persona.sex,
DELETED = persona.deleted,
AREA_ID = persona.tblarea.id,
AREA = persona.tblarea.name,
CIUDAD = persona.tblcity.name,
CIUDAD_ID = persona.tblcity_id,
PROVINCIA = persona.tblcity.tblstate.name,
PAIS = persona.tblcity.tblstate.tblcountry.name
})
Maybe the where clause using the anon type is messing it up and using persona.DELETED = 0 would help?
I got it ....
I created a new project
I migrate all the resources (images for example) from the old project to this new one.
Opened the NuGet package manager, and installed EF6
Also installed MySQL.Data and MySQL EF6 provider.
I imported the forms, from the original project to the new one.
Now I can do what you guys suggested.
The Problem ??? .... The version on .Net framework, and the EF I was using.
I had t update everything.

Getting instagram post url from media id

I have the post media_id in my hands and I'd like to know if there is a way to create a valid url from it.
For instance, if you have a Facebook post id (xxxx_yyyy) on your hands, you can create the following url from it (http://facebook.com/xxxx/posts/yyyy) and directly access the original post.
Is there a way to do this on Instagram? Having media_id (and user_id) in my hands, is it possible to create a single post url?
I had to implement client side javascript to solve this and Seano's answer was invaluable and I was glad they mentioned the use of the BigInteger library however I wanted to provide a complete implementation using the BigInteger library which as it turns out is quite necessary.
I downloaded the BigInteger lib from https://www.npmjs.com/package/big-integer.
Here is the function which works well for me.
function getInstagramUrlFromMediaId(media_id) {
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
var shortenedId = '';
media_id = media_id.substring(0, media_id.indexOf('_'));
while (media_id > 0) {
var remainder = bigInt(media_id).mod(64);
media_id = bigInt(media_id).minus(remainder).divide(64).toString();
shortenedId = alphabet.charAt(remainder) + shortenedId;
}
return 'https://www.instagram.com/p/' + shortenedId + '/';
}
I just want to point out that the usage of toString() when assigning the re-calculated media_id is very important, the value remains a string to ensure the entire number is used (in my case the media_id was 19 characters long). The BigInteger documentation also states this...
Note that Javascript numbers larger than 9007199254740992 and smaller than -9007199254740992 are not precisely represented numbers and will not produce exact results. If you are dealing with numbers outside that range, it is better to pass in strings.
Cheers!
I just stumbled across this question, all the solutions are great, but none of them were in a language I use often, so running the code would have been a pain in the ass for me.
Seeing that Python is everywhere, I ported over #seano's answer:
def getInstagramUrlFromMediaId(media_id):
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'
shortened_id = ''
while media_id > 0:
remainder = media_id % 64
# dual conversion sign gets the right ID for new posts
media_id = (media_id - remainder) // 64;
# remainder should be casted as an integer to avoid a type error.
shortened_id = alphabet[int(remainder)] + shortened_id
return 'https://instagram.com/p/' + shortened_id + '/'
You can also figure it out algorithmically. It can be done in any language, but here is a way via MySQL function:
DROP FUNCTION IF EXISTS url_fragment
DELIMITER |
CREATE FUNCTION url_fragment(PID BIGINT)
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
DECLARE ALPHA CHAR(64);
DECLARE SHORTCODE VARCHAR(255) DEFAULT "";
DECLARE MEDIAID BIGINT;
DECLARE REMAINDER INT;
SET ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
SET MEDIAID = SUBSTRING_INDEX(PID, "_", 1);
WHILE MEDIAID > 0 DO
SET REMAINDER = MOD(MEDIAID, 64);
SET MEDIAID = (MEDIAID - REMAINDER) / 64;
SET SHORTCODE = CONCAT(SUBSTRING(ALPHA, (REMAINDER + 1), 1), SHORTCODE);
END WHILE;
RETURN SHORTCODE;
END
|
DELIMITER ;
Here's how to derive the URL segment from the media ID using JavaScript:
function getInstagramUrlFromMediaId(media_id) {
media_id = parseInt(media_id.substring(0, media_id.indexOf('_')));
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
var shortenedId = '';
while (media_id > 0) {
var remainder = modulo(media_id % 64);
media_id = (media_id - remainder) / 64;
shortenedId = alphabet.charAt(remainder) + shortenedId;
}
return 'https://www.instagram.com/p/' + shortenedId + '/';
}
Depending on how old the Instagram post is, you may need to use a library like BigInteger to handle the larger IDs.
You can find a breakdown of the encoding between media id and url segment here: http://carrot.is/coding/instagram-ids
The instagram API returns a "shortcode" property. Something simple like this could work for you.
post.Link = "https://www.instagram.com/p/" + media.shortcode;
Yes this would be possible using the following endpoint one of the media endpoints:
Here is a small php script that will get the link based on media_id and user_id:
$media_id = 'media_id';
$user_id = 'user_id';
$client_id = 'instagram_client_id';
$client_secret = 'instagram_client_secret';
$url = "https://api.instagram.com/v1/media/{$media_id}_{$user_id}?client_id=$client_id&client_secret=$client_secret";
$response = file_get_contents($url);
$response = json_decode($response);
if (is_object($response)) {
$link_to_media = $response->data->link;
}
In the above example you should replace the media_id, user_id, client_id, client_secret with their appropriate values. You should also be able to use an access_token instead of client_id and client_secret as in this example.
References
Media Endpoints
I made Nick's answer use the BigInt that ships with Node. I also avoid returning the full url, I just return the shortcode.
function getInstagramShortcodeFromId(media_id) {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
let shortenedId = '';
while (media_id > 0) {
const remainder = BigInt(media_id) % BigInt(64);
media_id = ((BigInt(media_id) - BigInt(remainder)) / BigInt(64)).toString();
shortenedId = alphabet.charAt(Number(remainder)) + shortenedId;
}
return shortenedId;
}

How to write the HAVING clause with SQL COUNT(DISTINCT column_name) function in Codeigniter Active Record?

I am using Codeigniter and am trying to use the Active Record Class for all my database operations.
However, I did run into problems when trying to convert the last bid of the following (working) query into Active Record code.
$sql = ("SELECT ac.cou_id
FROM authorcourse ac
INNER JOIN course c
ON ac.cou_id = c.cou_id
WHERE cou_name = ? // ? = $cou_name
AND cou_number = ? // ? = $cou_number
AND cou_term = ? // ? = $cou_term
AND cou_year = ? // ? = $cou_year
AND FIND_IN_SET (ac.aut_id, ?) //? = $aut_ids_string
GROUP BY ac.cou_id
HAVING COUNT(DISTINCT ac.aut_id) = ? //? = $aut_quantity
AND COUNT(DISTINCT ac.aut_id) = (SELECT COUNT(DISTINCT ac2.aut_id)
FROM authorcourse ac2
WHERE ac2.cou_id = ac.cou_id)");
$query = $this->db->query($sql, array($cou_name, $cou_number, $cou_term, $cou_year, $aut_ids_string, $aut_quantity));
Question: How do I convert the HAVING clause into valid Active Record code?
I tried using $this->db->having(); and $this->db->distinct(); but failed to combine the functions to achieve the desired result.
My (working) code so far:
$this->db->select('ac.cou_id');
$this->db->from('authorcourse ac');
$this->db->join('course c', 'c.cou_id = ac.cou_id');
$this->db->where('cou_name', $cou_name);
$this->db->where('cou_number', $cou_number);
$this->db->where('cou_term', $cou_term);
$this->db->where('cou_year', $cou_year);
$this->db->where_in('ac.aut_id',$aut_ids);
$this->db->group_by('ac.cou_id');
// missing code
Thanks a lot!
You code seems quite clumsy. But, you can use having clause in the following way:
$this->db->having("ac.aut_id = '".$aut_qty."'", null, false)