Make cursor corresponding array with multiple rows followed by same row id's - arrays

I have a DB in which id's are change after few rows, then same I'd in some rows then change I'd. What I want that, the same I'd values will be populated listview's in one line, then when the Ids are same, they are all in one row. And thus the next rows populate with same rows which have same ID's.
My DB columns and rows are as follows:
Verse_id -------words_id----------words_ar------ translate_bn--
1-----------------------1---------------Mamun-----------Assistant---
1-----------------------2--------------- Salam------------Operator------
1-----------------------3---------------John--------------Assistant------
2 ----------------------1--------------- Smith-------------Manager------
2-----------------------2---------------Roger--------------Director--------
3-----------------------1---------------Qoel---------------Helper----------
3-----------------------2---------------Saki---------------Mechanics-----
3-----------------------3----------------Ali-----------------Getman----------
I want this DB in three lines, as follows : (listview):
1. Mamun. Salam John
Assistant. Operator. Assistant
------------------------------------------------------------------
2. Smith. Roger.
Manager. Director
------------------------------------------------------------------
3. Qoel. Saki. Ali.
Helper. Mechanics. Getman
I have Tried in Two way :
First :
private static final String PRIMARY_ID = "_id";
private static final String TABLE_NAME = "bywords";
private static final String FRIEND_ID = "verse_id";
private static final String WORDS_ID = "words_id";
private static final String WORDS_bN = "translate_bn";
private static final String WORDS_AR = "words_ar";
private SQLiteDatabase database;
private ArrayList<String> friends;
private ArrayList<String> trans1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
mContext = this;
ExternalDbOpenHelper dbOpenHelper = new ExternalDbOpenHelper(this, DB_NAME);
database = dbOpenHelper.openDataBase();
Cursor cursor = database.rawQuery("SELECT * FROM bywords", null);
ListView list4=(ListView)findViewById(R.id.list4) ;
String[] from = {WORDS_AR }; // _id mandatory
int[] to = new int[]{R.id.alquran_text};
CursorAdapter adapter = new SimpleCursorAdapter(
mContext,
R.layout.list_item,
cursor,
from,
to,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
list4.setAdapter(adapter);
And Then Second :
trans1 = new ArrayList<String>();
String[] allColumns2 = new String[] { FRIEND_ID,
BN_TRANS };
Cursor friendCursor2 = database.query(TABLE_NAME, allColumns2, null,
null, null, null, null);
if (friendCursor2 != null) {
friendCursor2.moveToFirst();
}
//return friendCursor;
if(!friendCursor2.isAfterLast()) {
do {
String name = friendCursor2.getString(1);
trans1.add(name);
} while (friendCursor2.moveToNext());
}
friendCursor2.close();
String [] bntrans1= new String[trans1.size()];
bntrans1 = trans1.toArray(bntrans1);
ListAdapter adapter = new ArrayAdapter<String>(
getApplicationContext(), R.layout.alert_row, seleted_route) {
ViewHolder holder;
Drawable icon;
class ViewHolder {
ImageView icon;
TextView title;
TextView title2;
}
public View getView(int position, View convertView,
ViewGroup parent) {
final LayoutInflater inflater = (LayoutInflater) getApplicationContext()
.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(
R.layout.alert_row, null);
holder = new ViewHolder();
//holder.icon = (ImageView) convertView
// .findViewById(R.id.icon4);
holder.title = (TextView) convertView
.findViewById(R.id.title4);
holder.title2 = (TextView) convertView
.findViewById(R.id.title2);
convertView.setTag(holder);
} else {
// view already defined, retrieve view holder
holder = (ViewHolder) convertView.getTag();
}
Drawable drawable = getResources().getDrawable(R.drawable.iqra1); //this is an image from the drawables folder
holder.title.setText(seleted_route[position]);
holder.title2.setText(seleted_route[position]);
//holder.icon.setImageDrawable(drawable);
return convertView;
}
};
By the second way I can populate two column in two text view in one rows. But what I want that the corresponding rows with same id of rows must populate in one line of listview with verse I'd. The id's whataver are same in rows may be 5, 10 or twenty rows same id. Whenever the same Id They are one line, When the Id change the newline begins.

