Android Native – How to live-debug a database

Introduction

One of the best debugging tools in Android Studio is the live database inspector. It allows developers to peek at the current state of the database and even run queries against it.

In this tutorial, we will learn how to use it to debug a local SQLite database.

Goals

At the end of the tutorial, you would have learned:

  1. How to create a SQLite Database.
  2. How to debug a SQLite Database using the Database Inspector.
Prerequisite Knowledge
  1. Basic Android development knowledge.
  2. Basic SQL knowledge.
Tools Required
  1. Android Studio.
Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Android project with the default Empty Activity.
Creating the SQLite database

Before learning about the database inspector, we obviously must have a database to inspect. So we will need to create the database first.

The first thing that we need to do to create a SQLite database is to define a contract. A contract is a class that specifies your schema layout. We do not need to instantiate this contract, so Android prefers for developers to put these contracts inside a Kotlin Object (Singleton).

The database used in this tutorial comprises exactly one table called student. The student table would have two columns, name and age. Let us create a Kotlin Object called StudentContract from the code below (you will need to a create new Kotlin file).

package com.example.daniwedblivedebug

object StudentContract {
}

Next, we need to add another Object representing the table student inside of StudentContract.

object Student : BaseColumns {
   const val TABLE = "student"
   const val COLUMN_NAME = "name"
   const val COLUMN_AGE = "age"
}

The Student Object also extends BaseColumns because it is recommended by Android. BaseColumns provide inheritors with a primary key field called _ID, which allows our database to work well with other Android components.

Make sure that you add the import for BaseColumns as well.

import android.provider.BaseColumns

The second step that we need to do is to create a SQL statement that will help us create our student table (DDL). Later on, we will pass this statement to a class called SQLiteOpenHelper.

Inside the StudentContract Object, add the constant below.

private const val SQL_CREATE_STUDENTS =
   "CREATE TABLE ${Student.TABLE} (" +
           "${BaseColumns._ID} INTEGER PRIMARY KEY," +
           "${Student.COLUMN_NAME} TEXT," +
           "${Student.COLUMN_AGE} INTEGER)"

Finally, the last step that we would need to do is to extend SQLiteOpenHelper. This class contains a method to create the database the first time we obtain a reference to the database through it.

Still inside the StudentContract object, add the StudentDbHelper class.

class StudentDbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {

   override fun onCreate(db: SQLiteDatabase) {
       db.execSQL(SQL_CREATE_STUDENTS)
   }

   override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
       TODO("Not yet implemented")
   }

   companion object {
       const val DATABASE_VERSION = 1
       const val DATABASE_NAME = "Student.db"
   }
}

We are required to implement both onCreate() and onUpgrade(). Since upgrading is not in scope for this tutorial, we can just skip implementing it. In onCreate(), we told our database to execute the DDL statement we described previously to create the student table.

The companion object in StudentDbHelper contains constants for the superclass to consume. They are self-explanatory.

Trigger the table creation

As stated previously, the table creation wont be triggered until we attempt to retrieve a reference to the underlying database once, so we must add a few lines into our MainActivity code.

First, instantiate StudentDbHelper and then save it as a constant in MainActivity.

Inside MainActivity, add the dbHelper property.

private val dbHelper = StudentContract.StudentDbHelper(this)

Then, inside onCreate(), append this line of code to the method.

dbHelper.readableDatabase

By obtaining a reference to the underlying database, we have triggered the table creation, which we will be able to see in the inspector later.

Optionally, we can also close the database when the main activity is destroyed. We can do that by calling the close() method on the dbHelper reference. Inside MainActivity, override onDestroy() with the code snippet below.

override fun onDestroy() {
   dbHelper.close()
   super.onDestroy()
}
Inspect the database

It is finally time to inspect the database. Run the app using the Debug option (Shift+F9). After Hello World! is printed on the screen, switch to the App Inspection tool.

You can find the App Inspection tool at the bottom of your IDE.

inspect.png

If it is missing, then you can just go to

View > Tool Windows > App Inspection

to bring it back.

The database might not load immediately after switching to the App Inspection tool. You might have to wait a couple of seconds for it to show. Once it is loaded, you will see the database and the student table like the screenshot below.

