Get Column Names in HBase Thrift C++? - visual-c++

I need to get the list of column qualifiers available in a HBase table.
Suppose I have a table 'Customers' with column 'info:Age' and 'contact:PhoneNo'. To get the list of column families I see there's a method 'getColumnDescriptors' which returns the value 'info' and 'contact'.
But how to retrieve the full column names 'info:Age' and 'contact:PhoneNo' from the table or atleast the qualifiers 'Age' and 'PhoneNo' alone.
With the method 'getRowWithColumns' I am able to get the list of column names where I have to pass the row key value.
Will I be able to achieve this through any other convenient way?

Here is a working solution in Java as you asked, you just have to change a few things to translate it to C++.
Basically this method will scan the table and retrieves the column qualifiers, then I add them into a list if this list does not already contains it.
Here, I look at all the rows, but if all your rows always have the same columns, you can just scan the first row, using a Get for example (look at the HBase documentation, I've written several examples there).
public ArrayList<String> getColumnName(String tablename) {
ArrayList<String> properties = new ArrayList<String>();
try {
Table table = this.connection.getTable(TableName.valueOf(tablename));
Scan scan = new Scan();
ResultScanner rs = table.getScanner(scan);
try {
for (Result r = rs.next(); r != null; r = rs.next()) {
for (Cell c : r.rawCells()) {
String family = new String(CellUtil.cloneFamily(c));
String qualifier = new String(CellUtil.cloneQualifier(c));
System.out.println("Column Family : "+ family);
System.out.println("Column Qualifier : " + qualifier);
if (!properties.contains(qualifier))
properties.add(new String(CellUtil.cloneQualifier(c)));
}
}
} finally {
rs.close(); // always close the ResultScanner!
}
} catch (IOException e) {
e.printStackTrace();
}
return properties;
}

Related

Value does not fall within the expected range - Exception for SharePoint Lookup Field

I am trying to copy data from one list to other list (both lists are on different sites) along with lookup columns. But, I am getting an error for lookup field as:
Value does not fall within the expected range
Code works and data gets copied for other non-lookup fields. I tried every possible way including increasing List View Lookup Threshold and all possible ways of code but still error persists at ExecuteQuery().
Below is my code for lookup field:
if (field is FieldLookup && field.InternalName == "Country")
{
var CountryLookup = (item.FieldValues["Country"] as FieldLookupValue).LookupValue.ToString();
var CountryLookupId = (item.FieldValues["Country"] as FieldLookupValue).LookupId.ToString();
FieldLookupValue flvRDS = new FieldLookupValue();
flvRDS.LookupId = int.Parse(CountryLookupId);
itemToCreate["Country"] = flvRDS;
itemToCreate.Update();
destContext.ExecuteQuery();
}
Help is really appreciated.
I assume item is the new ListItem you're trying to create on your target list.
But you're never in fact reading any value from field here! So basically, you're trying to set your new FieldLookup.LookupId with the item["Country"].LookupId, which should logically be empty at this moment.
Here's a method I use to retrieve a lookup field ListItem from a value, feel free to modify it to fit your need, since I don't know how you want to retrieve it (SPList is an alias for Microsoft.SharePoint.Client.List).
private ListItem GetLookupItem(FieldLookup lookupField, string lookupValue)
{
string mappingField = lookupField.LookupField;
Microsoft.SharePoint.Client.List lookupList = Context.Web.Lists.GetById(new Guid(lookupField.LookupList));
Context.Load(lookupList);
Context.ExecuteQuery();
ListItemCollection libListItems = lookupList.GetItems(CamlQuery.CreateAllItemsQuery());
Context.Load(libListItems, items => items.Include(
itemlookup => itemlookup.Id,
itemlookup => itemlookup[mappingField]));
Context.ExecuteQuery();
foreach (ListItem mappedItem in libListItems)
{
object mappedField = mappedItem[mappingField];
if (mappedField != null && mappedField.ToString().Equals(lookupValue))
return mappedItem;
}
return null;
}
Now that you have the corresponding ListItem, you can set your item.LookupId with its Id:
if (field is FieldLookup && field.InternalName == "Country")
{
FieldLookupValue flvRDS = new FieldLookupValue();
flvRDS.LookupId = GetLookupItem(field as FieldLookup, "France").Id; // here, dunno how you get your country's name
itemToCreate["Country"] = flvRDS;
itemToCreate.Update();
destContext.ExecuteQuery();
}
Feel free to add some more previous code if you want an answer more suited for your specific issue.

Find distinct values from column of datatable in c# and store distinct values in variables

i want to find distinct values from a column of datatable in c# and also want to store all these distinct values in variables
DataTable dtable = new DataTable();
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * from clubbb ", con);
da.Fill(dtable, "clubbb");
int toto = bdtable.AsEnumerable().Distinct().Count();
You need to implement the interface IEqualityComparer<DataRow> methods to provide the way the Distinct method will use to know whether 2 rows are duplicate or not. This can be achieved with a class like this:
public class CustomComparer : IEqualityComparer<DataRow>
{
public bool Equals(DataRow x, DataRow y)
{
// your custom equality logic here
}
public int GetHashCode(DataRow obj)
{
// return hash code depending on your distinct criteria
}
}
Then change the call you made:
int toto = bdtable.AsEnumerable().Distinct(new CustomComparer()).Count();
I had similar problem, and in my case I needed to know distinct values of specific column, so I passed the name of this column to the custom comparer I implemented, so that GetHashCode will return identical hash codes for duplicate values.
You can read more here: https://msdn.microsoft.com/en-us/library/ms132151(v=vs.110).aspx
Hope this helps :)

Scanning HBase based on two cells

