.. _creating-getting-deleting-ref:

Creating, Getting and Deleting Data
===================================

Simplecouchdb represents CouchDB documents as instances of document classes. Methods of a document instance create, update and delete the document. CouchDB documents can be fetched as document instances using views or id.

.. seealso::

    :ref:`schema-ref` for more information about documents use in simplecouchdb.

Creating and Updating a Document
--------------------------------

Instances of Document classes represent CouchDB documents. An application creates a new document by calling the constructor of the document class.

.. code-block:: python

    pet = Pet(name="Fluffy",
          type="cat",
          owner="Jean")

The new document is not created in CouchDB database until the instance is "saved" for the first time,  by calling the :meth:`simplecouchdb.schema.Document.save` method on the instance.

.. code-block:: python

    pet.save(db)

db is an instance of :class:`simplecouchdb.core.Database` .

If the instance has been saved before (id is not None), the :meth:`simplecouchdb.schema.Document.save` update it cleanly.

Getting documents using id
----------------------------

All documents stored in CouchDB have an id.

You can simply get a document with :meth:`simplecouchdb.schema.Document.get` :

.. code-block:: python

    pet.get(db, "04ba0f93aeef0602b757bd1cfb6b95c1")

If you don't specify id of document, id are generated by CouchDB server as `uuid <http://en.wikipedia.org/wiki/Uuid>`_.

Getting documents using view
----------------------------

Views are CouchDB way using `Map/Reduce <http://en.wikipedia.org/wiki/Map_reduce>`_ to get documents.

here is  simple design_doc in javascript that define a view to get all pets by their type

.. code-block:: python

    {
        '_id': '_design/pet',
        'language': 'javascript',
        'views': {
            'by_type': {
                'map': 'function(doc) { if (doc.doc_type == "Pet") emit(doc.type, doc); }'
            }
        }
    }


.. note::

    Each document instance is saved with a doc_type property. By default it is se to class name,
    but you could change it with :attr:`simplecouchdb.schema.Document.doc_type` property.

You could simply get all pet of type cat with :meth:`simplecouchdb.schema.Document.view` method :

.. code-block:: python

    cats = Pet.view(db, "pet/by_type", key="cat")

It return a :class:`simplecouchdb.core.ViewResults` object that you could itterate. All results are Pet instance.

You could also get results as dict object with :attr:`simplecouchdb.core.Database.view` property :

.. code-block:: python

    cats = db.view.get('pets/by_type', key="cat")

Like above, it return a :class:`simplecouchdb.core.ViewResults` object that you could itterate but resulst are simple dict not mapped to Pet instance and all results are simple javascript type: unicode, integer, list, dict.

.. seealso::

    See `HTTP View API <http://wiki.apache.org/couchdb/HTTP_view_API>`_ from the CouchDB wiki for more informations about views.

Getting documents using view property
-------------------------------------

Last way to get documents is by adding a :class:`simplecouchdb.schema.ViewProperty` to your document instance. It will alow you in the same time to define the view and using a simple way to synchronise it in your application.

.. code-block:: python

    class Pet(schema.Document):
        ...
        by_type = schema.ViewProperty("pet", map_fun="""function(doc) { if (doc.doc_type == "Pet") emit(doc.type, doc); }""")

    db.sync()
    cats = Pet.by_type.get(key="cat")
    
.. seealso::

    :ref:`viewdef` for more information View defintion.

Deleting document
-----------------

Delete a document by using :meth:`simplecouchdb.schema.Document.delete` method:

.. code-block:: python

    pet1 = Pet()
    pet.get(db, "04ba0f93aeef0602b757bd1cfb6b95c1")
    pet.delete()

Or use :meth:`simplecouchdb.core.Database.delete` or just :func:`del`:

.. code-block:: python

    db.delete("04ba0f93aeef0602b757bd1cfb6b95c1")

or 

.. code-block:: python

    del db["04ba0f93aeef0602b757bd1cfb6b95c1"]


