Android Open Source - notes Notes Database Storage






From Project

Back to project page notes.

License

The source code is released under:

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> Everyone is permitted to copy and distribute verbatim or...

If you think the Android project notes listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.iliakplv.notes.notes.db;
/* w ww  . jav  a 2s. com*/
import android.util.Pair;

import com.iliakplv.notes.NotesApplication;
import com.iliakplv.notes.notes.AbstractNote;
import com.iliakplv.notes.notes.Label;
import com.iliakplv.notes.notes.NotesUtils;
import com.iliakplv.notes.notes.storage.NotesStorage;
import com.iliakplv.notes.notes.storage.NotesStorageListener;
import com.iliakplv.notes.utils.AppLog;
import com.iliakplv.notes.utils.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class NotesDatabaseStorage implements NotesStorage {

  private static final String LOG_TAG = NotesDatabaseStorage.class.getSimpleName();
  private static final Integer INVALID_ID = -1;


  // list cache
  private List<AbstractNote> notesListCache;
  private volatile Integer notesListCacheLabelId = INVALID_ID;
  private volatile boolean notesListCacheActual = false;

  // list sort
  private volatile NotesUtils.NoteSortOrder notesSortOrder = NotesUtils.DEFAULT_SORT_ORDER;

  // note cache
  private AbstractNote noteCache;
  private volatile Integer noteCacheNoteId = INVALID_ID;
  private volatile boolean noteCacheActual = false;

  // labels cache
  private List<Label> labelsListCache;
  private volatile boolean labelsListCacheActual = false;

  // search cache
  private List<AbstractNote> searchListCache = new ArrayList<AbstractNote>();
  private String lastSearchQuery = "";

  // listeners
  private final List<NotesStorageListener> storageListeners = new LinkedList<NotesStorageListener>();


  // notes

  @Override
  public boolean setNotesSortOrder(NotesUtils.NoteSortOrder notesSortOrder) {
    boolean orderChanged = this.notesSortOrder != notesSortOrder;
    if (orderChanged) {
      this.notesSortOrder = notesSortOrder;
      notesListCacheActual = false;
      notifyListeners();
    }
    return orderChanged;
  }

  @Override
  public AbstractNote getNote(Serializable id) {
    refreshNoteCacheIfNeeded((Integer) id);
    return noteCache;
  }

  private void refreshNoteCacheIfNeeded(Integer noteId) {
    final boolean needToRefresh = !noteCacheActual || !noteCacheNoteId.equals(noteId);
    AppLog.d(LOG_TAG, "Note entry refresh (id=" + noteId + "). Cached entry " +
        (needToRefresh ? "NOT " : "") + "actual");
    if (needToRefresh) {
      noteCache = (AbstractNote) performDatabaseTransaction(TransactionType.GetNote, noteId);
      noteCacheNoteId = noteId;
      noteCacheActual = true;
    }
  }

  private void refreshNotesListCacheIfNeeded(Integer labelId) {
    final boolean needToRefresh = !notesListCacheActual || !notesListCacheLabelId.equals(labelId);
    AppLog.d(LOG_TAG, "Notes entries refresh (labelId=" + labelId + "). Cached entries list " +
        (needToRefresh ? "NOT " : "") + "actual");
    if (needToRefresh) {
      final TransactionType selectTransaction = labelId == NOTES_FOR_ALL_LABELS ?
              TransactionType.GetAllNotes :
              TransactionType.GetNotesForLabel;
      notesListCache =
          (List<AbstractNote>) performDatabaseTransaction(selectTransaction, labelId);
      notesListCacheLabelId = labelId;
      notesListCacheActual = true;
    }
  }

  @Override
  public List<AbstractNote> getNotesForLabel(Serializable labelId) {
    refreshNotesListCacheIfNeeded((Integer) labelId);
    return notesListCache;
  }

  @Override
  public List<AbstractNote> getNotesForQuery(String searchQuery) {
    if (!StringUtils.isBlank(searchQuery)) {
      searchQuery = StringUtils.normalizeString(searchQuery);
      if (!lastSearchQuery.equals(searchQuery)) {
        final NotesDatabaseAdapter adapter = new NotesDatabaseAdapter();
        adapter.open();
        final List<AbstractNote> allNotes = adapter.getAllNotes(notesSortOrder);
        adapter.close();

        final List<AbstractNote> searchResult = new ArrayList<AbstractNote>();
        for (AbstractNote note : allNotes) {
          final String title = StringUtils.normalizeString(note.getTitle());
          final String body = StringUtils.normalizeString(note.getBody());
          if (title.contains(searchQuery) || body.contains(searchQuery)) {
            searchResult.add(note);
          }
        }
        searchListCache = searchResult;
        lastSearchQuery = searchQuery;
      }
      return searchListCache;
    }
    return EMPTY_NOTES_LIST;
  }

  @Override
  public synchronized Serializable insertNote(AbstractNote note) {
    return (Integer) performDatabaseTransaction(TransactionType.InsertNote, note);
  }

  @Override
  public synchronized boolean updateNote(Serializable id, AbstractNote note) {
    return (Boolean) performDatabaseTransaction(TransactionType.UpdateNote, id, note);
  }

  @Override
  public synchronized boolean deleteNote(Serializable id) {
    return (Boolean) performDatabaseTransaction(TransactionType.DeleteNote, id);
  }


  // labels

  @Override
  public Label getLabel(Serializable id) {
    return (Label) performDatabaseTransaction(TransactionType.GetLabel, id);
  }

  @Override
  public List<Label> getAllLabels() {
    refreshLabelsListCacheIfNeeded();
    return labelsListCache;
  }

  private void refreshLabelsListCacheIfNeeded() {
    AppLog.d(LOG_TAG, "Labels entries refresh. Cached entries list " +
        (labelsListCacheActual ? "" : "NOT ") + "actual");
    if (!labelsListCacheActual) {
      labelsListCache = (List<Label>) performDatabaseTransaction(TransactionType.GetAllLabels);
      labelsListCacheActual = true;
    }
  }

  @Override
  public synchronized Serializable insertLabel(Label label) {
    return (Integer) performDatabaseTransaction(TransactionType.InsertLabel, label);
  }

  @Override
  public synchronized boolean updateLabel(Serializable id, Label label) {
    return (Boolean) performDatabaseTransaction(TransactionType.UpdateLabel, id, label);
  }

  @Override
  public synchronized boolean deleteLabel(Serializable id) {
    return (Boolean) performDatabaseTransaction(TransactionType.DeleteLabel, id);
  }


  // notes_labels

  @Override
  public List<Label> getLabelsForNote(Serializable noteId) {
    return (List<Label>) performDatabaseTransaction(TransactionType.GetLabelsForNote, noteId);
  }

  @Override
  public Set<Serializable> getLabelsIdsForNote(Serializable noteId) {
    return (Set<Serializable>) performDatabaseTransaction(TransactionType.GetLabelsIdsForNote, noteId);
  }

  @Override
  public Set<Pair<Serializable, Serializable>> getAllNotesLabelsIds() {
    return (Set<Pair<Serializable, Serializable>>) performDatabaseTransaction(TransactionType.GetAllNotesLabelsIds);
  }

  @Override
  public synchronized Serializable insertLabelToNote(Serializable noteId, Serializable labelId) {
    return (Integer) performDatabaseTransaction(TransactionType.InsertLabelToNote, noteId, labelId);
  }

  @Override
  public synchronized boolean deleteLabelFromNote(Serializable noteId, Serializable labelId) {
    return (Boolean) performDatabaseTransaction(TransactionType.DeleteLabelFromNote, noteId, labelId);
  }


  private Object performDatabaseTransaction(TransactionType transactionType, Object... args) {
    Object result;
    Integer noteId = 0;
    Integer labelId = 0;

    final NotesDatabaseAdapter adapter = new NotesDatabaseAdapter();
    adapter.open();
    switch (transactionType) {
      case GetNote:
        noteId = (Integer) args[0];
        result = adapter.getNote(noteId);
        break;
      case GetAllNotes:
        result = adapter.getAllNotes(notesSortOrder);
        break;
      case InsertNote:
        result = adapter.insertNote((AbstractNote) args[0]);
        break;
      case UpdateNote:
        noteId = (Integer) args[0];
        result = adapter.updateNote(noteId, (AbstractNote) args[1]);
        break;
      case DeleteNote:
        noteId = (Integer) args[0];
        adapter.deleteNoteLabelsForNote(noteId);
        result = adapter.deleteNote(noteId);
        break;

      case GetLabel:
        labelId = (Integer) args[0];
        result = adapter.getLabel(labelId);
        break;
      case GetAllLabels:
        result = adapter.getAllLabels();
        break;
      case InsertLabel:
        result = adapter.insertLabel((Label) args[0]);
        break;
      case UpdateLabel:
        labelId = (Integer) args[0];
        result = adapter.updateLabel(labelId, (Label) args[1]);
        break;
      case DeleteLabel:
        labelId = (Integer) args[0];
        adapter.deleteNoteLabelsForLabel(labelId);
        result = adapter.deleteLabel(labelId);
        break;

      case GetAllNotesLabelsIds:
        result = adapter.getAllNotesLabelsIds();
        break;
      case GetLabelsForNote:
        noteId = (Integer) args[0];
        result = adapter.getLabelsForNote(noteId);
        break;
      case GetLabelsIdsForNote:
        noteId = (Integer) args[0];
        result = adapter.getLabelsIdsForNote(noteId);
        break;
      case GetNotesForLabel:
        labelId = (Integer) args[0];
        result = adapter.getNotesForLabel(labelId, notesSortOrder);
        break;
      case InsertLabelToNote:
        noteId = (Integer) args[0];
        labelId = (Integer) args[1];
        result = adapter.insertNoteLabel(noteId, labelId);
        break;
      case DeleteLabelFromNote:
        noteId = (Integer) args[0];
        labelId = (Integer) args[1];
        result = adapter.deleteNoteLabel(noteId, labelId);
        break;

      case DeleteAllData:
        adapter.deleteAllData();
        result = null;
        break;

      default:
        throw new IllegalArgumentException("Wrong transaction type: " + transactionType.name());
    }
    adapter.close();

    onTransactionPerformed(transactionType, noteId, labelId);
    return result;
  }

  private void onTransactionPerformed(TransactionType transactionType, Integer noteId, Integer labelId) {
    AppLog.d(LOG_TAG, "Database transaction (" + transactionType.name() + ") performed");

    if (noteCacheNoteId.equals(noteId) && noteModificationTransaction(transactionType)) {
      noteCacheActual = false;
    }
    if (labelsModificationTransaction(transactionType)) {
      labelsListCacheActual = false;
    }
    if (databaseModificationTransaction(transactionType)) {
      notesListCacheActual = false;
      lastSearchQuery = "";
      notifyListeners();
    }
  }

  // Listeners

  private void notifyListeners() {
    NotesApplication.executeInBackground(new Runnable() {
      @Override
      public void run() {
        synchronized (storageListeners) {
          for (NotesStorageListener listener : storageListeners) {
            listener.onContentChanged();
          }
        }
      }
    });
  }

  @Override
  public boolean addStorageListener(NotesStorageListener listener) {
    if (listener == null) {
      throw new NullPointerException();
    }
    synchronized (storageListeners) {
      return storageListeners.add(listener);
    }
  }

  @Override
  public boolean removeStorageListener(NotesStorageListener listener) {
    if (listener == null) {
      throw new NullPointerException();
    }
    synchronized (storageListeners) {
      return storageListeners.remove(listener);
    }
  }

  @Override
  public List<NotesStorageListener> detachAllListeners() {
    synchronized (storageListeners){
      final List<NotesStorageListener> listeners =
          new LinkedList<NotesStorageListener>(storageListeners);
      storageListeners.clear();
      return listeners;
    }
  }

  @Override
  public void attachListeners(List<NotesStorageListener> listeners) {
    synchronized (storageListeners) {
      storageListeners.addAll(listeners);
    }
    notifyListeners();
  }

  private static boolean databaseModificationTransaction(TransactionType transactionType) {
    switch (transactionType) {
      case InsertNote:
      case UpdateNote:
      case DeleteNote:

      case InsertLabel:
      case UpdateLabel:
      case DeleteLabel:

      case InsertLabelToNote:
      case DeleteLabelFromNote:

      case DeleteAllData:
        return true;
    }
    return false;
  }

  private static boolean noteModificationTransaction(TransactionType transactionType) {
    switch (transactionType) {
      case UpdateNote:
      case DeleteNote:

      case UpdateLabel:
      case DeleteLabel:

      case InsertLabelToNote:
      case DeleteLabelFromNote:

      case DeleteAllData:
        return true;
    }
    return false;
  }

  private static boolean labelsModificationTransaction(TransactionType transactionType) {
    switch (transactionType) {
      case InsertLabel:
      case UpdateLabel:
      case DeleteLabel:

      case DeleteAllData:
        return true;
    }
    return false;
  }


  @Override
  public void sync() {
    // do nothing
  }

  @Override
  public void clear() {
    performDatabaseTransaction(TransactionType.DeleteAllData);
  }


  /*********************************************
   *
   *            Inner classes
   *
   *********************************************/

  private static enum TransactionType {
    GetNote,
    GetAllNotes,
    InsertNote,
    UpdateNote,
    DeleteNote,

    GetLabel,
    GetAllLabels,
    InsertLabel,
    UpdateLabel,
    DeleteLabel,

    GetAllNotesLabelsIds,
    GetLabelsForNote,
    GetLabelsIdsForNote,
    GetNotesForLabel,
    InsertLabelToNote,
    DeleteLabelFromNote,

    DeleteAllData
  }

}




