How to use plsql-parser (ANTLR) - plsql

I'd like to check PL/SQL query syntax in automated tests, and it looks like https://github.com/porcelli/plsql-parser might be useful for that. I am not easily finding out how I would install and use it though.
Note that this is for a Ruby project, but I'm reasonably competent in Java. I'm hoping there's some way I can run the checking via console, pass in the SQL, and get back any error info, including line/column.
Thanks.

Download the ANTLR tool ver 3.5.1
Download the source codes from here (as this version was ported to 3.5.1)
Use the tool to compile the sources from poarsers/no-ast subdir
1st compile PLSQLLexer.g
2nd compile PLSQLParser.g from no-ast subdir
the use this sample code as an example:
import org.antlr.runtime.ANTLRNoCaseFileStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import br.com.porcelli.parser.plsql.PLSQLLexer;
import br.com.porcelli.parser.plsql.PLSQLParser;
public static void parse(String file) {
try {
PLSQLLexer lex = new PLSQLLexer(new ANTLRNoCaseFileStream(file));
CommonTokenStream tokens = new CommonTokenStream(lex);
PLSQLParser parser = new PLSQLParser(tokens);
/*start_rule_return AST =*/ parser.data_manipulation_language_statements();
System.err.println(file +": " + parser.getNumberOfSyntaxErrors());
if(parser.getNumberOfSyntaxErrors() != 0)
{
//System.exit(1);
}
} catch (RecognitionException e) {
System.err.println(e.toString());
} catch (IOException e) {
System.err.println(e.toString());
} catch (java.lang.OutOfMemoryError e) {
System.err.println(file + ":");
System.err.println(e.toString());
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
System.err.println(file + ":");
System.err.println(e.toString());
}
}

Related

Xamarin, SQLite : Don't know how to read System.Char

I use the below code to search SQLite table. It works fine with Android 9. But I receive the below error in Android 10.
Where should I check or how can I make minimal change in the code so that it will work on Android 10 also.
Edit 1:
I'm using the following versions.
Xamarin.Forms v4.5.0.495
Xamarin.Essentials v1.3.1
sqlite-net-pcl v1.7.335
Code:
public SearchPage()
{
InitializeComponent();
conn = DependencyService.Get<ISQLiteMyConnection>().GetConnection();
try
{
DisplayLines("");
}
catch (Exception ex)
{
DisplayAlert("Error", ex.Message, "Ok");
}
}
public void DisplayLines(string searchText)
{
if (String.IsNullOrWhiteSpace(searchText))
{
var details = (from x in conn.Table<QLines>() select x).ToList();
myLines.ItemsSource = details;
searchCount.Text = "";
}
else
{
var details1 = (from x in conn.Table<QLines>() where x.PartA.Contains(searchText) || x.PartB.Contains(searchText) select x).ToList();
myLines.ItemsSource = details1;
searchCount.Text = "Matches found : " + details1.Count.ToString();
}
}
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
DisplayLines(e.NewTextValue);
}
Error:
Don't know how to read System.Char
I got the issue.
The nuget package SQLite.Net.Core-PCL is deprecated. This package is handling LINQ like query on SQLite db. Suggested alternative is sqlite-net-pcl. Might be, I need to revise the code.
Edit: I have updated the Xamarin Form to version 5. And revised the code ( I used query instead of LINQ)

With OpenCSV, how do I append to existing CSV using a MappingStrategy?