db.png

If you are familiar with other database management consoles such as MySQL Workbench, SSMS, DBeaver, etc, then the Database Inspector should be quite easy for you to use.

Running queries

To execute statements against the database, open a New Query Tab.

queries.png

Our database currently does not have any row, so let us add one row. In the New Query tab, run the SQL statement below.

INSERT INTO student values(1, "John", 19);

To check if a student named John with age 19 has been added to the database, you do not have to run any SELECT query. You can just double click on the student table, and the database will show current rows.

student.png

You can also change how many rows can be displayed. The default is 50.

The Database Inspector also allows us to modify values directly. Double-click on Johns name and change the value to Mary.

There is no option to delete a row directly using the Database Inspector, so we must run a DELETE statement to delete the row.

DELETE FROM student WHERE _id=1;

The Database Inspector will advise that the statement was run successfully. If we refresh the student table view, we can see that the row has been deleted.

Solution Code

StudentContract.kt

package com.example.daniwedblivedebug

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.provider.BaseColumns

object StudentContract {
   object Student : BaseColumns {
       const val TABLE = "student"
       const val COLUMN_NAME = "name"
       const val COLUMN_AGE = "age"
   }

   private const val SQL_CREATE_STUDENTS =
       "CREATE TABLE ${Student.TABLE} (" +
               "${BaseColumns._ID} INTEGER PRIMARY KEY," +
               "${Student.COLUMN_NAME} TEXT," +
               "${Student.COLUMN_AGE} INTEGER)"

   class StudentDbHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {

       override fun onCreate(db: SQLiteDatabase) {
           db.execSQL(SQL_CREATE_STUDENTS)
       }

       override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
           TODO("Not yet implemented")
       }

       companion object {
           const val DATABASE_VERSION = 1
           const val DATABASE_NAME = "Student.db"
       }
   }
}

MainActivity.kt

package com.example.daniwedblivedebug

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

   private val dbHelper = StudentContract.StudentDbHelper(this)

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
       dbHelper.readableDatabase
   }

   override fun onDestroy() {
       dbHelper.close()
       super.onDestroy()
   }
}
Summary

Congratulations, you have learned how to create a SQLite database and use the Database Inspector tool. The full project code can be found here: https://github.com/dmitrilc/DaniweDBLiveDebug/tree/master

perform an operation on database using yesterday’s and today’s value

I have a database where there is an table wm for water meters :

    +------+---------------+
    | Code |     name      |
    +------+---------------+
    | wm1  | water meter 1 |
    | wm2  | water meter 2 |
    | wm3  | water meter 3 |
    +------+---------------+

and another table counters where there are counters value :

    +------+---------+-------+------------+
    | Code | Code_wm | value | created_at |
    +------+---------+-------+------------+
    |    1 | wm1     |   100 | 2020-10-18 |
    |    2 | wm1     |   0   | 2020-10-19 |
    |    3 | wm2     |   0   | 2020-10-18 |
    |    4 | wm2     |   100 | 2020-10-19 |
    |    5 | wm3     |   0   | 2020-10-18 |
    |    6 | wm3     |   100 | 2020-10-19 |
    +------+---------+-------+------------+

i want get this result :

    | code_wm | result |   Date     |
    +---------+--------+------------+
    | wm1     | 0-100  | 2020-10-19 |
    | wm2     | 100-0  | 2020-10-19 |
    | wm3     | 100-0  | 2020-10-19 |
    +---------+--------+------------+

but when i try :

SELECT code_wm , LAG(value,1,0) OVER ( ORDER BY code_wm) as result
FROM counters 

i don't get the correct result : https://www.db-fiddle.com/f/7TuSTaukG336tqnTNDg4em/0

MYSQL 8 Query Join Problem

I have the following query which has died after running over an hour on my local mysql 8 server:

UPDATE download
  LEFT JOIN lookup ON download.ip_address between lookup.start_ip AND lookup.end_ip
SET ref = (
    SELECT lookup.id FROM lookup WHERE download.ip_address between lookup.start_ip AND lookup.end_ip);