Related

Create string array from SQLite database column in Android Studio

I have created an app with an SQLite database and a ListView that I want to populate using the database. To do this I have written an adapter class called HomeListAdapter. This class takes 4 string arrays as input and that is where my problem is. At first, I just used random string arrays to populate the ListView by typing them myself, for example:
String[] homelist_name_short = {
"Flower", "Bush", "Tree"};
String[] homelist_name_long = {
"Red rose", "Berry bush", "Oak"};
String[] homelist_date = {
"20-9-2017", "11-10-2017", "12-10-2017"};
String[] homelist_price = {
"€1.50", "€2.48", "€0.68"};
Now I want this to be put into the listview automatically and to do that I have written the code that can be seen below..
I have created a class called Home:
public class Home {
private String mShortHomeName;
private String mLongHomeName;
private String mHomeDate;
private String mHomePrice;
public Home(String ShortName, String LongName, String Date, String Price) {
this.mShortHomeName = ShortName;
this.mLongHomeName = LongName;
this.mHomeDate = Date;
this.mHomePrice = Price;
}
public String getShortName() {
return this.mShortHomeName;
}
public String getLongName() {
return this.mLongHomeName;
}
public String getDate() {
return this.mHomeDate;
}
public String getPrice() {
return this.mHomePrice;
}
}
Added the following to my DatabaseHelper:
public Cursor getAllHomesAsCursor() {
SQLiteDatabase db = this.getWritableDatabase();
String[] columns = {"rowid as _id","*"};
return db.query(TABLE_NAME,columns,null,null,null,null,null);
}
The following to the activity that contains my listview:
DatabaseHelper db = new DatabaseHelper(getActivity());
Cursor csr = db.getAllHomesAsCursor();
HLAdapter adapter = new HLAdapter(getActivity(), csr);
listView.setAdapter(adapter);
The HLAdapter looks as follows:
public class HLAdapter extends CursorAdapter {
public HLAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor csr, ViewGroup parent) {
return LayoutInflater.from(context).inflate(
R.layout.homelist_listview_layout,
parent,
false
);
}
#Override
public void bindView(View view, Context context, Cursor csr) {
TextView sname = (TextView) view.findViewById(R.id.homelist_name_short);
TextView lname = (TextView) view.findViewById(R.id.homelist_name_long);
TextView date = (TextView) view.findViewById(R.id.homelist_date);
TextView price = (TextView) view.findViewById(R.id.homelist_price);
sname.setText(csr.getString(csr.getColumnIndex("name_short")));
lname.setText(csr.getString(csr.getColumnIndex("name_long")));
date.setText(csr.getString(csr.getColumnIndex("date")));
price.setText(csr.getString(csr.getColumnIndex("price")));
}
}
My DatabaseHelper class looks as follows:
public class DatabaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "Main.db";
public static final String TABLE_NAME = "current_table";
public static final String COL_1 = "name_short";
public static final String COL_2 = "name_long";
public static final String COL_3 = "date";
public static final String COL_4 = "price";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME + " (name_short TEXT,name_long TEXT, due_date TEXT, price TEXT) ");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public Cursor getAllHomesAsCursor() {
SQLiteDatabase db = this.getWritableDatabase();
String[] columns = {"rowid as _id","*"};
return db.query(TABLE_NAME,columns,null,null,null,null,null);
}
public boolean insertData(String name_short, String name_long, String due_date, String price) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_1,name_short);
contentValues.put(COL_2,name_long);
contentValues.put(COL_3,due_date);
contentValues.put(COL_4,price);
long result = db.insert(TABLE_NAME,null,contentValues);
if(result == -1)
return false;
else
return true;
}
public void deleteAllData() {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_NAME);
}
public Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("SELECT * FROM " + TABLE_NAME ,null);
return res;
}
public Cursor getSpecifiedColumnData(String column) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("SELECT column FROM " + TABLE_NAME,null);
return res;
}
}
I would think that my code should be working fine, but when I run the app. It closes immediately. Can you tell me what the problem is?
I believe the issue is that you need 4 String arrays to be passed to the adapter, so doing it like above you'd need to have a unique equivalent of getAllData for each type.
However considering that a house has a short name, long name, date and price a better approach could to consider all of these properties as an object and thus create a class. You could then create a List not of String objects but as a List of House objects, you'd be able to get them all in one go etc.
So (P.S. for the sake of my sanity I've incorporated the SO4522191 into the following so I can keep some sort of track of the code) :-
1) Create your Home Object to hold all values/properties of a house:-
1-a) Create a file the same as your home name, it's going to be a java class file.
In this case I've called it SO45422191Home, the code could be along the lines of :-
public class SO45422191Home {
private String mShortHomeName;
private String mLongHomeName;
private String mHomeDate;
private String mHomePrice;
public SO45422191Home(String ShortName, String LongName, String Date, String Price) {
this.mShortHomeName = ShortName;
this.mLongHomeName = LongName;
this.mHomeDate = Date;
this.mHomePrice = Price;
}
public String getShortName() {
return this.mShortHomeName;
}
public String getLongName() {
return this.mLongHomeName;
}
public String getDate() {
return this.mHomeDate;
}
public String getPrice() {
return this.mHomePrice;
}
}
Explanation
Using the above we can create a SO45422191Home object, in code elsewhere e.g. in your activity, by using something
like SO45422191Home Myhome = new SO45422191Home("Flower","Red
Rose","20-9-2017","1.50");.
With the MyHome object you can extract the properties e.g.
MyHome.getPrice() would return a String with a value of 1.50.
Similar for the other properties.
You can create an array of objects e.g. SO45422191Home[] homes = new
SO45422191Home[3]; will create an array of 3 (empty) SO45422191Home
objects. We could set the first element of the array using homes[0] =
new SO45422191Home("Bush","Cherry","11-10-2017","2.48");
2) Create a means of getting an array of SO45422191Home objects from the database.
here's some code for this:-
public List<SO45422191Home> getAllHomes() {
List<SO45422191Home> rv = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor csr = db.query(HOMETABLE,null,null,null,null,null,null);
while (csr.moveToNext()) {
SO45422191Home h = new SO45422191Home(
csr.getString(csr.getColumnIndex(SHORTHOMENAME)),
csr.getString(csr.getColumnIndex(LONGHOMENAME)),
csr.getString(csr.getColumnIndex(HOMEDATE)),
csr.getString(csr.getColumnIndex(HOMEPRICE))
);
rv.add(h);
}
csr.close();
return rv;
}
Explanation You used List and added elements to the list, List is similar but for SO45422191Home objects rather
than String objects.
The Database is opened, if not already open, using SQLiteDatabase db
= this.getWritableDatabase();.
All rows are extracted into a cursor.
The cursor is traversed each row at a time.
For each row a SO45422191Home object is created by getting the respective data from the cursor
(Note that csr.getColumnIndex(columnname) is used
rather than hard coding the column's index/offset, doing so can reduce
the chance for errors and also reduce overheads should changes be
applied.).
The the new object is added to the list.
Obviously column names would have to be adjusted, you may also want to add db.close() before the return.
3) Amend your adapter to take and use the the single list of objects rather than the 4 List.
here's an example adapter for use by a List (Note that R.layout.homeentry is the layout used for each entry in the ListView), the layout is below in the section re Cursor Adapter:-
public class AdapterHomeList2 extends ArrayAdapter {
List<SO45422191Home> homes;
LayoutInflater lInflater;
public AdapterHomeList2(Context context, List<SO45422191Home> homes) {
super(context,R.layout.homeentry, homes);
lInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.homes = homes;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.homeentry, parent, false);
}
TextView sname = (TextView) view.findViewById(R.id.shortname);
TextView lname = (TextView) view.findViewById(R.id.longname);
TextView date = (TextView) view.findViewById(R.id.date);
TextView price = (TextView) view.findViewById(R.id.price);
sname.setText(homes.get(position).getShortName());
lname.setText(homes.get(position).getLongName());
date.setText(homes.get(position).getDate());
price.setText(homes.get(position).getPrice());
return view;
}
}
This is the code for an ArrayList :-
public class AdapterHomeList3 extends ArrayAdapter {
ArrayList<SO45422191Home> homes;
LayoutInflater lInflater;
public AdapterHomeList3(Context context, ArrayList<SO45422191Home> homes) {
super(context,R.layout.homeentry, homes);
lInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.homes = homes;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.homeentry, parent, false);
}
TextView sname = (TextView) view.findViewById(R.id.shortname);
TextView lname = (TextView) view.findViewById(R.id.longname);
TextView date = (TextView) view.findViewById(R.id.date);
TextView price = (TextView) view.findViewById(R.id.price);
sname.setText(homes.get(position).getShortName());
lname.setText(homes.get(position).getLongName());
date.setText(homes.get(position).getDate());
price.setText(homes.get(position).getPrice());
return view;
}
}
Using a CursorAdapter
1) Add a new method to extract a cursor with all rows (NOTE! for cursor adapter a row named _id is required)
public Cursor getAllHomesAsCursor() {
SQLiteDatabase db = this.getWritableDatabase();
String[] columns = {"rowid as _id","*"};
return db.query(HOMETABLE,columns,null,null,null,null,null);
}
Note! instead of all columns i.e. coding null as the second parameter
to 'query' (which doesn't get the hidden rowid column (assuming
WITHOUT ROWID hasn't been used)), will will get the rowid (a unqiue
row identifier) and name this AS _id to suite the Cursor Adapter
hence "rowid as _id", the following * as the second element of
the columns array means all rows (specifying null as 2nd parameter
result in SELECT * .....).
Otherwise it's pretty simple. NOTE you must not close the database,
otherwise you can't access the cursor.
2) You will need a layout for each item in the list, as you would for a custom array adapter and it can be the same one i.e. there are no diferences according to which adapter is used. e.g. I created :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/shortname"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/longname"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/date"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/price"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
</LinearLayout>
3) Create The Cursor Adpater as a class file, very similar to an Array Adapter.
public class AdapterHomeList extends CursorAdapter {
public AdapterHomeList(Context context, Cursor cursor) {
super(context, cursor,0);
}
#Override
public View newView(Context context, Cursor csr, ViewGroup parent) {
return LayoutInflater.from(context).inflate(
R.layout.homeentry, //<< layout for each list item
parent,
false
);
}
#Override
public void bindView(View view, Context context, Cursor csr) {
TextView sname = (TextView) view.findViewById(R.id.shortname);
TextView lname = (TextView) view.findViewById(R.id.longname);
TextView date = (TextView) view.findViewById(R.id.date);
TextView price = (TextView) view.findViewById(R.id.price);
sname.setText(csr.getString(csr.getColumnIndex(SO45422191.SHORTHOMENAME)));
lname.setText(csr.getString(csr.getColumnIndex(SO45422191.LONGHOMENAME)));
date.setText(csr.getString(csr.getColumnIndex(SO45422191.HOMEDATE)));
price.setText(csr.getString(csr.getColumnIndex(SO45422191.HOMEPRICE)));
}
}
Note! R.layout.homeentry being the layout for the list entries
and id's are from this.
4) From the respective activity, get the cursor, get an instance of the adapter and set the ListView to use the adapter.
e.g.:-
Cursor csr = dbhlp.getAllHomesAsCursor();
AdapterHomeList ahl = new AdapterHomeList(this,csr);
ListView hl = (ListView) this.findViewById(R.id.homelist);
hl.setAdapter(ahl);
result :-
Using cursor.getColumnIndex()
getColumnIndex
int getColumnIndex (String columnName)
Returns the zero-based index for the given column name, or -1 if the
column doesn't exist. If you expect the column to exist use
getColumnIndexOrThrow(String) instead, which will make the error more
clear.
SQLiteCursor
Using getColumnIndex as opposed to specifying the index removes the need to manually determine column offsets.
For example purposes, there is a table, named items with 3 columns, named as name, date and price :-
Using a query that uses the equivalent of SELECT * FROM items, the query will return a cursor with 3 columns, name, date and price
column name would have an offset of 0.
column date would have an offset of 1.
column price would have an offset of 2.
To extract the date from the cursor you could code cursor.getString(1);
However, if you were to have a query based upon SELECT date, price, name FROM items then the offsets would be:-
column name would have an offset of 2.
column date would have an offset of 0.
column price would have an offset of 1.
In this case you'd have to code cursor.getString(0); to extract the date.
It could be easy to inadvertently code the wrong offset, especially when using larger tables or when joining tables or when introducing generated columns.
Using cursor.getString(cursor.getColumnIndex("date")); could be used in both situations as it would return 1 in the first case and 0 in the second case.
Above, as an example, sname.setText(csr.getString(csr.getColumnIndex(SO45422191.SHORTHOMENAME))); has been coded.
Home.SHORTHOMENAME is a class varaible defined in the Database Helper (i.e. SO45422191 is the DatabaseHelper Class and SHORTHOMENAME is the class variable) that equates to the column name of the respective column as can be seen from the Database Helper code extract:-
public class SO45422191 extends SQLiteOpenHelper {
public static final String DBNAME = "SO45422191";
public static final String HOMETABLE = "homes";
public static final String SHORTHOMENAME = "shorthomename";
public static final String LONGHOMENAME = "longhomename";
public static final String HOMEDATE = "homedate";
public static final String HOMEPRICE = "homeprice";
// constructor
public SO45422191(Context context) {
super(context, DBNAME , null , 1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table " + HOMETABLE +
"(" +
SHORTHOMENAME + " TEXT, " +
LONGHOMENAME + " TEXT, " +
HOMEDATE + " TEXT, " +
HOMEPRICE + ")");

loaderManager recyclerview imageview viewholder content provider fails

I am new at android and new at posting here and trying a sink in slowly but am stuck here at inflating imageViews. Below am providing code snippets from my app that i would thank you for your help
Here is my table
private static final String CREATE_TABLE = "CREATE TABLE "+TABLE_NAME+" ("+KEY_ID,"+KEY_PROFILEPIC+" BLOB,"+KEY_IMAGE+" BLOB)";
this is my viewholder class
`public CityHolder(final View view) {
super(view);
ButterKnife.bind(this, itemView); }
public void bindData(final Cursor cursor) {
String name = cursor.getString(cursor.getColumnIndex("name"));
this.name.setText(name);
String CircularNetWorkImageView =cursor.getString(cursor.getColumnIndex("profilePic"));
this.CircularNetWorkImageView.setText(CircularNetWorkImageView);
}
`
and then i am using recyclerview to bind to cursor.
am also using a a content Provider to both insert and then retrieve data and load by use of the LoaderManager.LoaderCallbacks
here is how i get the data through volley json
JSONArray jsonArray = response.getJSONArray("city");
for (int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObjectCity = jsonArray.getJSONObject(i);
String name = jsonObjectCity.getString("name");
String profilePic = jsonObjectCity.getString("profilePic");
String image = jsonObjectCity.getString("image");
City city = new City();
city.setName(name);
city.setProfilePic(profilePic);
city.setImage(image);
ContentValues values = new ContentValues();
values.put(CityDb.KEY_NAME, name);
values.put(CityDb.KEY_PROFILEPIC, profilePic);
values.put(CityDb.KEY_IMAGE, image);
getContentResolver().insert(CityContentProvider.CONTENT_URI, values);
}
}catch(JSONException e){e.printStackTrace();}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley","Error");
}
}
);
requestQueue.add(jor);
}
#Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
String[] allColumns = new String[] {
CityDb.KEY_ID,
CityDb.KEY_NAME,
CityDb.KEY_PROFILEPIC,
CityDb.KEY_IMAGE
};
return new CursorLoader(this,CityContentProvider.CONTENT_URI,allColumns, null, null, null);
}`
Now the String Name is displayed in my fragment but am having issue getting the image and profilePic in circularNetworkimageView to display.
what could i be missing, please guide me

javaFX - tableview getting selected items

How can I get a selected item in a row from tableview in javaFX with Sqlite Database.
I am now using this to get the Index of the row:
(...)
#FXML
private ObservableList<UserData> data;
#FXML
private TableView table;
#FXML
private void pressTableAction() {
System.out.println("Selected index: " +table.getSelectionModel().getSelectedIndex());
}
(...)
public void initialize (URL url, ResourceBundle rb) {
try {
con = DataBaseConnection.getConnected();
stat = con.createStatement();
data = FXCollections.observableArrayList();
ResultSet rs = con.createStatement().executeQuery("SELECT * FROM person");
while (rs.next()) {
data.add(new UserData(rs.getInt("p_id"), rs.getString("Name")));
}
column1.setCellValueFactory(new PropertyValueFactory("p_id"));
column2.setCellValueFactory(new PropertyValueFactory("Name"));
table.setItems(null);
table.setItems(data);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
Public static class UserData {
private IntegerProperty p_id;
private StringProperty Name;
private UserData(Integer p_id, String Name) {
this.p_id = new SimpleIntegerProperty (p_id);
this.Name = new SimpleStringProperty(Name);
}
public IntegerProperty p_idProperty() {
return p_id;
}
public StringProperty NameProperty() {
return Name;
}
}
My db looks like this:
CREATE TABLE person (p_id INTEGER PRIMARY KEY AUTOINCREMENT, Name VARCHAR(30) NOT NULL);
How can I get the p_id or the Name of the row I clicked?
#FXML
private void pressTableAction() {
System.out.println("Selected index: " + table.getSelectionModel().getSelectedIndex());
System.out.println("Selected p_id: " + ????)
}
First, do not use raw types for your table and table columns. Your IDE should be generating lots of warnings for this. So you should do
#FXML
TableView<UserData> table ;
instead of the declaration you have. Similarly the columns should be declared with the appropriate types.
If your model class UserData follows the standard JavaFX properties pattern, it will have a getP_id() method, and you can do
UserData selected = table.getSelectionModel().getSelectedItem();
System.out.println("Selected p_id: "+selected.getP_id());

SSIS - OleDBDataAdapter Fill Method not Filling data table

I'm trying to fill a data table with a object variable in SSIS but I'm having problem doing so. The first time a row passes the script component, the data table gets filled but, when the next rows passes through the script, the code doesn't fill the dataset and the whole script doesn't do its job correctly. Any help with this issue?
ScriptComponent Code
Main.cs
/// <summary>
/// This method is called once for every row that passes through the component from Input0.
///
/// Example of reading a value from a column in the the row:
/// string zipCode = Row.ZipCode
///
/// Example of writing a value to a column in the row:
/// Row.ZipCode = zipCode
/// </summary>
/// <param name="Row">The row that is currently passing through the component</param>
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
OleDbDataAdapter sc = new OleDbDataAdapter();
DataTable dt = new DataTable();
sc.Fill(dt, Variables.SpecialCharacter); //Problem occurs here, Fill method doesn't fill after first row is processed by the script.
List<StringValidation> listObj = new List<StringValidation>();
foreach (DataRow row in dt.Rows)
{
object[] array = row.ItemArray;
StringValidation varObj = new StringValidation();
varObj.SourceCharacter = array[0].ToString();
varObj.TargetCode = array[1].ToString();
listObj.Add(varObj);
}
StringValidation obj = new StringValidation();
Row.ADDRL1 = obj.RemoveInvalidCharacter(Row.ADDRL1, listObj, "ADDRL1");
Row.ADDRL2 = obj.RemoveInvalidCharacter(Row.ADDRL2, listObj, "ADDRL2");
}
StringValidation.cs
public class StringValidation
{
public string SourceCharacter { get; set; }
public string TargetCode { get; set; }
public string RemoveInvalidCharacter(string text, List<StringValidation> listObj, string ColumnName)
{
foreach (StringValidation obj in listObj)
{
if (text.Contains(obj.SourceCharacter))
{
text = text.Replace(obj.SourceCharacter, obj.TargetCode);
}
}
return text;
}
}
Move code that only has to run once to PreExecute()
Try moving the DataTable filling into the PreExecute() method. It only needs to be loaded once, so any problems caused by multi-loading should go away if you do this. See my code (and comments) below.
/* Turn adapter and table into member variables */
OleDbDataAdapter sc = new OleDbDataAdapter();
DataTable dt = new DataTable();
public override void PreExecute()
{
/* Fill data table in PreExecute(). Only needs to be loaded once. If it only works the first time this should fix it. */
sc.Fill(dt, Variables.SpecialCharacter);
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
List<StringValidation> listObj = new List<StringValidation>();
foreach (DataRow row in dt.Rows)
{
object[] array = row.ItemArray;
StringValidation varObj = new StringValidation();
varObj.SourceCharacter = array[0].ToString();
varObj.TargetCode = array[1].ToString();
listObj.Add(varObj);
}
StringValidation obj = new StringValidation();
Row.ADDRL1 = obj.RemoveInvalidCharacter(Row.ADDRL1, listObj, "ADDRL1");
Row.ADDRL2 = obj.RemoveInvalidCharacter(Row.ADDRL2, listObj, "ADDRL2");
}
And try this for performance improvement and cleaner code
You'd probably get even better performance if you moved all that into the PreExecute() section (see below). I also used Linq to simplify creating your List() object.
/* Don't forget to add using System.Linq; at the top of the page. */
List<StringValidation> stringValidations;
public override void PreExecute()
{
OleDbDataAdapter sc = new OleDbDataAdapter();
DataTable dt = new DataTable();
sc.Fill(dt, Variables.SpecialCharacter);
stringValidations = (from scRow in dt.Rows
select new StringValidation
{
SourceCharacter = scRow[0].ToString(),
TargetCode = scRow[1].ToString()
}).ToList();
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
List<StringValidation> listObj = new List<StringValidation>();
StringValidation obj = new StringValidation();
Row.ADDRL1 = obj.RemoveInvalidCharacter(Row.ADDRL1, stringValidations, "ADDRL1");
Row.ADDRL2 = obj.RemoveInvalidCharacter(Row.ADDRL2, stringValidations, "ADDRL2");
}

Load spesific string from clicked list view?

i have fragment with listview
myfragment :
public class LightFragment extends Fragment {
String[] name;
String[] type;
String[] swim;
int[] flag;
ListView list;
ListViewAdapter adapter;
public LightFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_light, container, false);
name = getResources().getStringArray(R.array.sport);
type = new String[] { "China", "India", "United States",
"Indonesia", "Brazil" };
swim = new String[] { "1,354,040,000", "1,210,193,422",
"315,761,000", "237,641,326", "193,946,886" };
flag = new int[] { R.drawable.light11,
R.drawable.light12,
R.drawable.light21,
R.drawable.light22,
R.drawable.light23,
R.drawable.light24,
R.drawable.light25,
R.drawable.light26,
R.drawable.light27 };
// Locate the ListView in fragmenttab1.xml
list = (ListView) rootView.findViewById(R.id.listview);
// Pass results to ListViewAdapter Class
adapter = new ListViewAdapter(getActivity(), name, type, swim,
flag);
// Binds the Adapter to the ListView
list.setAdapter(adapter);
// Capture clicks on ListView items
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Send single item click data to SingleItemView Class
Intent i = new Intent(getActivity(), SingleItemView.class);
// Pass all data rank
i.putExtra("rank", name);
// Pass all data country
i.putExtra("country", type);
// Pass all data population
i.putExtra("population", swim);
// Pass all data flag
i.putExtra("flag", flag);
// Pass a single position
i.putExtra("position", position);
// Open SingleItemView.java Activity
startActivity(i);
}
});
return rootView;
}
}
Listviewadapter :
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
String[] rank;
String[] country;
String[] population;
int[] flag;
LayoutInflater inflater;
public ListViewAdapter(Context context, String[] rank, String[] country,
String[] population, int[] flag) {
this.context = context;
this.rank = rank;
this.country = country;
this.population = population;
this.flag = flag;
}
public int getCount() {
return rank.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
// Declare Variables
TextView txtrank;
TextView txtcountry;
TextView txtpopulation;
ImageView imgflag;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.listview_item, parent, false);
// Locate the TextViews in listview_item.xml
txtrank = (TextView) itemView.findViewById(R.id.name);
txtcountry = (TextView) itemView.findViewById(R.id.type);
txtpopulation = (TextView) itemView.findViewById(R.id.swim);
// Locate the ImageView in listview_item.xml
imgflag = (ImageView) itemView.findViewById(R.id.flag);
// Capture position and set to the TextViews
txtrank.setText(rank[position]);
txtcountry.setText(country[position]);
txtpopulation.setText(population[position]);
// Capture position and set to the ImageView
imgflag.setImageResource(flag[position]);
return itemView;
}
}
mysingleviewitem :
public class SingleItemView extends Activity {
TextView txtname;
TextView txttype;
TextView txtswim;
TextView txtfunny;
TextView txtwalking;
TextView txtangry;
TextView txtsad;
ImageView imgflag;
String[] name;
String[] type;
String[] swim;
String[] funny;
String[] walking;
String[] angry;
String[] sad;
int[] flag;
int position;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.singleitemview);
Intent i = getIntent();
// Get a single position
position = i.getExtras().getInt("position");
// Get the list of rank
name = i.getStringArrayExtra("rank");
// Get the list of country
type = i.getStringArrayExtra("country");
// Get the list of population
swim = i.getStringArrayExtra("population");
funny = i.getStringArrayExtra("rank");
// Get the list of country
walking = i.getStringArrayExtra("country");
// Get the list of population
angry = i.getStringArrayExtra("population");
sad = i.getStringArrayExtra("rank");
// Get the list of flag
flag = i.getIntArrayExtra("flag");
// Locate the TextViews in singleitemview.xml
txtname = (TextView) findViewById(R.id.name);
txttype = (TextView) findViewById(R.id.type);
txtswim = (TextView) findViewById(R.id.swim);
txtfunny = (TextView) findViewById(R.id.funny);
txtwalking = (TextView) findViewById(R.id.walking);
txtangry = (TextView) findViewById(R.id.angry);
txtsad = (TextView) findViewById(R.id.sad);
// Locate the ImageView in singleitemview.xml
imgflag = (ImageView) findViewById(R.id.flag);
// Load the text into the TextViews followed by the position
txtname.setText(name[position]);
txttype.setText(type[position]);
txtswim.setText(swim[position]);
txtfunny.setText(funny[position]);
txtwalking.setText(walking[position]);
txtangry.setText(angry[position]);
txtsad.setText(sad[position]);
// Load the image into the ImageView followed by the position
imgflag.setImageResource(flag[position]);
}
}
myarray :
<string-array name="sport">
<item >Lari</item>
<item >Bola</item>
<item >Balap</item>
<item >tinju</item>
<item >renang</item>
</string-array>
<string-array name="Lari">
<item >100 meter</item>
<item >mulai</item>
<item >finish</item>
<item >piala</item>
</string-array>
detail:
ListViewItem with the title of the string array "sport" and managed according to the layout of the array string.
and when clicked will open singleviewitem listview but I want the words that appear taken from <string-array name = "Lari"> and so on according listview of <string-array name = "sport">
so for example I click listview with Running title will be out is
<item >100 meter</item>
<item >mulai</item>
<item >finish</item>
<item >piala</item>
Please help,
sorry, my english is bad
nb: I've tried getstringarray the position but only raises the string according to the position of the clicked listview
Because of reputation I cannot leave a comment, but you can simply get text from chosen array and compare it to any name.
If I understood correctly your problem is you cannot load array from res/arrays with same name that clicked item in listview has.
I solved it by searching in array clicked word and if matched - took it.
All actions here inside onItemClickListener
For example:
String[] myString = null;
String text = parent.getItemAtPosition(position).toString();
if(text.equalsIgnoreCase("Lari")){
myString = getResources().getStringArray(R.array.lari);
}else if(text.equalsIgnoreCase("sport")){
myString = getResources().getStringArray(R.array.sport);
}
And then you may pass this array through intent and fill your next listview.
I hope this is what you want.
EDIT: When you got the name of clicked listitem, you may find same array in res/arrays.
After that just pass this array through Intent and fill next list with this array using Adapter.
Intent intent = new Intent(this, YourNextActivity.class);
intent.putExtra("justNameForArray", mString);
In next activity you can get this array:
Intent intent = getIntent();
String[] arrayFromPreviousClass = intent.getStringArrayExtra("justNameForArray");
And after that you may fill out your new list.
If you say you wanna third listitem, you may catch it inside onItemClickListener:
switch(position){
case 0:
//do smthg;
break;
case 1:
//do smthg;
break;
case 2:
//here you may get your string array and pass it through intent to another activity with another view
break;
}

Resources