With OpenCSV, how do I append to existing CSV using a MappingStrategy? There are lots of examples I could find where NOT using a Bean mapping stategy BUT I like the dynamic nature of the column mapping with bean strategy and would like to get it working this way. Here is my code, which just rewrites the single line to CSV file instead of appending.
How can I fix this? Using OpenCSV 4.5 . Note: I set my FileWriter for append=true . This scenario is not working as I expected. Re-running this method simply results in over-writing the entire file with a header and a single row.
public void addRowToCSV(PerfMetric rowData) {
File file = new File(PerfTestMetric.CSV_FILE_PATH);
try {
CSVWriter writer = new CSVWriter(new FileWriter(file, true));
CustomCSVMappingStrategy<PerfMetric> mappingStrategy
= new CustomCSVMappingStrategy<>();
mappingStrategy.setType(PerfMetric.class);
StatefulBeanToCsv<PerfMetric> beanToCsv
= new StatefulBeanToCsvBuilder<PerfMetric>(writer)
.withMappingStrategy(mappingStrategy)
.withSeparator(',')
.withApplyQuotesToAll(false)
.build();
try {
beanToCsv.write(rowData);
} catch (CsvDataTypeMismatchException e) {
e.printStackTrace();
} catch (CsvRequiredFieldEmptyException e) {
e.printStackTrace();
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Or, is the usual pattern to load all rows into a List and then re-write entire file? I was able to get it to work by writing two MappingStrategy mapping strategies and then conditionally using them with a if-file-exists but doing it that way leaves me with a "Unchecked assignment" warning in my code. Not ideal; hoping for an elegant solution?
I've updated OpenCSV to version 5.1 and got it working. In my case I needed the CSV headers to have a specific name and position, so I'm using both #CsvBindByName and #CsvBindByPosition, and needed to create a custom MappingStrategy to get it working.
Later, I needed to edit the MappingStrategy to enable appending, so when it's in Appending mode I don't need to generate a CSV header.
public class CustomMappingStrategy<T> extends ColumnPositionMappingStrategy<T> {
private boolean useHeader=true;
public CustomMappingStrategy(){
}
public CustomMappingStrategy(boolean useHeader) {
this.useHeader = useHeader;
}
#Override
public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
final int numColumns = FieldUtils.getAllFields(bean.getClass()).length;
super.setColumnMapping(new String[numColumns]);
if (numColumns == -1) {
return super.generateHeader(bean);
}
String[] header = new String[numColumns];
if(!useHeader){
return ArrayUtils.EMPTY_STRING_ARRAY;
}
BeanField<T, Integer> beanField;
for (int i = 0; i < numColumns; i++){
beanField = findField(i);
String columnHeaderName = extractHeaderName(beanField);
header[i] = columnHeaderName;
}
return header;
}
private String extractHeaderName(final BeanField<T, Integer> beanField){
if (beanField == null || beanField.getField() == null || beanField.getField().getDeclaredAnnotationsByType(CsvBindByName.class).length == 0){
return StringUtils.EMPTY;
}
//return value of CsvBindByName annotation
final CsvBindByName bindByNameAnnotation = beanField.getField().getDeclaredAnnotationsByType(CsvBindByName.class)[0];
return bindByNameAnnotation.column();
}
}
Now if you use the default constructor it'll add the header to the generated CSV, and using a boolean you can tell it to add a header or to ignore it.
I never found an answer to this question and so what I ended up doing was doing a branch if-condition where .csv file exists or not. If file exists I used MappingStrategyWithoutHeader strategy, and if file didn't yet exist, I used MappingStrategyWithHeader strategy. Not ideal, but I got it working.

How to avoid extent report to not to overwrite the html file name

I am using extent reports in appium with testng and its working fine for me.whenver my tests run is completed then extent report generates html file in my project folder and that is what expected.
Issue is that when I again run my tests then extent report generate new html report file by overwrting the name of previously created html file.
I want extent report to generate html file with unique names or name with date in in, each time when I run my tests
You can create your file name to be the current timestamp. This way, it will be easy to have a unique name for your report file -
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
extent = new ExtentReports (userDir +"\\test-output\\" + timeStamp + ".html", true);
You can do it by setting unique name:
String reportFile = resultDirectory + fileName + ".html";
than method for saving report to certain folder:
public void saveReportFolder() throws IOException {
File srcDir = new
File(System.getProperty("user.home")+"/Automation/target");
File destDir = new File(System.getProperty("user.home") + "/reports/"+ System.getProperty("user.name")+"/"+dateTimeGenerator());
FileUtils.copyDirectory(srcDir, destDir);
}
...and utility for setting dateTime:
public static String dateTimeGenerate(){
Format formatter = new SimpleDateFormat("YYYYMMdd_HHmmssSSS");
Date date = new Date(System.currentTimeMillis());
return formatter.format(date);
}
Or simply use klov reports start server and have everything in database (MongoDb), it is more elegant way to go.
Hope this helps,
I use:
private static String timestamp = new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()).replaceAll(":", "-");
public static String reportFullPath = getReportsPath() + "\\AutomationReport_" + timestamp + ".html";
I have done it like this, simple and crisp.
String Outputfilename= ExecutionConfig.FileOutname;
System.err.close(); // written to remove JAVA 9 incompatibility.. continued below
System.setErr(System.out); // continue.. and remove the warnings
extent = new ExtentReports(System.getProperty("user.dir") + "/test-output/"+Outputfilename+".html", true);
So here ExecutionConfig.FileOutname is called from the class ExecutionConfig where i am reading the values from the config.properties file. and then here assigning it to the output-file.
Also it worked for me.
I also faced a similar issue. As in the real-world, we need old reports as well. Below is the solution in Java for Extent PDF report
I added an event listener method. Event used- TestRunStarted. We further need to register for this event too. The solution can be done for HTML report too.
public void setCustomReportName(TestRunStarted event)
{
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
String currenttimestamp =sdf.format(timestamp);
Properties prop=new Properties();
//extent.reporter.pdf.out is the name of property which tell the report path
prop.setProperty("extent.reporter.pdf.out", "test output/PdfReport/ExtentPdf_"+currenttimestamp+".pdf");
ExtentService e1 =new ExtentService();
//ExtentReportsLoader is the inner class of ExtentService and initPdf is its private method which takes the path for report
Class<?>[] a=e1.getClass().getDeclaredClasses();
Method met;
//Even there is exception test run wont fail and report will also be generated (ExtentPdf.pdf)
try {
met = a[0].getDeclaredMethod("initPdf", Properties.class);
met.setAccessible(true);
met.invoke(a[0], prop);
} catch (NoSuchMethodException e) {
System.out.println("There is no method with name initPdf");
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
System.out.println("Argument passed to method initPdf are not correct");
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

Getting started with XMLPullParser

I am trying to use XMLPullParser but I cannot find any useful tutorials. Based off of the instructions on http://xmlpull.org/ I need to download an implementation of XMLPullParser as a jar file and then add it to my class path. However I cannot find any link to any jar file that works. Does anyone know where I might be able to find a jar file I can download.
Thanks
Ok, here it is for you.
From the official doc :
XmlPull API Implementations:
XNI 2 XmlPull
XPP3/MXP1
KXML2
Here i use KXML2.
Steps :
Download KXML2 jar file from here.
Create a new java project
Create a new class
Right click the java project -> Properties -> Java Build path -> Libraries -> Add external jar's -> Add downloaded kxml2 jar file.
Java code
import java.io.IOException;
import java.io.StringReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class XmlPullparserBasic {
public static void main (String args[]) throws XmlPullParserException, IOException
{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput( new StringReader ( "<foo>Hello World!</foo>" ) );
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start document");
} else if(eventType == XmlPullParser.START_TAG) {
System.out.println("Start tag "+xpp.getName());
} else if(eventType == XmlPullParser.END_TAG) {
System.out.println("End tag "+xpp.getName());
} else if(eventType == XmlPullParser.TEXT) {
System.out.println("Text "+xpp.getText());
}
eventType = xpp.next();
}
System.out.println("End document");
}
}
Output :
Hope it helps!

How to enable create / insert in a AxGridView in Enterprise Portal (Dynamics AX 2009)

There must be a way to enable creation and insertion of a record from a AxGridView without using the Tunnel and Wizard approach. From what I have found on the Internet so far, the only example is using a Wizard, and I honestly don't find that to be a user friendly approach.
Has anyone tried to enable insertion of records directly from a AxGridView?
Yes it is possible to enter data through AxGridView. Just enable Editing, deleting for that control. And one more thing to make new row - you have to make addditional button - create new line, and code behind:
protected void NewLine_Click(object sender, EventArgs e)
{
int editIdx = AxGridView1.EditIndex;
try
{
// Save the last unsaved line if any
if (AxGridView1.EditIndex != -1 && AxGridView1.Rows.Count > 0)
{
this.AxGridView1.UpdateRow(AxGridView1.EditIndex, true);
}
DataSetViewRow dsvr = this.dsv.AddNew();
}
catch (System.Exception ex)
{
AxExceptionCategory exceptionCategory;
if (!AxControlExceptionHandler.TryHandleException(this, ex, out exceptionCategory))
{
// Throw the fatal exception
throw;
}
if (exceptionCategory == AxExceptionCategory.NonFatal)
{
AxGridView1.EditIndex = editIdx;
}
}
}
private DataSetView dsv //get dataset view
{
get
{
DataSet dataSet = this.AxDataSource1.GetDataSet();
return dataSet.DataSetViews[this.AxGridView1.DataMember];
}
}

Resources