how can I get table_name , report_name and universe_name from sdk? - sap

I want to get table_name , report_name and universe_name from sdk,
it it possible with java sdk?
I can get query like this:
IInfoObjects infoObjectsUniverse2;
IInfoStore iStore2;
IEnterpriseSession es2=null;
try {
es2 = CrystalEnterprise.getSessionMgr().logon( user, password, CMSName, cmsAuthType);
//session.setAttribute( "enterpriseSession", es );
iStore2 = (IInfoStore)es2.getService("", "InfoStore");
IInfoObjects getuniv;
String queryUniverse = "SELECT * FROM ci_appobjects WHERE SI_Kind='DSL.MetaDataFile' and SI_SPECIFIC_KIND = 'DSL.Universe'";
getuniv = iStore2.query(queryUniverse);

You can retrieve the WI report's name (SI_NAME) and its associated universes (SI_UNIVERSE,SI_DSL_UNIVERSE) from the repository:
SELECT si_id, si_name, si_universe, si_dsl_universe FROM ci_infoobjects WHERE si_kind='Webi' and si_instance=0
Both the SI_UNIVERSE and SI_DSL_UNIVERSE properties are collections of IDs that you'll need to serialize and include in a second query to get the details about the universes:
SELECT * FROM ci_appobjects WHERE si_id IN ([serialized list of IDs])
If you just want a list of the UNV or UNX universes, use this query:
SELECT * FROM ci_appobjects WHERE si_kind IN ('Universe','DSL.Universe')
You'll need to use one of the Universe SDKs to access the universe's collection of tables and such.
You could also try the RESTful Raylight SDK, but good luck finding the documentation--all the links that I've seen are orphans.

Related

Multi keywords search with SQL

I'm using a search bar on my website based on keyup binding and ajax requests. It works fine but I would like my search engine to be able to have finner result with multi keywords management.
However I could not find any simple method to set up this kind of search method.
Does anyone knows how to set this up ?
Here is the actual SQL request that's being made:
if ($recherche !=""){
$req = $this->bdd->prepare("SELECT * FROM videos WHERE titre LIKE :recherche OR auteur LIKE :recherche UNION SELECT videos.id_video, videos.titre, videos.lien, videos.auteur, videos.date_upload FROM videos RIGHT JOIN mots_clefs ON videos.id_video = mots_clefs.id_video AND mots_clefs.mot_clef LIKE :recherche ORDER BY date_upload DESC LIMIT ".$start.", ".$limit);
$req->execute(array('recherche' => "%".$recherche."%"));
$result = json_encode($req->fetchAll(PDO::FETCH_ASSOC));
}
Request example:
SELECT * FROM videos WHERE titre LIKE '%word 1 word 2%' OR auteur LIKE '%word 1 word 2%' UNION SELECT videos.id_video, videos.titre, videos.lien, videos.auteur, videos.date_upload FROM videos RIGHT JOIN mots_clefs ON videos.id_video = mots_clefs.id_video AND mots_clefs.mot_clef LIKE '%word 1 word 2%' ORDER BY date_upload DESC LIMIT 0, 20);
You can execute the above query in a loop by passing one keyword at a time.
get the entire keyword list provided by the user into a sting.
Use string.Split() method by passing comma(,) as delimiter to get the list of the keywords into an array list.
loop through the array list and pass to the query.
Make sure you append the data fetched from the SQL into a data table or dataset and Not rewrite it.
string select = "SELECT * FROM [MyTable] WHERE [Title] LIKE '%" + strSearch.Replace(",", "%' OR [Title] LIKE '%") + "%'";

Clean a JSON in a PostGreSQL request

I have a SQL request that is almost perfect (for what I want to do):
WITH liste_fichiers_joints AS (
SELECT
id_dans_table,
ARRAY_AGG (row_to_json(f)) ids_fichier
FROM
fichiers_joints fj
LEFT JOIN fichiers f ON f.id = fj.id_fichier
WHERE
nom_table = 'taches'
GROUP BY
id_dans_table
)
SELECT t.id, t.nom, lfj.ids_fichier
FROM taches t
JOIN liste_fichiers_joints lfj ON lfj.id_dans_table = t.id
As you may have guessed, I'd like to get in the same request getting all the tasks: the id of a task, the name of the task but also in an array all the ids and names of the attached files if there are any.
The result is nearly what I want, but the last column displays this:
{"{\"uuid\":\"fd809b1f-6849-4322-a654-67f70c46a435\",\"nom\":\"test.png\",\"date\":\"2020-11-17T01:21:24.223354\",\"status\":\"TMP\",\"id\":185}"}
I'd like to remove the uuid and status parts, I tried some subrequests, up to no avail.
Also, I'd like to remove the backslashes \, because otherwise it will be complicated to use this column as a JSON in my Javascript.
Does anybody has a clue?
Thanks in advance.
You can use json[b]_build_object() instead of row_to_json[b](): it accepts a list of key/value pairs, so you have fine-grained control about what is going into your objects.
Also, you most likely want a JSON array, rather than a Postgres array of JSON objects.
I would recommend changing this:
ARRAY_AGG (row_to_json(f)) ids_fichier
To:
jsonb_agg(
jsonb_build_object('nom', f.nom, 'date', f.date, 'id', f.id)
) as ids_fichier

