dart - mirror - how to know variable name using mirrors - variables

I am editing my question to fully describe what i need exactly is. I want to create sql query using reflection based on the model/fields as follows.
here method getFieldName() is a dummy sample of my need because i don't know how to implement.
import 'package:reflection_test2/common/reflect/Reflector.dart';
#reflector
class Table
{
int id;
String name;
String sql = "SELECT " + getFieldName(name) + " FROM TABLE "
"WHERE " + getFieldName(id) + "=" + 1.toString();
String getFieldName(dynamic field)
{
String fieldName = sameWayToGetFieldName(field);
return fieldName;
}
}

You tagged your question with flutter. Flutter does not allow using dart:mirror package. So there is no way to retrieve the variable name.
PS. Why do you need the name of the variable? If you need named numbers, you can use Map class.

You should wrap the variable in a class then use reflection...Like this
class MyClass{
int myint = 9;
}
void getVariableNames(){
ClassMirror classMirror = reflectClass(MyClass);
for(var attribute in classMirror.declarations.values){
if(attribute is VariableMirror){
var attributeName = MirrorSystem.getName(attribute.simpleName);
print(attributeName);
}
}
}
main() {
getVariableNames();
}
PLEASE NOTE: Flutter doesn't support reflection/mirrors yet but you can try this out in dart.
https://flutter.dev/docs/resources/faq#does-flutter-come-with-a-reflectionmirrors-system

Related

DBArrayList to List<Map> Conversion after Query