All ip fields are IPV4 and stored as unsigned integers and are indexed. The lookup table is approx. 3M rows, relating ip ranges to country, area, and city. The download table is approx. 2K rows. What I'm trying to do is get the id from the lookup table row that has the ip range that the download ip_address falls into.

Does someone see a problem with the query?

I am trying to avoid duplicate usernames and emails

                        **my functions.php file**
                                                 <?php
                                                 function confirmquery( $result ){
                                                     global $db;
                                                     if(!$result){
                                                        die("OUERY FAILED .".mysqli_error($db));
                                                      }
                                                }

                                                function redirect($location){
                                                  return header("Location:". $location);
                                                }

                                                function is_admin($username = ''){
                                                    global $db;
                                                    $sql = "SELECT user_role FROM users WHERE username = '$username'";
                                                    $result = mysqli_query($db, $sql);
                                                    confirmquery( $result );
                                                 $row = mysqli_fetch_array($result);
                                                     if ($row['user_role'] == 'admin') {
                                                       return true;
                                                     }else {
                                                       return false;
                                                     }
                                                }

                                                function username_exists($username = ''){
                                                    global $db;
                                                    $sql = "SELECT 'username' FROM users WHERE 'username' = '$username'";
                                                    $result = mysqli_query($db, $sql);
                                                    confirmquery( $result );

                                                      if (mysqli_num_rows($result) > 0) {
                                                        return true;
                                                      }else {
                                                        return false;
                                                      }
                                                }

                                                function email_exists($user_email = ''){
                                                    global $db;
                                                    $sql = "SELECT 'user_email' FROM users WHERE 'user_email' = '$user_email'";
                                                    $result = mysqli_query($db, $sql);
                                                    confirmquery( $result );

                                                     if (mysqli_num_rows($result) > 0) {
                                                       return true;
                                                     }else {
                                                       return false;
                                                     }
                                                }

                                                function recordCount($table){
                                                    global $db;
                                                  $sql    =" SELECT * FROM ".$table;
                                                  $result = mysqli_query($db, $sql);
                                                  return  mysqli_num_rows($result);

                                                }

                                                function register_user($username,$user_email,$user_password){
                                                  global $db;

                                                    $username     =mysqli_real_escape_string($db,$username);
                                                    $user_email   =mysqli_real_escape_string($db,$user_email);
                                                    $user_password=mysqli_real_escape_string($db,$user_password);

                                                    $user_password = password_hash($user_password, PASSWORD_BCRYPT, array('COST' => 12 ));

                                                    $sql="INSERT INTO `users`
                                                              SET

                                                            `username`         ='{$username}',
                                                            `user_email`       ='{$user_email}',
                                                            `user_password`    ='{$user_password}',
                                                            `user_role`        ='user'";

                                                      $result = mysqli_query($db, $sql);
                                                      confirmquery( $result );

                                                }

                                                function login_user($user_email, $user_password){
                                                      global $db;
                                                      $user_email    =trim($user_email);
                                                      $user_password =trim($user_password);

                                                      $user_email = mysqli_real_escape_string($db,$user_email);
                                                      $user_password = mysqli_real_escape_string($db,$user_password);

                                                 $sql = "SELECT * FROM `users` WHERE user_email='{$user_email}'";
                                                 $result = mysqli_query($db, $sql);
                                                     if(!$result){
                                                         die("OUERY FAILED .".mysqli_error($db));
                                                       }

                                                  while($row = mysqli_fetch_array($result)){
                                                     $db_user_id = $row['user_id'];
                                                     $db_username = $row['username'];
                                                     $db_user_email = $row['user_email'];
                                                     $db_user_password = $row['user_password'];
                                                     $db_user_firstname = $row['user_firstname'];
                                                     $db_user_lastname = $row['user_lastname'];
                                                     $db_user_role= $row['user_role'];
                                                     }
                                                    // $user_password = crypt($user_password,$db_user_password);

                                                if (password_verify($user_password, $db_user_password)) {
                                                $_SESSION['db_username']       = $db_username;
                                                $_SESSION['db_user_firstname'] = $db_user_firstname;
                                                $_SESSION['db_user_lastname']  = $db_user_lastname;
                                                $_SESSION['db_user_role']      = $db_user_role;

                                                  redirect("/gms/index.php");
                                                }

                                                }

                                                 ?>

                             **My registration.php file**     

                        <?php   include "includes/connect.php"; ?>
                        <?php  include "includes/header.php"; ?>
                        <?php  include "./admin/functions.php"; ?>

                         <?php
                             if ($_SERVER['REQUEST_METHOD'] == "POST") {
                              $username      =trim($_POST['username']);
                              $user_email    =trim($_POST['email']);
                              $user_password =trim($_POST['password']);

                              $error = [
                                'username' => '',
                                'email' => '',
                                'password' => ''
                              ];

                              if(strlen($username) < 4){
                                $error['username'] = 'Username needs to be longer';
                              }

                              if($username == ''){
                                $error['username'] = 'Username cannot be empty';
                              }

                              if(username_exists($username)){
                                $error['username'] = 'Username already exists';
                              }

                              if($user_email == ''){
                                $error['email'] = 'Email cannot be empty';
                              }

                              if(email_exists($user_email)){
                                $error['email'] = 'Email already exists, <a href = "index.php">Please login</a>';
                              }

                              if($user_password == ''){
                                $error['password'] = 'Password cannot be empty';
                              }

                              foreach ($error as $key => $value) {
                                if(empty($value)){
                                  unset($error[$key]);
                                  }
                                }

                                if(empty($error)){
                                  register_user($username, $user_email, $user_password);
                                  login_user($user_email, $user_password );
                                }

                            }

                          ?>

                            <!-- Navigation -->

                            <?php  include "includes/navigation.php"; ?>

                            <!-- Page Content -->
                            <div class="container">

                        <section id="login">
                            <div class="container">
                                <div class="row">
                                    <div class="col-xs-6 col-xs-offset-3">
                                        <div class="form-wrap">
                                        <h1>Register</h1>
                                            <form role="form" action="registration.php" method="post" id="login-form" autocomplete="oFF">

                                                <div class="form-group">
                                                    <label for="username" class="sr-only">username</label>
                                                    <input type="text" name="username" id="username" class="form-control" placeholder="Enter Desired Username"
                                                      autocomplete="on"
                                                      value = "<?php echo isset($username) ? $username : '' ?>"  >
                                                      <p><?php echo isset($error['username']) ? $error['username'] : '' ?></p>

                                                </div>
                                                 <div class="form-group">
                                                    <label for="email" class="sr-only">Email</label>
                                                    <input type="email" name="email" id="email" class="form-control" placeholder="somebody@example.com"

                                                    value = "<?php echo isset($user_email) ? $user_email : '' ?>">
                                                    <p><?php echo isset($error['email']) ? $error['email'] : '' ?></p>

                                                </div>
                                                 <div class="form-group">
                                                    <label for="password" class="sr-only">Password</label>
                                                    <input type="password" name="password" id="key" class="form-control" placeholder="Password">

                                                    <p><?php echo isset($error['password']) ? $error['password'] : '' ?></p>

                                                </div>

                                                <input type="submit" name="register" id="btn-login" class="btn btn-custom btn-lg btn-block" value="Register">
                                            </form>

                                        </div>
                                    </div> <!-- /.col-xs-12 -->
                                </div> <!-- /.row -->
                            </div> <!-- /.container -->
                        </section>

                                <hr>

                        <?php include "includes/footer.php";?>

