Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP - Compare data on JSON and database

I have a database called ebookstore.db as below: database

and JSON as below: JSON

I want when slug on JSON is not the same as a title in the database, it will display the amount of data with a slug on JSON which is not same as a title in the database in ukomikText.

Code:

    string judulbuku;
     try
     {
        string urlPath1 = "https://...";
        var httpClient1 = new HttpClient(new HttpClientHandler());
        httpClient1.DefaultRequestHeaders.TryAddWithoutValidation("KIAT-API-KEY", "....");
        var values1 = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("halaman", 1),
            new KeyValuePair<string, string>("limit", 100),
        };

         var response1 = await httpClient1.PostAsync(urlPath1, new FormUrlEncodedContent(values1));
         response1.EnsureSuccessStatusCode();

        if (!response1.IsSuccessStatusCode)
        {
            MessageDialog messageDialog = new MessageDialog("Memeriksa update Komik gagal", "Gangguan Server");
            await messageDialog.ShowAsync();
        }
        string jsonText1 = await response1.Content.ReadAsStringAsync();
        JsonObject jsonObject1 = JsonObject.Parse(jsonText1);
        JsonArray jsonData1 = jsonObject1["data"].GetArray();

        foreach (JsonValue groupValue in jsonData1)
        {
            JsonObject groupObject = groupValue.GetObject();

            string id = groupObject["id"].GetString();
            string judul = groupObject["judul"].GetString();
            string slug = groupObject["slug"].GetString();

            BukuUpdate file1 = new BukuUpdate();
            file1.ID = id;
            file1.Judul = judul;
            file1.Slug = slug;

            List<String> title = sqlhelp.GetKomikData();
            foreach (string juduldb in title)
            {
                judulbuku = juduldb.Substring(juduldb.IndexOf('.') + 1);
                if (judulbuku != file1.Slug.Replace("-", "_") + ".pdf")
                {
                    BukuData.Add(file1);
                    ListBuku.ItemsSource = BukuData;
                }
                else
                {
                    ukomikText.Text = "belum tersedia komik yang baru";
                    ukomikText.Visibility = Visibility.Visible;
                }
            }
        }
        if (ListBuku.Items.Count > 0)
        {
            ukomikText.Text = BukuData.Count + " komik baru";
            ukomikText.Visibility = Visibility.Visible;
            jumlahbuku = BukuData.Count;
        }
        else
        {
            ukomikText.Text = "belum tersedia komik yang baru";
            ukomikText.Visibility = Visibility.Visible;
        }

 public static List<String> GetKomikData()
        {
            List<String> entries = new List<string>();

            using (SqliteConnection db =
                new SqliteConnection("Filename=ebookstore.db"))
            {
                db.Open();
                SqliteCommand selectCommand = new SqliteCommand
                    ("SELECT title FROM books where folder_id = 67", db);
                SqliteDataReader query = selectCommand.ExecuteReader();
                while (query.Read())
                {
                    entries.Add(query.GetString(0));
                }
                db.Close();
            }
            return entries;
        }

BukuUpdate.cs:

public string ID { get; set; }
public string Judul { get; set; }
public string Slug { get; set; }

I have a problem, that is when checking slugs on JSON, then the slug that is displayed is the first slug is displayed repeatedly as much data in the database, after that show the second slug repeatedly as much data on the database, and so on, as below: result

How to solve it so that slug on JSON is not displayed repeatedly (according to the amount of data on JSON)?

like image 664
Rose Avatar asked Jul 12 '18 04:07

Rose


1 Answers

The problem is that you have two nested foreach loops. What the code does in simplified pseudocode:

For each item in JSON
   Load all rows from DB
   And for each loaded row
      Check if the current JSON item matches the row from DB and if not, output

As you can see, if you have N items in the JSON and M rows in the database, this inevitably leads to N*M lines of output except for those rare ones where the JSON item matches a specific row in database.

If I understand it correctly, I assume that you instead want to check if there is a row that matches the JSON item and if not, output it. You could do this the following way:

List<String> title = sqlhelp.GetKomikData();
HashSet<string> dbItems = new HashSet<string>();
foreach (string juduldb in title)
{
    judulbuku = juduldb.Substring(juduldb.IndexOf('.') + 1);
    dbItems.Add( judulbuku );
}

...

foreach ( JsonValue groupValue in jsonData1 )
{
    ...

    //instead of the second foreach

    if ( !dbItems.Contains( file1.Slug.Replace("-", "_") + ".pdf" ) )
    {
         //item is not in database
    }
    else
    {
         //item is in database
    }
}

Additional tips

  • Avoid calling GetKomikData inside the foreach. This method does not have any arguments and that means you are just accessing the database again and again without a reason, which takes time and slows down the execution significantly. Instead, call GetKomikData only once before the first foreach and then just use title variable.
  • Don't assign ItemsSource every time the collection changes. This will unnecessarily slow down the UI thread, as it will have to reload all the items with each loop. Instead, assign the property only once after the outer foreach
  • write your code in one language. When you start mixing variable names in English with Indonesian, the code becomes confusing and less readable and adds cognitive overhead.
  • avoid non-descriptive variable names like file1 or jsonObject1. The variable name should be clear and tell you what it contains. When there is a number at the end, it usually means it could be named more clearly.
  • use plurals for list variable names - instead of title use titles
like image 168
Martin Zikmund Avatar answered Oct 18 '22 22:10

Martin Zikmund