Commits

Mikhail Korobov committed f64869f

PostgreSQL support. Fix #1.

Comments (0)

Files changed (5)

 dist/
 .build/
 MANIFEST
+django_qsstats_magic.egg-info

qsstats/__init__.py

         self.aggregate = aggregate or Count('id')
         self.today = today or self.update_today()
 
+    def _guess_engine(self):
+        if hasattr(self.qs, 'db'): # django 1.2+
+            engine_name = settings.DATABASES[self.qs.db]['ENGINE']
+        else:
+            engine_name = settings.DATABASE_ENGINE
+        if 'mysql' in engine_name:
+            return 'mysql'
+        if 'postg' in engine_name: #postgres, postgis
+            return 'postgresql'
+        if 'sqlite' in engine_name:
+            return 'sqlite'
+
     # Aggregates for a specific period of time
 
     def for_interval(self, interval, dt, date_field=None, aggregate=None):
             return partial(self.this_interval, name[5:])
         raise AttributeError
 
-
     def time_series(self, start, end=None, interval='days',
-                    date_field=None, aggregate=None, engine='mysql'):
+                    date_field=None, aggregate=None, engine=None):
         ''' Aggregate over time intervals '''
         end = end or self.today
         args = [start, end, interval, date_field, aggregate]
+        engine = engine or self._guess_engine()
         sid = transaction.savepoint()
         try:
-            #TODO: engine should be guessed
             return self._fast_time_series(*(args+[engine]))
         except (QuerySetStatsError, DatabaseError,):
             transaction.savepoint_rollback(sid)
         return stat_list
 
     def _fast_time_series(self, start, end, interval='days',
-                          date_field=None, aggregate=None, engine='mysql'):
+                          date_field=None, aggregate=None, engine=None):
         ''' Aggregate over time intervals using just 1 sql query '''
         date_field = date_field or self.date_field
         aggregate = aggregate or self.aggregate
+        engine = engine or self._guess_engine()
 
         start, _ = get_bounds(start, interval.rstrip('s'))
         _, end = get_bounds(end, interval.rstrip('s'))
                         filter(**kwargs).order_by().values('d').\
                         annotate(agg=aggregate)
 
-        data = dict((parse(item['d'], yearfirst=True), item['agg']) for item in aggregate_data)
+        def to_dt(d): # leave dates as-is
+            return parse(d, yearfirst=True) if isinstance(d, basestring) else d
+        data = dict((to_dt(item['d']), item['agg']) for item in aggregate_data)
 
         stat_list = []
         dt = start
             'weeks': "DATE_FORMAT(DATE_SUB(`"+date_field+"`, INTERVAL(WEEKDAY(`"+date_field+"`)) DAY), '%%Y-%%m-%%d')",
             'months': "DATE_FORMAT(`" + date_field +"`, '%%Y-%%m-01')",
             'years': "DATE_FORMAT(`" + date_field +"`, '%%Y-01-01')",
+        },
+        'postgresql': {
+            'minutes': "date_trunc('minute', %s)" % date_field,
+            'hours': "date_trunc('hour', %s)" % date_field,
+            'days': "date_trunc('day', %s)" % date_field,
+            'weeks': "date_trunc('week', %s)" % date_field,
+            'months': "date_trunc('month', %s)" % date_field,
+            'years': "date_trunc('year', %s)" % date_field,
         }
     }
 
     try:
         engine_sql = SQL[engine]
     except KeyError:
-        raise UnsupportedEngine('%s DB engine is not supported' % engine)
+        msg = '%s DB engine is not supported. Supported engines are: %s' % (engine, ", ".join(SQL.keys()))
+        raise UnsupportedEngine(msg)
 
     try:
         return engine_sql[interval]
 
 from django.conf import settings
 from django.core.management import call_command
+import sys
+
+engine = sys.argv[1]
 
 settings.configure(
     INSTALLED_APPS=('qsstats', 'django.contrib.auth', 'django.contrib.contenttypes'),
-    DATABASE_ENGINE = 'sqlite3',
+    DATABASES = {
+        'default': {
+            'ENGINE': 'django.db.backends.' + engine,
+            'NAME': 'test'
+        }
+    }
 )
 
 if __name__ == "__main__":
 #!/usr/bin/env python
 from distutils.core import setup
 
+for cmd in ('egg_info', 'develop'):
+    import sys
+    if cmd in sys.argv:
+        from setuptools import setup
+
 setup(
     name='django-qsstats-magic',
     version='0.5.2',
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.