MY CODE STILL REGISTERS A USER WITH THE SAME USERNAME

                    function username_exists($username){
                        global $db;
                        $sql = "SELECT 'username' FROM users WHERE 'username' = '$username'";
                        $result = mysqli_query($db, $sql);
                        confirmquery( $result );

                         if (mysqli_num_rows($result) > 0) {
                           return true;
                         }else {
                           return false;
                         }
                    }
                    if(username_exists($username)){
                            $error['username'] = 'Username already exists';
                          }

my function is not working

                        function username_exists($username){
                            global $db;
                            $sql = "SELECT 'username' FROM users WHERE 'username' = '$username'";
                            $result = mysqli_query($db, $sql);
                            confirmquery( $result );

                             if (mysqli_num_rows($result) > 0) {
                               return true;
                             }else {
                               return false;
                             }
                        }
                        if(username_exists($username)){
                                $error['username'] = 'Username already exists';
                              }

Database Fundamentals #22: Using the Join Operator, CROSS JOIN

CROSS JOIN

While the CROSS JOIN is not used much, and, depending on the size of your data it can be dangerous, there are some uses for it. For example, you may want to write a query that will summarize all the sales for the companies and people in your system. You can do this using what is called an aggregate operation or a GROUP BY:

SELECT c.CompanyName,
p.LastName,
SUM(ft.TransactionAmount) AS 'TransactionTotals'
FROM Management.Company AS c
JOIN Finance.FinancialTransaction AS ft
ON c.CompanyID = ft.CompanyID
JOIN Personnel.Person AS p
ON p.PersonID = ft.PersonID
GROUP BY c.CompanyName, p.LastName;
You might also like:  Overview of SQL Joins in SQL Server