How to get From & To Ip Address from CIDR BigQuery

BigQuery provides updated geoip2 public dataset here [bigquery-publicdata -> geolite2 -> ipv4_city_blocks] which contains network column with IPv4 CIDR values.
How do I convert the CIDR values in the network column via BigQuery SQL (and not via a utility outside BigQuery) into start & end ip-address values so that I can find if an IP address is within a range or no? Would be helpful if you can provide the query to obtain the range ips for a CIDR value in the table.
Below is for BigQuery Standard SQL
#standardSQL
CREATE TEMP FUNCTION cidrToRange(CIDR STRING)
RETURNS STRUCT<start_IP STRING, end_IP STRING>
LANGUAGE js AS """
var beg = CIDR.substr(CIDR,CIDR.indexOf('/'));
var end = beg;
var off = (1<<(32-parseInt(CIDR.substr(CIDR.indexOf('/')+1))))-1;
var sub = beg.split('.').map(function(a){return parseInt(a)});
var buf = new ArrayBuffer(4);
var i32 = new Uint32Array(buf);
i32[0] = (sub[0]<<24) + (sub[1]<<16) + (sub[2]<<8) + (sub[3]) + off;
var end = Array.apply([],new Uint8Array(buf)).reverse().join('.');
return {start_IP: beg, end_IP: end};
""";
SELECT network, IP_range.*
FROM `bigquery-public-data.geolite2.ipv4_city_blocks`,
UNNEST([cidrToRange(network)]) IP_range
It took about 60 sec to process all 3,037,858 rows with result like below
This query will do the job:
# replace with your source of IP addresses
# here I'm using the same Wikipedia set from the previous article
WITH source_of_ip_addresses AS (
SELECT REGEXP_REPLACE(contributor_ip, 'xxx', '0') ip, COUNT(*) c
FROM `publicdata.samples.wikipedia`
WHERE contributor_ip IS NOT null
GROUP BY 1
)
SELECT city_name, SUM(c) c, ST_GeogPoint(AVG(longitude), AVG(latitude)) point
FROM (
SELECT ip, city_name, c, latitude, longitude, geoname_id
FROM (
SELECT *, NET.SAFE_IP_FROM_STRING(ip) & NET.IP_NET_MASK(4, mask) network_bin
FROM source_of_ip_addresses, UNNEST(GENERATE_ARRAY(9,32)) mask
WHERE BYTE_LENGTH(NET.SAFE_IP_FROM_STRING(ip)) = 4
)
JOIN `fh-bigquery.geocode.201806_geolite2_city_ipv4_locs`
USING (network_bin, mask)
)
WHERE city_name IS NOT null
GROUP BY city_name, geoname_id
ORDER BY c DESC
LIMIT 5000`
Find more details on:
https://towardsdatascience.com/geolocation-with-bigquery-de-identify-76-million-ip-addresses-in-20-seconds-e9e652480bd2
The first thing you need to check is, if that function already exists, so please refer to the BigQuery Functions and Operators documentation.
If not, you need to use Standard SQL User-Defined Functions (UDF), which lets you create a function using another SQL expression or another programming language, such as JavaScript.
Keep in mind when using UDF JavaScript function, BigQuery initializes a JavaScript environment with the function's contents on every shard of execution. There is no optimization to avoid loading the environment, so it can slow down the query.
Regarding to GeoIP2 City and Country CSV Databases site, there is a utility to convert 'network' column to start/end IPs or start/end integers. Refer to Github site for details.
January 2023 solution
Just wanted to respond to Felipe's comment here. I'm not sure why he is suggesting an alternate solution using Snowflake, as his existing solution works just fine. The only difference is that you need to create the dataset yourself.
I managed to solve this by going through the exact same steps listed in Felipe's very helpful original blog article:
Sign-up to MaxMind and download the Geolite2 databases (link)
Download the two CSV files GeoLite2-City-Blocks-IPv4.csv and GeoLite2-City-Locations-en.csv, upload them to a GCP bucket, and create tables from them. I lazily used the BQ automated schema feature and it worked just fine :)
Simply create a geolite2_locs table using a query similar to the one below (just keep or drop your columns as required for your use-case)
CREATE OR REPLACE TALBLE `dataset.geolite2_locs` OPTIONS() AS (
SELECT
ip_ref.network,
NET.IP_FROM_STRING(REGEXP_EXTRACT(ip_ref.network, r'(.*)/' )) network_bin,
CAST(REGEXP_EXTRACT(ip_ref.network, r'/(.*)' ) AS INT64) mask,
ip_ref.geoname_id,
city_ref.continent_name as continent_name,
city_ref.country_name as country_name,
city_ref.city_name as city_name,
city_ref.subdivision_1_name as subdivision_1_name,
city_ref.subdivision_2_name as subdivision_2_name,
ip_ref.latitude as latitude,
ip_ref.longitude as longitude,
FROM `geolite2`.`geolite2-ipv4` ip_ref LEFT JOIN `geolite2`.`geolite2-city-en` city_ref USING (geoname_id)
);
Adapt the query in Felipe's guide or just replace the fh-bigquery.geocode.201806_geolite2_city_ipv4_locs with your new table in his answer above.
Should take you at max 1 hour to get this going. Hope it helps.

Liferay DynamicQuery - xPath and Array comparison

My final goal is I want to get plid and portletId that can be display my article(or entry with any type if it is possible).
I have sql query that return me any portlet availble for display my article.
But when I have to use dynamicQuery to get the same results, I get problem with xPath and array comparison, please help!
SELECT * FROM portletpreferences pr
WHERE pr.preferences != '<portlet-preferences />' AND pr.ownerid = 0 AND pr.portletid ilike '%_INSTANCE_%' AND pr.plid IN(
SELECT layout.plid FROM layout
WHERE layout.type_ = 'portlet' AND layout.groupid = 19 AND layout.hidden_ is false)
AND pr.portletpreferencesid IN (
SELECT pr.portletpreferencesid FROM portletpreferences pr
WHERE 'true' = ANY(xpath('//preference[name="anyAssetType"]/value/text()', XMLPARSE(DOCUMENT pr.preferences))::text[])
OR (SELECT (array(SELECT id_ FROM journalstructure))::text[]) && xpath('//preference[name="classTypeIds"]/value/text()', XMLPARSE(DOCUMENT pr.preferences))::text[] )
If you are bent upon using this same query, then use this query directly with Custom-SQL in liferay by creating custom-finders instead of using DynamicQuery. That would give you a lot of flexibility in using any type of SQL query directly.
I don't think this query can be converted to DynamicQuery, but if you do manage to convert it then please do post it here :-)
DynamicQuery is very powerful, see e.g. my answer how to find layouts with specific JournalArticles. I think your requirement is similar to this one:
Liferay: How to find all Layouts with the specific JournalArticle in AssetPublisher portlets?

Basic - SQL Query to LINQ Query

I have been trying out some LINQ query can someone please show how to convert the following SQL query to LINQ:
SELECT *, firstname+' '+lastname AS FullName FROM Client WHERE age > 25;
Don't worry about the where part (put it in for completeness) more wandering how to achieve that first part.
Now I have come across something like this:
from c in dc.Clients select new {FullName = c.firstname + " "+c.lastname}
But i don't know how to get it to select everything else without specifying it ie:
{firstname = c.firstname, id = c.id ..... etc}
But I was hoping for another way of achieving that.
So I'm just wandering if someone could show me the right or another way of accomplishing this :)
Thanks All :)
You have to select the actual item then refer to its properties. There's no way to expand the individual columns into the anonymous type.
var query = from c in dc.Clients
where c.Age > 25
select new
{
Client = c,
FullName = c.firstname + " " + c.lastname
};
foreach (var item in query)
{
// item.Client.Id
// item.FullName
// item.Client.FirstName
}
Selecting the actual item gives you access to the same properties you were using to construct the anonymous type. It's not a complete waste though if the query had more going on, such as a join with another table and including fields from that result in the anonymous type, along with the entire Client object.
You can can't autogenerate every column with Linq2Sql or EF (you can however find a way to mimic this behavior with micro-orms like Dapper and massive).
More conveniently, you can just select a new anonymous type with 3 fields, firstname, lastname and a client like:
from c in dc.Clients
select new
{
FullName = c.firstname + " "+c.lastname,
Client = c
}
I would however recommend to select just those properties that you really need. This forces you to think about how to compose your query and what the query is intended to do (and hence, select). Alternatively, you can just select the client, and use some extension methods to select full names. like:
public static string GetFullName(this Client client){ return client.firstname + " " + client.lastname; }