Data Access Layer for Analysis Services w/Dynamic MDX - service

We have project that uses Analysis Services as it's datasource. To try to avoid having to create 100's of queries because of all the selection options we allow, we create our mdx queries with alot of switches and string concatenation. This is our "Data Access Layer". It is a beast to manage and the smallest mistake: missing spaces, mispellings are easy to miss and even easier to accidently include. Does anyone know of a good resource that can help make this more manageable, like a tutorial, white paper or sample project.
To give you an idea of the case logic I'm talking about and it goes on and on...
if (Time == Day)
{
if (Years == One)
{
return (" MEMBER " + CurrentSalesPercent +
" AS ([Sales % " + YearString + " " + StatusType + "]) ");
}
else //2Y
{
return (" MEMBER " + CurrentSalesPercent +
" AS ([Sales % 2Y " + StatusType + "]) ");
}
}
else if (Time == Week)
{
if (Years == One)
{
return (" MEMBER " + CurrentSalesPercent +
" AS ([Sales WTD % " + YearString + " " + StatusType + "]) ");
}
else //2Y
{
return (" MEMBER " + CurrentSalesPercent +
" AS ([Sales WTD % 2Y " + StatusType + "]) ");
}
...
To be honest, I'm not sure if all the different measures and calculations are correct either. But, that's controlled by another team, so we have a little less influence here.
Thanks!
mkt

Have you looked at the way MS generates MDX? If you have SSRS installed, get "Red gate Reflector" and disassemble C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer\bin\MDXQueryGenerator.dll
Apart from that, pre-canned queries that take parameters seems pretty standard :(

Related

Get previous day in an Expression

Just need help on this as I am new at SSIS. I got an expression but I want yesterday, not today.
"Daily "+ (RIGHT("0" + (DT_STR,4,1252) DatePart("yyyy",getdate()),4))+(RIGHT("0" + (DT_STR,4,1252) DatePart("mm",getdate()),2))+(RIGHT("0" + (DT_STR,4,1252) DatePart("dd",getdate()),2))+".CSV"
Currently it looks like this
Daily 20161006.CSV
What I want is
Daily 20161005.CSV
Here you go.
"Daily "
+ (DT_WSTR, 4) YEAR(DATEADD("day",-1,GETDATE()))
+ RIGHT("0" + (DT_WSTR, 2) DATEPART("MM", DATEADD("day", -1, GETDATE())),2)
+ RIGHT("0" + (DT_WSTR, 2) DATEPART("DD", DATEADD("day", -1, GETDATE())),2)
+ ".CSV"
It looks like you are in Australia, so it is 20161006 there, but in US Right now, it is 20161005, and see how it shows yesterday i.e. 20161004 in the file name when I clicked Evaluate value
"Daily "+ (RIGHT("0" + (DT_STR,4,1252) DatePart("yyyy",getdate()),4))+(RIGHT("0" + (DT_STR,4,1252) DatePart("mm",getdate()),2))+(RIGHT("0" +(DT_STR,4,1252) (DatePart("dd",getdate())-1),2))+".CSV"
This should work.

Improve performance on native sql query

I'm trying to build a location-based application in Java EE, which returns providers from a certain radius given coordinates as input. As I use JPA, I couldn't find a solution to querying the database with a named query as it doesn't support functions like Sin, Cos etc. I found a nice read here, sql-haversine, where I could use a native query instead. The query executes fast (33 ms) on the database (Postgres), but very slow when executed from the application (> 800 ms).
Is there a way to speed things up, from the application end, or do you have to use something like a stored procedure in the database.
My method looks like this:
#SuppressWarnings("unchecked")
public List<Company> findCompaniesByProximity(Coordinate coordinate, int distance) {
double latitude = coordinate.getLatitude();
double longitude = coordinate.getLongitude();
String sql = "SELECT * FROM ("
+ "SELECT *, c.distance_unit * DEGREES(ACOS(COS(RADIANS(c.lat)) * COS(RADIANS(companies.latitude)) * "
+ "COS(RADIANS(c.lng) - RADIANS(companies.longitude)) + SIN(RADIANS(c.lat)) * SIN(RADIANS(companies.latitude)))"
+ ") AS distance "
+ "FROM Companies "
+ "JOIN (SELECT ?1 AS lat, ?2 AS lng, ?3 AS search_radius, 111.045 AS distance_unit) "
+ "AS c ON 1=1 "
+ "WHERE companies.latitude "
+ "BETWEEN c.lat - (c.search_radius / c.distance_unit) "
+ "AND c.lat + (c.search_radius / c.distance_unit) "
+ "AND companies.longitude "
+ "BETWEEN c.lng - (c.search_radius / (c.distance_unit * COS(RADIANS(c.lat)))) "
+ "AND c.lng + (c.search_radius / (c.distance_unit * COS(RADIANS(c.lat))))"
+ ") AS proximity "
+ "WHERE distance <= search_radius "
+ "ORDER BY distance "
+ "LIMIT 25";
List<Company> companies = null;
try {
Query query = em.createNativeQuery(sql, Company.class);
query.setParameter(1, latitude);
query.setParameter(2, longitude);
query.setParameter(3, distance / 1000.0);
companies = (List<Company>) query.getResultList();
} catch (IllegalArgumentException e) {
System.err.println("Argument is invalid " + e);
} catch (PersistenceException e) {
System.err.println("PersistenceException: " + e.getMessage());
}
return companies;
}
The method is called from a singleton EJB, and I'm using Payara server with Postgres and EclipseLink. Everything is called locally so I thought the connection to database would be much faster. Iv'e also tried the postgres earthdistance extension, but it was even slower ( > 1800 ms). I've quite new to programming and especially Java EE so I might have done something wrong along the way :)
Thanks, in advance.

libpq, insert with parameters

I am wondering if I can make parameterized queries directly from C/C++ with libpq instead of using strings and if do how should this code look's like?
string tblins = "";
tblins = "INSERT INTO " + commtable + " "
"(vdoc, bdoc, mytime, txml) VALUES ("
"'" + cxml.vdoc + "', "
+ cxml.bdoc + ", " //integer
"'" + cxml.mytime + "', "
"'" + cxml.txml + "')";
result = PQexec(conn, tblins.c_str());
Thanks.
Yes, you can use the PQexecParams function as explained in the documentation.
If parameters are used, they are referred to in the command string as $1, $2, etc. nParams is the number of parameters supplied; it is the length of the arrays paramTypes[], paramValues[], paramLengths[], and paramFormats[].

Checking User Agent in Wicket

I am using wicket 1.5 and I am not able to see in the getClientInfo() method
(WebRequest)RequestCycle.get().getRequest()
I saw the other place this code
WebClientInfo clientInfo = (WebClientInfo)WebRequestCycle.get().getClientInfo();
But I am not able to see any WebRequestCycle in Wicket 1.5.
Any ideas how to check the user agent in Wicket 1.5?
The easiest way is to use
WebSession.get().getClientInfo().getUserAgent();
On newer Wicket Versions (6 or newer), you should use:
WebClientInfo clientInfo = new WebClientInfo(getRequestCycle());
System.out.println("Client: " + clientInfo.getUserAgent());
System.out.println("Navigator: " + clientInfo.getProperties().getNavigatorAppName() + ", version " + clientInfo.getProperties().getNavigatorAppVersion() + ", codName: " + clientInfo.getProperties().getNavigatorAppCodeName() + ", plataform: " + clientInfo.getProperties().getNavigatorPlatform() + ", AppCodName: " + clientInfo.getProperties().getNavigatorAppCodeName());
System.out.println("NavigatorUserAgent: " + clientInfo.getProperties().getNavigatorUserAgent());
System.out.println("Tamanho da tela (Width x Height): " + clientInfo.getProperties().getScreenWidth() + " x " + clientInfo.getProperties().getScreenHeight() );
You can also do:
((WebRequest) getRequest()).getHeader("User-Agent")

How to use Netbeans Variable Formatters?

By default when viewing watches/variables of objects in Netbeans, it shows its address instead of its value. This is quite tiresome since I have to expand the variable to see its real value (e.g. for Double, Integer, Date, etc). As it turns out, Netbeans has "Variable formatters" but there is hardly any documentation that i can find for it.
How would I go about displaying e.g. a simple Date variable in a human readable format in the Watches/Variables window? I don't fully understand the "Edit Variable Formatter" dialog.
I was able to properly do it for Double and Integer by using the following code snippet:
toString()
So the code seems to run in the context of the Double/Integer class. How would I refer to the actual variable if I need to do something more advanced such as:
return DateHelpers.formatDate(dateVariableName??, "yyyy-MM-dd");
In the variables view, you have a small $ icon (at the top left) which tooltip says :"Show variable value as toString() or formatted value".
Just click that, it will show you the "value" of those variables.
EDIT: If you want to add a variable formatter, it's very simple. On the variable formatter view, just click the "Add ..." button then:
In "Formatter Name" put the name of you formatter eg. "My Date formatter"
"Class Types" put your complete class name eg. java.util.Date
Select "Value formatted as a result of code snippet" and type the code to apply. For instance:
toString()
but if you want to manipulate the data or display some other thing you can. For instance:
toString() + " (" + getTime() + ")"
Which will display the time in human readable format plus the time as a long.
Don't forget to select the $ icon on the view to apply your formatter.
My answer won't solve the question. It will rather echo the previous answers. First, I haven't seen the $ sign in the variables-panel in NetBeans. Seems it was replaced with a context menu in current versions.
I haven't found the answer to the actual question, as of how you would reference the variable to debug, within the "Variable Formatters" Dialog. Something like "this" or "$1" isn't working definitely. Also the facility does not seem to know about Standard Java JRE classes like SimpleDateFormatter.
So when debugging Java JRE classes, I guess you have to live with what they're offering in terms of public methods.
Here's a workaround for the especially user friendly Date class, if you're stuck with a JDK below version 8 (as me). Just create a new Variable Formatter in NetBeans via
Tools > Options > Java > Variable Formatters > Add
Then in the "Class Types" editfield enter:
java.util.Date
Under "Value formatted as a result of code snippet" use one of the next snippets.
// German format - "dd.MM.yyyy hh:mm"
((getDate() < 10) ? ("0" + getDate()) : getDate()) + "." + ((getMonth() < 9) ? ("0" + (getMonth() + 1)) : (getMonth() + 1) ) + "." + (getYear() + 1900) + " " + ((getHours() < 10) ? "0" + getHours() : getHours()) + ":" + ((getMinutes() < 10) ? "0" + getMinutes() : getMinutes()) + ":" + ((getSeconds() < 10) ? "0" + getSeconds() : getSeconds())
// US format - "MM/dd/yyyy hh:mm"
((getMonth() < 9) ? ("0" + (getMonth() + 1)) : (getMonth() + 1) ) + "/" + ((getDate() < 10) ? ("0" + getDate()) : getDate()) + "/" + (getYear() + 1900) + " " + ((getHours() < 10) ? "0" + getHours() : getHours()) + ":" + ((getMinutes() < 10) ? "0" + getMinutes() : getMinutes()) + ":" + ((getSeconds() < 10) ? "0" + getSeconds() : getSeconds())
// ISO-8601 - "yyyy-MM-dd hh:mm"
(getYear() + 1900) + "-" + ((getMonth() < 9) ? ("0" + (getMonth() + 1)) : (getMonth() + 1) ) + "-" + ((getDate() < 10) ? ("0" + getDate()) : getDate()) + " " + ((getHours() < 10) ? ("0" + getHours()) : getHours()) + ":" + ((getMinutes() < 10) ? ("0" + getMinutes()) : getMinutes()) + ":" + ((getSeconds() < 10) ? ("0" + getSeconds()) : getSeconds())
The next snippet could also come in handy, when your lost in the the debug-output overkill of an instance of java.util.Calendar:
// German format - "dd.MM.yyyy hh:mm"
((get(5) < 10) ? ("0" + get(5)) : get(5)) + "." + ((get(2) < 9) ? ("0" + (get(2) + 1)) : (get(2) + 1) ) + "." + (get(1)) + " " + ((get(10) < 10) ? "0" + get(10) : get(10)) + ":" + ((get(12) < 10) ? "0" + get(12) : get(12)) + ":" + ((get(13) < 10) ? "0" + get(13) : get(13))
You can even put a much more complex code in the variable formatter, as long as you return a string. For example, if I have a class with two string members, name and surname I can paste the follwing code in the "Value formatted.." box:
String result;
if (name != null) {
result = name + " " + surname;
} else {
result = "<null>";
}
return result;
.. and for displaying as children the name and surname separately you can paste a code in the "Children displayed as.." box to return a String[], for example:
String[] results = new String[2];
results[0] = "name: " + name;
results[1] = "surname: " + surname;
return results;
This will display two nodes as children in the variables debug window with the name and surname
The variable itself can be referenced by this (at least it works in Netbeans 8.1).
So, let's say we want the identityHashCode of our Collection after its size:
"size = " +size() + " #" + System.identityHashCode(this)