This will add all the values up in the SUM operation for each company and each person that has values so that your data will look like this:

How to return parameters from different table rows

I have three tables(table, table2,table3). From table1 i want to return three rows: Title, Desc,time,'products' AS type

From table2 i want to return three rows: group_title, group_desc, created,'groups' AS type

From table3 i want to return three rows: name, occupation,birth,'users' AS type

  $sql = "SELECT DISTINCT * 
    FROM
        (SELECT table1.title, table1.desc, table1.time,'products' AS type
        FROM table1 ORDER BY rand() LIMIT 5) AS T
     UNION ALL
        (SELECT table2.group_name,table2.group_desc,table2.created,'groups' AS type
        FROM tabl2 
        JOIN table1 ON table2.id = table1.id 
         ORDER BY rand() LIMIT 5)
    UNION ALL
        (SELECT table3.name,table3.occupation,table3.birth,'users' AS type
        FROM table3
        JOIN  table1 ON table3.id = table1.id
        ORDER BY rand() LIMIT 5)";

am using Ionic to push those three parameters of an Array to the next page so if i use AS and put the same name. I set a parameter AS type that i need so i can work different types. it has to be 'products' AS type for table1, 'groups' AS type for table2, users as type for table3 i want to separate the objects from each table.

It cant use AS the for the rest of the columns because i want to push the original columns
e.g.

 (SELECT table1.title AS title, table1.desc AS desc, table1.time AS time
    FROM table1 ORDER BY rand() LIMIT 5) AS T
 UNION ALL
    (SELECT table2.group_name AS title,table2.group_desc AS desc,table2.created AS time.....

If i do that it displays the object parameters ok e.g. {{item.title}}

but i can not push or navctrl the parameter as title it has to be group_name. I hope i made myself clear.

Show error when I login SQL server management.

Show error when I login to the SQL server management. First, I change the server name. Second restart the server/1st stop services the start services. Then I check the server name

SELECT @@servername AS 'ServerName'

using this line the show new change server name. Then I closed the window of SQL server then open it and type the new change server but show error. Please help me.... I use SQL Server 2008 r2. Windows authentication

Click Here

SELECT  HOST_NAME() AS 'host_name()',
@@servername AS 'ServerName\InstanceName',
SERVERPROPERTY('servername') AS 'ServerName',
SERVERPROPERTY('machinename') AS 'Windows_Name',
SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS 'NetBIOS_Name',
SERVERPROPERTY('instanceName') AS 'InstanceName',
SERVERPROPERTY('IsClustered') AS 'IsClustered'

EXEC sp_DROPSERVER 'JAYANTA'
EXEC sp_ADDSERVER 'SIASERVER', 'local'

MySql GROUP BY on script

Hello i have a problem with a Sql script

SELECT col1_id, col1_name, col2 FROM table GROUP BY ?????

col1_id col1_name col2
A john bear
A john dog
A john cat
A john bear
A john dog
A john cat
A john dog
A john cat
A john bear
A john dog
A john cat
A john bear
A john dog
A john cat
A john dog
A john cat

I want to return all results. It has to return like this: echo col1_id . col1_name (A john) and then col2 (bear,dog, cat)