Java Source Code List

com.iliakplv.notes.NotesApplication.java
com.iliakplv.notes.analytics.EventTracker.java
com.iliakplv.notes.analytics.Event.java
com.iliakplv.notes.gui.main.MainActivityTest.java
com.iliakplv.notes.gui.main.MainActivity.java
com.iliakplv.notes.gui.main.NavigationDrawerFragment.java
com.iliakplv.notes.gui.main.NoteDetailsFragment.java
com.iliakplv.notes.gui.main.NotesListFragment.java
com.iliakplv.notes.gui.main.dialogs.AboutDialog.java
com.iliakplv.notes.gui.main.dialogs.AbstractItemDialog.java
com.iliakplv.notes.gui.main.dialogs.DropboxAccountLinkingDialog.java
com.iliakplv.notes.gui.main.dialogs.LabelEditDialog.java
com.iliakplv.notes.gui.main.dialogs.NoteLabelsDialog.java
com.iliakplv.notes.gui.main.dialogs.SimpleItemDialog.java
com.iliakplv.notes.gui.main.dialogs.VoiceSearchInstallDialog.java
com.iliakplv.notes.gui.settings.SettingsActivity.java
com.iliakplv.notes.notes.AbstractNote.java
com.iliakplv.notes.notes.LabelComparator.java
com.iliakplv.notes.notes.Label.java
com.iliakplv.notes.notes.NoteComparator.java
com.iliakplv.notes.notes.NotesUtils.java
com.iliakplv.notes.notes.TextNote.java
com.iliakplv.notes.notes.db.NotesDatabaseAdapter.java
com.iliakplv.notes.notes.db.NotesDatabaseOpenHelper.java
com.iliakplv.notes.notes.db.NotesDatabaseStorage.java
com.iliakplv.notes.notes.dropbox.DropboxHelper.java
com.iliakplv.notes.notes.dropbox.NotesDropboxStorage.java
com.iliakplv.notes.notes.storage.NotesStorageListener.java
com.iliakplv.notes.notes.storage.NotesStorage.java
com.iliakplv.notes.notes.storage.StorageDataTransfer.java
com.iliakplv.notes.notes.storage.StorageWrapper.java
com.iliakplv.notes.notes.storage.Storage.java
com.iliakplv.notes.storage.StorageTest.java
com.iliakplv.notes.utils.AppLog.java
com.iliakplv.notes.utils.ConnectivityUtils.java
com.iliakplv.notes.utils.StringUtils.java
com.iliakplv.notes.utils.Utils.java