Currently, I have a SQL query that returns information to me in a DBArrayList.
It returns data in this format : [{id=2kjhjlkerjlkdsf324523}]
For the next step, I need it to be in a List<Map> format without the id: [2kjhjlkerjlkdsf324523]
The Datatypes being used are DBArrayList, and List.
If it helps any, the next step is a function to collect the list and then to replace all single quotes if any [SQL-Injection prevention]. Using:
listMap = listMap.collect() { "'" + Util.removeSingleQuotes(it) + "'" }
public static String removeSingleQuotes(s) {
return s ? s.replaceAll(/'"/, '') : s
}
I spent this morning working on it, and I found out that I needed to actually collect the DBArrayList like this:
listMap = dbArrayList.collect { it.getAt('id')}
If you're in a bind like I was and restrained to a specific schema this might help, but #ou_ryperd has the correct answer!
While using a DBArrayList is not wrong, Groovy's idiom is to use the db result as a collection. I would suggest you use it that way directly from the db:
Map myMap = [:]
dbhandle.eachRow("select fieldSomeID, fieldSomeVal from yourTable;") { row ->
map[row.fieldSomeID] = row.fieldSomeVal.replaceAll(/'"/, '')
}

dynamically change a part of the variable path

I know this question has been asked a bunch of times, but none of the answers (or at least what i took away from them) was a help to my particiular problem.
I want to dynamically change a part of the variable path, so i don't have to repeat the same code x-times with just two characters changing.
Here's what i got:
In the beginning of my script, i'm setting the reference to PlayerData scripts, attached to the GameManager object like this:
var P1 : P1_Data;
var P2 : P2_Data;
function Start(){
P1 = GameObject.Find("GameManager").GetComponent.<P1_Data>();
P2 = GameObject.Find("GameManager").GetComponent.<P2_Data>();
}
Later, i want to access these scripts using the currentPlayer variable to dynamically adjust the path:
var currentPlayer : String = "P1"; //this actually happens along with some other stuff in the SwitchPlayers function, i just put it here for better understanding
if (currentPlayer.PlayerEnergy >= value){
// do stuff
}
As i was afraid, i got an error saying, that PlayerEnergy was not a part of UnityEngine.String.
So how do I get unity to read "currentPlayer" as part of the variable path?
Maybe some parse function I haven't found?
Or am I going down an entirely wrong road here?
Cheers
PS: I also tried putting the P1 and P2 variables into an array and access them like this:
if (PlayerData[CurrentPlayerInt].PlayerEnergy >= value){
// do stuff
}
to no success.
First of all,
var currentPlayer : String = "P1"
here P1 is just string, not the previous P1/P2 which are referenced to two scripts. So, if you want, you can change
currentPlayer.PlayerEnergy >= value
to
P1.PlayerEnergy >= value
or,
P2.PlayerEnergy >= value
But if you just want one function for them, like
currentPlayer.PlayerEnergy >= value
Then you have to first set currentPlayer to P1/P2 which I assume you are trying to do. You must have some codes that can verify which player is selected. Then, maybe this can help -
var playerSelected: int = 0;
var currentPlayerEnergy: int = 0;
.....
//Use your codes to verify which player is selected and then,
if (playerSelected == 1) {
currentPlayerEnergy = P1.PlayerEnergy;
} else if (playerSelected == 2) {
currentPlayerEnergy = P2.PlayerEnergy;
}
//Now use your favorite function
if (currentPlayerEnergy >= value) {
//Do stuff
}
As there was no reply providing the answer I needed, I'll share the solution that did the trick for me, provided by a fellow student.
Instead of having the PlayerData scripts pre-written, I generate them using a public class function in a Playermanager script. This generates the Playerdata as attached scripts, saved into an array.
I can then access them through Playermanager.Playerlist[Playernumber].targetvariable.
Which is what I wanted to do, only with the Playerdata being attached to a script instead of a gameobject. And it works great!
Here's the full code of my Playermanager Script:
//initialise max players
public var maxplayers : int = 2;
// Initialise Playerlist
static var Players = new List.<PlayerData>();
function Start () {
for (var i : int = 0; i < maxplayers; i++){
var Player = new PlayerData();
Players.Add(Player);
Players[i].PlayerName = "Player " + i;
}
DontDestroyOnLoad (transform.gameObject);
}
public class PlayerData {
public var PlayerName : String;
public var PlayerEnergy : int = 15;
public var Fleet : List.<GameObject> = new List.<GameObject>();
}
As you see, you can put any type of variable in this class.
I hope this helps some of you who have the same problem.
cheers,
Tux

How to get Alfresco custom content model property information?

Is there any way to programmatically understand what properties there are for a custom model in Alfresco?
For example, data dictionary in oracle helps you to find what tables are defined by which column names and column data types.
My goal is a sample code in java which extracts all custom defined content models, their attributes, their attributes data types, etc. For example my sample code should return to me that there is a custom content Model which has an integer attribute with name 'No' and a string attribute with name 'Description'. I know this is possible with DictionaryComponent, But I don't know how should I use it.
Take a look at org.alfresco.service.cmr.dictionary.DictionaryService.
will your Java-code running in-context with alfresco (as part of the /alfresco webapp) or outside?
If your running in-context, then Alfreso Java Foundation API is your choice where DictionaryService is part of. just inject the bean into your java code.
If your code is running outside of alfresco, then Alfresco REST API or CMIS is your choice.
If you're still lost, then train yourself first. Jeff wrote some good articles http://ecmarchitect.com/alfresco-developer-series & also a book.
Also a good starting point - Alfresco Developer Docs: http://docs.alfresco.com/4.2/topic/com.alfresco.enterprise.doc/concepts/dev-for-developers.html
thanks a lot of alfresian responses, My code sample is something like below:
I found the sample code from : this URL
public void GetAllAvailableDataTypes() throws IOException
{
Session session = getSession();
boolean includePropertyDefintions = true;
for (Tree t : session.getTypeDescendants(
null, // start at the top of the tree
-1, // infinite depth recursion
includePropertyDefintions // include prop defs
)) {
printTypes(t, "");
}
}
public void printTypes(Tree tree, String tab) {
ObjectType objType = (ObjectType) tree.getItem();
String type = objType.getId();
if(true)//type.endsWith("hstcase"))
{
System.out.println(tab + "TYPE:" + objType.getDisplayName() +
" (" + objType.getDescription() + ")");
//Print some of the common attributes for this type
System.out.print(tab + " Id:" + "-----"+ objType.getId() + "-----");
System.out.print(" Fileable:" + objType.isFileable());
System.out.print(" Queryable:" + objType.isQueryable());
if (objType instanceof DocumentType) {
System.out.print(" [DOC Attrs->] Versionable:" +
((DocumentType)objType).isVersionable());
System.out.println(" Content:" +
((DocumentType)objType).getContentStreamAllowed());
Map<String, org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition<?>> props = objType.getPropertyDefinitions();
Set<String> keys = props.keySet();
Collection<org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition<?>> porpsAsCollection = props.values();
for(org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition<?> p: porpsAsCollection)
{
//System.out.println(p.getDescription());
PropertyType pt = p.getPropertyType();
System.out.println("Display Name: "+ p.getDisplayName());
System.out.println("Local Name: "+ p.getLocalName());
System.out.println("Attribute Type: "+ pt.value());
}
}
System.out.println(""); // end the line
}
List<Tree> childs = tree.getChildren();
for (Tree t : childs) {
// there are more - call self for next level
printTypes(t, tab + " ");
}
}

How can Jdbc template be used for UPDATE query with IN clause?

I've gone through various forums to handle the IN clause using spring's namedParamJdbcTemplate but i still do not get the stuff I'm exactly looking for.
Below is my issue:
I've the following method:
public void updateBatchTableForStatus(List<Integer> reportShellIds, String scheduleType) {
Map<String,List<Integer>> shellIds = Collections.singletonMap("reportShellIds", reportShellIds);
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("reportShellIds", shellIds, Types.NUMERIC)
parameters.addValue("eventType", scheduleType, Types.VARCHAR);
this.namedParamJdbcTemplate.update(GET_EVENT_METADATA_INFO, parameters);
}
The query refered in above method is as defined below:
public static final String SQL_UPDATE_BATCH_LOOKUP_TABLE_FOR_STATUS_BY_BATCH_IDS = "" +
"UPDATE " +
TABLE_BATCH_REF + " BLK " +
"SET " +
"BLK.EXECUTION_STATUS_CODE = :eventType " +
"WHERE " +
"BLK.BATCH_ID in(:reportShellIds) ";
Datatype for BATCH_ID column is Number(24,0) and for the EXECUTION_STATUS_CODE column Varchar.
I'm using Oracle db.
However, the above method throws a SQL exception.
Can someone pls tell me where I'm wrong and what is the fix for it ?
Many thanks in advance.
Best Regards
LB
You are binding reportShellIds to a Map, but it needs to be a List for Spring to bind it correctly. Perhaps you meant shellIds.values() or the variable reportShellIds?
You can use another method with simple Map<String,Object> and place the array as is into the parameter map
public int update(String sql, java.util.Map<java.lang.String,?> paramMap)

Does Dapper support the like operator?

Using Dapper-dot-net...
The following yields no results in the data object:
var data = conn.Query(#"
select top 25
Term as Label,
Type,
ID
from SearchTerms
WHERE Term like '%#T%'",
new { T = (string)term });
However, when I just use a regular String Format like:
string QueryString = String.Format("select top 25 Term as Label, Type, ID from SearchTerms WHERE Term like '%{0}%'", term);
var data = conn.Query(QueryString);
I get 25 rows back in the collection. Is Dapper not correctly parsing the end of the parameter #T?
Try:
term = "whateverterm";
var encodeForLike = term => term.Replace("[", "[[]").Replace("%", "[%]");
string term = "%" + encodeForLike(term) + "%";
var data = conn.Query(#"
select top 25
Term as Label,
Type,
ID
from SearchTerms
WHERE Term like #term",
new { term });
There is nothing special about like operators, you never want your params inside string literals, they will not work, instead they will be interpreted as a string.
note
The hard-coded example in your second snippet is strongly discouraged, besides being a huge problem with sql injection, it can cause dapper to leak.
caveat
Any like match that is leading with a wildcard is not SARGable, which means it is slow and will require an index scan.
Yes it does. This simple solution has worked for me everytime:
db.Query<Remitente>("SELECT *
FROM Remitentes
WHERE Nombre LIKE #n", new { n = "%" + nombre + "%" })
.ToList();
Best way to use this to add concat function in query as it save in sql injecting as well, but concat function is only support above than sql 2012
string query = "SELECT * from country WHERE Name LIKE CONCAT('%',#name,'%');"
var results = connection.query<country>(query, new {name});
The answer from Sam wasn't working for me so after some testing I came up with using the SQLite CONCAT equivalent which seems to work:
string sql = "SELECT * FROM myTable WHERE Name LIKE '%' || #NAME || '%'";
var data = IEnumerable data = conn.Query(sql, new { NAME = Name });
Just to digress on Sam's answer, here is how I created two helper methods to make searches a bit easier using the LIKE operator.
First, creating a method for generating a parameterized query, this method uses dynamic: , but creating a strongly typed generic method should be more desired in many cases where you want static typing instead of dynamic.
public static dynamic ParameterizedQuery(this IDbConnection connection, string sql, Dictionary<string, object> parametersDictionary)
{
if (string.IsNullOrEmpty(sql))
{
return null;
}
string missingParameters = string.Empty;
foreach (var item in parametersDictionary)
{
if (!sql.Contains(item.Key))
{
missingParameters += $"Missing parameter: {item.Key}";
}
}
if (!string.IsNullOrEmpty(missingParameters))
{
throw new ArgumentException($"Parameterized query failed. {missingParameters}");
}
var parameters = new DynamicParameters(parametersDictionary);
return connection.Query(sql, parameters);
}
Then adding a method to create a Like search term that will work with Dapper.
public static string Like(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm))
{
return null;
}
Func<string, string> encodeForLike = searchTerm => searchTerm.Replace("[", "[[]").Replace("%", "[%]");
return $"%{encodeForLike(searchTerm)}%";
}
Example usage:
var sql = $"select * from products where ProductName like #ProdName";
var herringsInNorthwindDb = connection.ParameterizedQuery(sql, new Dictionary<string, object> { { "#ProdName", Like("sild") } });
foreach (var herring in herringsInNorthwindDb)
{
Console.WriteLine($"{herring.ProductName}");
}
And we get our sample data from Northwind DB:
I like this approach, since we get helper extension methods to do repetitive work.
My solution simple to this problem :
parameter.Add("#nomeCliente", dfNomeCliPesquisa.Text.ToUpper());
query = "SELECT * FROM cadastrocliente WHERE upper(nome) LIKE " + "'%" + dfNomeCliPesquisa.Text.ToUpper() + "%'";