source: OpenRLabs-Git/deploy/rlabs-docker/web2py-rlabs/gluon/packages/dal/pydal/adapters/couchdb.py

main
Last change on this file was 42bd667, checked in by David Fuertes <dfuertes@…>, 4 years ago

Historial Limpio

  • Property mode set to 100755
File size: 5.6 KB
Line 
1from ..helpers.classes import FakeCursor, SQLALL
2from ..helpers.methods import uuid2int
3from ..objects import Query, Field
4from .base import NoSQLAdapter, SQLAdapter
5from . import adapters
6
7
8@adapters.register_for("couchdb")
9class CouchDB(NoSQLAdapter):
10    dbengine = "couchdb"
11    drivers = ("couchdb",)
12
13    uploads_in_blob = True
14
15    def _initialize_(self):
16        super(CouchDB, self)._initialize_()
17        self.ruri = "http://" + self.uri[10:]
18        self.db_codec = "UTF-8"
19
20    def connector(self):
21        conn = self.driver.Server(self.ruri, **self.driver_args)
22        conn.cursor = lambda: FakeCursor()
23        conn.close = lambda: None
24        conn.commit = lambda: None
25        return conn
26
27    def create_table(self, table, migrate=True, fake_migrate=False, polymodel=None):
28        if migrate:
29            try:
30                self.connection.create(table._tablename)
31            except:
32                pass
33        super(CouchDB, self).create_table(table, migrate, fake_migrate, polymodel)
34
35    def _expand(self, expression, field_type=None, query_env={}):
36        if isinstance(expression, Field):
37            if expression.type == "id":
38                return "%s._id" % expression.tablename
39        return SQLAdapter._expand(self, expression, field_type, query_env=query_env)
40
41    def insert(self, table, fields):
42        rid = uuid2int(self.db.uuid())
43        ctable = self.connection[table._tablename]
44        values = dict((k.name, self.represent(v, k.type)) for k, v in fields)
45        values["_id"] = str(rid)
46        ctable.save(values)
47        return rid
48
49    @staticmethod
50    def _make_id_field(field_name):
51        return field_name == "id" and "_id" or field_name
52
53    def _select(
54        self,
55        query,
56        fields,
57        left=False,
58        join=False,
59        distinct=False,
60        orderby=False,
61        groupby=False,
62        having=False,
63        limitby=False,
64        orderby_on_limitby=True,
65        for_update=False,
66        outer_scoped=[],
67        required=None,
68        cache=None,
69        cacheable=None,
70        processor=None,
71    ):
72        if not isinstance(query, Query):
73            raise SyntaxError("Not Supported")
74
75        new_fields = []
76        for item in fields:
77            if isinstance(item, SQLALL):
78                new_fields += item._table
79            else:
80                new_fields.append(item)
81
82        fields = new_fields
83        tablename = self.get_table(query)._tablename
84        fieldnames = [f.name for f in (fields or self.db[tablename])]
85        colnames = ["%s.%s" % (tablename, fieldname) for fieldname in fieldnames]
86        fields = ",".join(
87            ["%s.%s" % (tablename, self._make_id_field(f)) for f in fieldnames]
88        )
89        fn = "(function(%(t)s){if(%(query)s)emit(%(order)s,[%(fields)s]);})" % dict(
90            t=tablename,
91            query=self.expand(query),
92            order="%s._id" % tablename,
93            fields=fields,
94        )
95        return fn, colnames
96
97    def select(self, query, fields, attributes):
98        fn, colnames = self._select(query, fields, attributes)
99        tablename = colnames[0].split(".")[0]
100        ctable = self.connection[tablename]
101        rows = [cols["value"] for cols in ctable.query(fn)]
102        processor = attributes.get("processor", self.parse)
103        return processor(rows, fields, colnames, False)
104
105    def update(self, table, query, fields):
106        from ..drivers import couchdb
107
108        if not isinstance(query, Query):
109            raise SyntaxError("Not Supported")
110        if query.first.type == "id" and query.op == self.dialect.eq:
111            rid = query.second
112            tablename = query.first.tablename
113            ctable = self.connection[tablename]
114            try:
115                doc = ctable[str(rid)]
116                for key, value in fields:
117                    doc[key.name] = self.represent(
118                        value, self.db[tablename][key.name].type
119                    )
120                ctable.save(doc)
121                return 1
122            except couchdb.http.ResourceNotFound:
123                return 0
124        tablename = self.get_table(query)._tablename
125        rows = self.select(query, [self.db[tablename]._id], {})
126        ctable = self.connection[tablename]
127        table = self.db[tablename]
128        for row in rows:
129            doc = ctable[str(row.id)]
130            for key, value in fields:
131                doc[key.name] = self.represent(value, table[key.name].type)
132            ctable.save(doc)
133        return len(rows)
134
135    def count(self, query, distinct=None):
136        if distinct:
137            raise RuntimeError("COUNT DISTINCT not supported")
138        if not isinstance(query, Query):
139            raise SyntaxError("Not Supported")
140        tablename = self.get_table(query)._tablename
141        rows = self.select(query, [self.db[tablename]._id], {})
142        return len(rows)
143
144    def delete(self, table, query):
145        from ..drivers import couchdb
146
147        if not isinstance(query, Query):
148            raise SyntaxError("Not Supported")
149        if query.first.type == "id" and query.op == self.eq:
150            rid = query.second
151            tablename = query.first.tablename
152            assert tablename == query.first.tablename
153            ctable = self.connection[tablename]
154            try:
155                del ctable[str(rid)]
156                return 1
157            except couchdb.http.ResourceNotFound:
158                return 0
159        tablename = self.get_table(query)._tablename
160        rows = self.select(query, [self.db[tablename]._id], {})
161        ctable = self.connection[tablename]
162        for row in rows:
163            del ctable[str(row.id)]
164        return len(rows)
Note: See TracBrowser for help on using the repository browser.