0

I'm building an app where I've to create multiple tables on a SQLite database.

The best example I can give is of one store that I'll have to manage, so I'm creating one table for each category (wines, beers, milk, etc...) of products where I have to manage the brands that I'm selling but, if I quit from selling one of this categories I would like to be able to drop this category table.

But I tried many examples from the web and nothing works. I'm always getting the same error.

Because I've many items on my tables I built a custom list view and a custom adapter and both are working perfectly, I can delete or add new items without problems, build new tables, but the same approach doesn't work to drop my built tables.

I intentionally let my database opened until my activity is destroyed so I don't have to open it trough my adapter.

Maybe someone can help me how to drop a table with the name passed from a String, using one button or in this case, would be really helpful using my adapter button, because my idea is to add buttons on my list view.

Just to make clear, I can drop the tables if I create one editText to type my tables names and use a button to run this code:

dataBase.execSQL("DROP TABLE IF EXISTS '" + tableName + "'");

or if I run this code during the execution of the method onCreate and I give a name from a table that really exists.

dataBase.execSQL("DROP TABLE IF EXISTS 'test 1'");

So my question is not how to handle NullPointerException but how to manipulate my SQLite database from my custom adapter.

Thank you!

this is my adapter code:

public class MyCustomAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
private SQLiteDatabase dataBase;
private String tableName;

public MyCustomAdapter(ArrayList<String> list, Context context) {
    this.list = list;
    this.context = context;
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int pos) {
    return list.get(pos);
}

@Override
public long getItemId(int pos) {
    //return list.get(pos).getId();

    //just return 0 if your list items do not have an Id variable.
    return 0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.list_item_clickable, null);
    }

    //Handle TextView and display string from your list
    TextView listItemText = (TextView)view.findViewById(R.id.list_item_textview);
    listItemText.setText(list.get(position));

    //Handle buttons and add onClickListeners
    Button deleteBtn = (Button)view.findViewById(R.id.delete_btn);

    deleteBtn.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {

            //criar alertDialog
            AlertDialog.Builder  dialog = new AlertDialog.Builder(context);

            dialog.setTitle("Delete!");

            dialog.setMessage("Do you wish to delete this ToDo list?");

            dialog.setCancelable(false);

            dialog.setIcon(android.R.drawable.ic_delete);

            dialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    Toast.makeText(context, "No!", Toast.LENGTH_SHORT).show();
                }
            });

            dialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) { 
                    final String tableName= list.get( position ).toString();

                    try {

                        dataBase.execSQL("DROP TABLE IF EXISTS '" + tableName + "'");
                                //dataBase.execSQL("DROP TABLE IF EXISTS 'test 1'");

                                list.remove(position); //or some other task

                                    Toast.makeText(context, "Tabela " + tableName + " removida com sucesso!", Toast.LENGTH_SHORT).show();
                                    notifyDataSetChanged();


                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            });

            dialog.create();
            dialog.show();

        }
    });

    listItemText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Toast.makeText(context, "Item position is: " + list.get(position), Toast.LENGTH_SHORT).show();

            Intent intent = new Intent(context, MainActivity.class);
            String tabelaNome = list.get( position ).toString();

            intent.putExtra("tableName", tableName);

           context.startActivity(intent);
        }
    });

    return view;
}

Error message

  • "I'm always getting the same error." What error? – Code-Apprentice Feb 22 '17 at 23:46
  • Hello, thank you! I forgot that... I'll update the post with the error. This is the first time I post a question. – Curtes Malteser Feb 22 '17 at 23:56
  • please edit your question – Code-Apprentice Feb 23 '17 at 00:01
  • Note that spaces in table names are problematic – Code-Apprentice Feb 23 '17 at 00:16
  • You're right, but it doesn't work either on my table called test. I add also problems with double and single quotes and now it's working but this is completly out of my understanding. – Curtes Malteser Feb 23 '17 at 00:24
  • please copy and paste the error message and show which line causes the error – Code-Apprentice Feb 23 '17 at 00:26
  • Where do you initialize `database`? – Code-Apprentice Feb 23 '17 at 00:28
  • @Code-Apprentice - Possible duplicate of What is a NullPointerException, and how do I fix it? Problem solved. I forgot in one very stupid way. to pass the database to the construtor of my adapter class. `public MyCustomAdapter(ArrayList list, SQLiteDatabase database, Context context) { this.list = list; this.database = database; this.context = context; }` and then pass it on my HomeActivity to the custom adapter `MyCustomAdapter adapter = new MyCustomAdapter(arrTblNames, database, this);` – Curtes Malteser Feb 24 '17 at 23:08
  • that is one solution. Alternatively the adapter can just open the database itself internally. – Code-Apprentice Feb 24 '17 at 23:52
  • @Code-Apprentice - That's my wish, if you could help me with that would be great and I can't find an answer. I forgot it but, my error is exactly that "Can't open database "apptarefas". I've been lost between job interviews, my current job, and developing my published app, so sometimes I'm to tired to make sense. My idea to open the datbase internally is because I can open it and close it, after each interaction. I don't know if that's best practice to open/close it all the time but, that was the way I found to avoid the "leaking error". Solving this question would be a true value help. – Curtes Malteser Feb 25 '17 at 00:16
  • You should post a new question. But I do not really understand the problem. Opening the database for your adapter us the same add opening it for onClick(). – Code-Apprentice Feb 25 '17 at 00:28
  • I do not understand why you are doing entire tables. I think there is probably a better solution. You should also look into CursorAdapter. – Code-Apprentice Feb 25 '17 at 00:31

1 Answers1

0

Note the difference between your two SQL statements:

dataBase.execSQL("DROP TABLE IF EXISTS '" + tableName + "'");
dataBase.execSQL("DROP TABLE IF EXISTS teste 1"); 

The one you say works does not have quotes around the table name.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Well, the differences are that on the first one, I'm trying to pass a String value called tableName, and on the second one I built one table called teste 1 just to try if the problem is from the passed value or if the SQL code wasn't just being executed properly. But none of them work when executing the code from my adapter. – Curtes Malteser Feb 23 '17 at 00:06
  • @CurtesMalteser Either way, the SQ syntax **is the same**. – Code-Apprentice Feb 23 '17 at 00:07
  • I know, if I use this systax when I'm running this code on the method onCreate works great, or if I'm using a databaseHelper but, when I'm trying to pass values to this it just doesn't work. I'm working on the error to share... – Curtes Malteser Feb 23 '17 at 00:13
  • @CurtesMalteser What does "doesn't work" mean? – Code-Apprentice Feb 23 '17 at 00:15
  • It doesn't drop the table whith the passed name even if it exists. I just shared a screen shot from the message error. It should work since I use the same approach to build tables and add or remove items from these tables. I just don't get the error here, that's why I decide to use stackoverflow for the first time. – Curtes Malteser Feb 23 '17 at 00:21
  • @CurtesMalteser please copy and paste the error message – Code-Apprentice Feb 23 '17 at 00:23
  • thank you for your hint. I was to tired yesterday and not thinking clear. Yes, the syntax... I forgot the single quotes to get the string name, so I was getting an error due to the spaces. But, this works when using a button on my layout and typing the table name in one EditText, but I would like to use it from my adapter and the errors are the java.lang.NullPointerException or can't open the database. I'm lost and the NullPointerException doesn't fix my error. The question is really how to "touch" the database from my adapter... Thank you so much! – Curtes Malteser Feb 24 '17 at 00:26