Let's say I have two HBase cells:
x:y
x:z
How do I do the equivalent of this SQL:
SELECT * FROM some_table WHERE x_y = ? AND x_z = ?
This is the (Groovy) code I have for generating the basic filters:
static SingleColumnValueFilter makeColumnFilter(String family, String qualifier, String expectedValue) {
new SingleColumnValueFilter (
Bytes.toBytes(family),
Bytes.toBytes(qualifier),
CompareFilter.CompareOp.valueOf('EQUAL'),
new SubstringComparator(expectedValue))
}
def filterz = filters.collect {
makeColumnFilter(it.family, it.qualifier, it.expectedValue)
}
def fl = new FilterList(filterz)
def scan = new Scan()
scan.setFilter(fl)
def family = 'x'.bytes
t.getScanner(scan).each {
println "${Bytes.toString(it.getValue(family, 'y'.bytes))}"
count++
}
The print statement shows nothing but nulls even though I'm passing in x for the family value and y/z for the qualifiers. It appears to not be filtering the values. What am I doing wrong?
You need to filter the rows if the column is not found using setFilterIfMissing.
Change the makeColumnFilter to :
static SingleColumnValueFilter makeColumnFilter(String family, String qualifier, String expectedValue) {
def colFilter = new SingleColumnValueFilter (
Bytes.toBytes(family),
Bytes.toBytes(qualifier),
CompareFilter.CompareOp.valueOf('EQUAL'),
new SubstringComparator(expectedValue))
colFilter.setFilterIfMissing(true)
colFilter
}
I think SingleColumnValueExcludeFilter should do the job.
Scan scan = new Scan();
SingleColumnValueExcludeFilter singleColumnValueFilterY = new SingleColumnValueExcludeFilter("x".getBytes(),
"y".getBytes(), CompareOp.EQUAL, new BinaryComparator("valueY".getBytes()), true, true);
SingleColumnValueExcludeFilter singleColumnValueFilterZ = new SingleColumnValueExcludeFilter("x".getBytes(),
"z".getBytes(), CompareOp.EQUAL, new BinaryComparator("valueZ".getBytes()), true, true);
FilterList filterList = new FilterList(Operator.MUST_PASS_ALL);
filterList.addFilter(singleColumnValueFilterX);
filterList.addFilter(singleColumnValueFilterY);
scan.setFilter(filterList);
More detailed documentation on HBase filters could be found here.
Hope this will help.

Returning an Object[][] gives NullPointerException

I have an Access database which I need to retrieve all fields except the first and last and display it in a JTable. Everything works perfectly fine when I create my Object[][] but when i return it, i get a NullPointerException. I tried to find where there could be a null value in the database by printing the whole object out but that works fine and no values are null. Why would returning the Object[][] give me a NullPointerException and how can i fix it?
the stack trace is:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
public Object [] [] SetTrainingLogTable() throws SQLException
{
DatabaseConnection connection = new DatabaseConnection();
//Retrieves all the data from the TrainingLog table
ResultSet resultset = connection.SelectStatements("SELECT * FROM TrainingLog");
//Retrieves the number of entries
ResultSet numberofworkouts = connection.SelectStatements("SELECT COUNT(*) FROM TrainingLog");
int count = numberofworkouts.getInt(1);
number = count;
String[][] table = new String [count] [6];
//Number to incriment for while loops
int row = 0;
String date = "";
while(row<count)
{
date = resultset.getString(2);
table [row][0] = calculate.RefineDate(date);
table [row][1] = resultset.getString(3);
table [row][2] = resultset.getString(4);
table [row][3] = resultset.getString(5);
table [row][4] = resultset.getString(6);
table [row][5] = resultset.getString(7);
resultset.next();
row++;
}
Object[][] data = table;
connection.close();
return data;
}
I ran a debugger and it only gives the error when the return line is run.
It's best to post the stack trace and tell which line is raising the error. However, the typical way of writing such code is:
Connection con = ...;
Statement st = ...;
ResultSet rs = ...;
while (rs.next()) {
// ...
}
The result set starts out pointing before the first row. rs.next() returns whether there is a next row, and advances to it if it exists. Can you rewrite it in that style?
Other suggestions:
Can you create an actual object type instead of using Object[] to store the data from each row? Call it Workout.
Can you use a List<Workout> instead of your Object[][]?
Is the date stored in the database as a SQL DATE or TIMESTAMP? Then, don't convert it to a Java String: use java.sql.Date or java.util.Date. At work, I have a large old program that uses strings for dates, and it uses different formats to convert the values at different times. It's pretty miserable.
Don't use SELECT *. Give the names of the columns to return. Use the rs.getString("column_name") syntax.
There's no need to set one variable to the returned table and immediately set another variable to it.
Closing the connection or statement should be done in a finally block, or by try-with-resources.

Programmatically access external list associated column

Hi I have 2 external lists 'A' and 'B'. with an associated column in A, that looks up for B.
When i view/edit item in browser, it shows correct values as shown in picture below.
But when i try to access the list in code, i can access all column values, but associated column value comes null.
The code look something like this :
items = listReports.GetItems();
System.Collections.Generic.List<ReportItem> reportItems = new List<ReportItem>();
foreach (SPListItem it in items)
{
if (it != null)
{
ReportItem item = new ReportItem();
// extItem comes null
var extItem = it["ExtCol"];
// extItem comes null
DateTime date;
if (DateTime.TryParse(it["GeneratedOn"].ToString(), out date))
{
item.dateGenerated = date.Date;
}
DateTime time;
if (DateTime.TryParse(it["GeneratedOn"].ToString(), out time))
{
item.timeGenerated = time.Date;
}
reportItems.Add(item);
}
}
I'm not sure, but, "ExtCol" - is that rigth name for field in your external type? For external items sharepoint may substitute a name of external item/column in the source field name.

Resources