From f0b0e795f9718692e1cb9ad1fec5d412b16ebc16 Mon Sep 17 00:00:00 2001 From: Michael Salgado Date: Wed, 29 Jul 2015 00:43:46 -0500 Subject: [PATCH] - Change icons. - Fix #29 Error updating layer single user account. - Fix #27 Error getting columns in SQL dialog. --- CHANGELOG.md | 28 +++++++++++++---------- CartoDBPlugin.py | 9 ++++---- README.md | 2 +- dialogs/Main.py | 2 +- dialogs/NewSQL.py | 22 +++++++++++++------ images/icons/add.png | Bin 1760 -> 987 bytes images/icons/add_sql.png | Bin 619 -> 0 bytes images/icons/avatar.png | Bin 0 -> 2625 bytes images/icons/error.png | Bin 0 -> 3772 bytes images/icons/map.png | Bin 0 -> 1221 bytes images/icons/sql.png | Bin 467 -> 998 bytes images/icons/upload.png | Bin 0 -> 1154 bytes layers/CartoDBLayer.py | 44 +++++++++++++++++++++++-------------- metadata.txt | 5 ++++- resources.qrc | 8 ++++++- toolbars/CartoDBToolbar.py | 1 + widgets/ListItemWidgets.py | 3 ++- 17 files changed, 80 insertions(+), 44 deletions(-) delete mode 100644 images/icons/add_sql.png create mode 100644 images/icons/avatar.png create mode 100644 images/icons/error.png create mode 100644 images/icons/map.png create mode 100644 images/icons/upload.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 335317d..247fe6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,13 @@ * Default symbology for not supported symbols. * Add messages for not supported symbols. -* Add uploaded message +* Add uploaded message. +* Change icons. + +#### Fixes + +* Fix #29 Error updating layer single user account. +* Fix #27 Error getting columns in SQL dialog. @@ -13,7 +19,7 @@ #### Enhancements -* Remove connection controls in SQL Editor +* Remove connection controls in SQL Editor. * Add composite mode in create maps. * Add dash style to lines in create maps. * Add join style to lines in create maps. @@ -23,9 +29,9 @@ #### Fixes -* Fix #19 Do not allow to edit read-only layers -* Show owner in shared layers, issue #18 -* Fix #26 Encoding error creating map +* Fix #19 Do not allow to edit read-only layers. +* Show owner in shared layers, issue #18. +* Fix #26 Encoding error creating map. @@ -39,7 +45,7 @@ #### Fixes -* Fix #23 Error conecting multiuser account +* Fix #23 Error conecting multiuser account. ### 0.1.5 (2015-06-16) @@ -48,9 +54,9 @@ * Upload layers to CartoDB (More formats). * Create basic visualization. Support: - * Borders - * Fill - * Label + * Borders. + * Fill. + * Label. ### 0.1.4 (2015-06-05) @@ -65,7 +71,7 @@ #### Fixes -* Fix avatar size +* Fix avatar size. * Fix #21 Insert data without complete fields. * Enable buttons only if there is at least one created connection. @@ -101,6 +107,7 @@ ### 0.1.1 (2014-11-27) +* Fix error when repeat layer name at spatialite database. #### New Features * Load cartodb layers from SQL Queries. @@ -108,7 +115,6 @@ #### Fixes. * New connection dialog is now a modal window. -* Fix error when repeat layer name at spatialite database. ### 0.1.0 (2014-09-23) diff --git a/CartoDBPlugin.py b/CartoDBPlugin.py index efa7d44..e6bdd2c 100644 --- a/CartoDBPlugin.py +++ b/CartoDBPlugin.py @@ -81,11 +81,11 @@ def initGui(self): self._mainAction = QAction(self.tr('Add CartoDB Layer'), self.iface.mainWindow()) self._mainAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/add.png")) self._loadDataAction = QAction(self.tr('Upload layers to CartoDB'), self.iface.mainWindow()) - self._loadDataAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/polygon.png")) + self._loadDataAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/upload.png")) self._createVizAction = QAction(self.tr('Create New Map'), self.iface.mainWindow()) - self._createVizAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/rectangle.png")) + self._createVizAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/map.png")) self._addSQLAction = QAction(self.tr('Add SQL CartoDB Layer'), self.iface.mainWindow()) - self._addSQLAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/add_sql.png")) + self._addSQLAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/sql.png")) self.toolbar = CartoDBToolbar() self.toolbar.setClick(self.connectionManager) @@ -182,7 +182,8 @@ def run(self): for i, table in enumerate(selectedItems): widget = dlg.getItemWidget(table) worker = CartoDBLayerWorker(self.iface, widget.tableName, widget.tableOwner, dlg, - filterByExtent=dlg.filterByExtent(), readonly=widget.readonly) + filterByExtent=dlg.filterByExtent(), readonly=widget.readonly, + multiuser=widget.multiuser) worker.finished.connect(self.addLayer) self.worker = worker worker.load() diff --git a/README.md b/README.md index ed088c5..6394d36 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Voilá !!!! #### Adding SQL CartoDB layer -Click on the icon: ![Icon](images/add_sql.png?raw=true "Icon") or on the web menu item "CartoDB Plugin" => "Add SQL CartoDB Layer" +Click on the icon: ![Icon](images/icons/sql.png?raw=true "Icon") or on the web menu item "CartoDB Plugin" => "Add SQL CartoDB Layer" ![Dialog 3](images/sql_dialog.png?raw=true "Adding SQL layer") diff --git a/dialogs/Main.py b/dialogs/Main.py index 422548f..b3f7fda 100644 --- a/dialogs/Main.py +++ b/dialogs/Main.py @@ -86,7 +86,7 @@ def updateList(self, visualizations): widget = CartoDBDatasetsListItem( visualization['name'], owner, visualization['table']['size'], visualization['table']['row_count'], - shared=(owner != self.currentUser)) + shared=(owner != self.currentUser), multiuser=self.currentMultiuser) # item.setText(visualization['name']) readonly = False # qDebug('Vis:' + json.dumps(visualization, sort_keys=True, indent=2, separators=(',', ': '))) diff --git a/dialogs/NewSQL.py b/dialogs/NewSQL.py index 3f1cdc1..901af85 100644 --- a/dialogs/NewSQL.py +++ b/dialogs/NewSQL.py @@ -115,13 +115,12 @@ def findTables(self): if not str(self.currentMultiuser) in ['true', '1', 'True']: sqlTables = "SELECT CDB_UserTables() table_name" res = cl.sql( - "SELECT *, CDB_ColumnType(table_name, column_name) column_type \ - FROM ( \ - SELECT *, CDB_ColumnNames(table_name) column_name \ - FROM (" + sqlTables + ") t1 \ - ) t2 \ - WHERE CDB_ColumnType(table_name, column_name) != 'USER-DEFINED' \ - ORDER BY table_name, column_name") + "WITH usertables AS (" + sqlTables + ") \ + SELECT ut.table_name, c.column_name, c.data_type column_type \ + FROM usertables ut \ + JOIN information_schema.columns c ON c.table_name = ut.table_name \ + WHERE c.data_type != 'USER-DEFINED' \ + ORDER BY ut.table_name, c.column_name") else: sqlTables = "SELECT string_agg(privilege_type, ', ') AS privileges, table_schema, table_name \ FROM information_schema.role_table_grants tg \ @@ -208,3 +207,12 @@ def getQuery(self): def showEvent(self, event): worker = CartoDBPluginWorker(self, 'findTables') worker.start() + +''' +WITH usertables AS (SELECT CDB_UserTables() table_name) +SELECT ut.table_name, c.column_name, c.data_type column_type, ut.privileges + FROM usertables ut + JOIN information_schema.columns c ON c.table_name = ut.table_name +WHERE c.data_type != 'USER-DEFINED' +ORDER BY ut.table_name, c.column_name +''' diff --git a/images/icons/add.png b/images/icons/add.png index 898afe9aa862eeeda9822545a7466095e13c0a0e..2c1d66f672b235d4997e8db56167c08f09dad681 100644 GIT binary patch literal 987 zcmV<110?*3P)>%5wH)sm-?fi+sMiBqV$1OsfVY4-%kl2F94~X< z+#Z59-zR~kRMl&~YiAxOpHQumPK=a2yhGoIEXVsA*Z`uG{|U?S=7BE((+y0%SDq&` zzZdv6am@lhwlwz9Ba1_8Sx$k zmU{v4ctW-2az78e*QVbu83Fv%D+@+i%0umPz<2F8fOp!A7XY6m-#_@Sz14Rb`mWss zaTd6os;U8R10N>kC$s3mu5=&;q6~bOxE}@X1YQRo@Ll`YEP9aNtq?Uq0A=73ueDha=e`cO?T3cUI07- z{NC@INw+PC2XrISSy$jA;4E+tU@}Z*f3q;0tJMySTra9yx+y?$u&{n;=={Rs$}3mi z?*<_DUHid|r{p;BS2OtOyO)QjOEYLK#G$-mk}zq3G$u>9LqwAS1RYE+KTbFI3@$KQWOEE+8uZ5jYhB>!rv zUm|m`uzo0#$#czwi*!TJlv4i%k3=KJ^eyNucI^DZ;@lmFFQFRA7{xJ%OLwucwaGuh zHc#hI*002ov JPDHLkV1k)m#-RWJ literal 1760 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 literal 0 HcmV?d00001 diff --git a/images/icons/error.png b/images/icons/error.png new file mode 100644 index 0000000000000000000000000000000000000000..cc07f30ad71d3cab63e38c44a0b835bb0aba98a4 GIT binary patch literal 3772 zcmaJ^dpwi-AAiPVS(xcg%rHuJbDL#|5stYemt11Dg~KkkVRC6MC0*p2TeZqLx=^hg zr&4JmDN4FoQigR@h}Lz7_|5s9&hPifuix`}p67dc-tYJ4`g%RjQyAd4Nn2~R761U+ z-d^O*s!_ObK^Cd*?atJ0)v${15ylT@ksZ446e7lfZk zLjK#SFiHTzoy}z+?9evWG%OB>u(wC!Z0+praqAIyEDn#ss!n@roGsDLo``oq{Cyx* z*0}WT#LZ;Szip{jBxF3F&mm$kX=!QbG#fOV8;8L;Iyx?B;PKWfgf%an#it6aSv=G4 z3S3Ah{{By4-j;L@1GAaIW2bOws={qIT`$s4x_1}361#KFOCvjYizdMW#2Fd61{qv*LYIO{zq`$gIjtalQpK5NrwgOyCdc$=4 zbGs;7VO^~hsEM#f_O;%~kpv5(C2IMogV>$%pO6w2_M?$2A(wN@o z5lNBg{48BJ0SP)<{^P0|uXg@Apj>hsBCuc2~>U9^~S^FtvI zScS6nnGd00d%0i*24-T6NBa$aNQcy6Od z@m5nKA|dU9%=Zeb%h_JUr5E zUi`!!I65~T&;z*;vhU4-qNPuxG-L+~jtf@VJ9TWe`@P-oOmh)}vWydr7=m)150a`w zK!QL0Hzn7VV!DplALb97v3wnI>mvlPbr5j;VgXBs4nU^g*^8|+H`y<}00 zT=lLMqSvFhP&JLo2R78)1p+>#qiWs+ZOX0|^?)OD?Vp+}8P3U7haWYctGsnY*QNj0 zdq6aAV)k9Q{5BqRurS?2T{-fo$+CWJ7dYCl0(30Ks7u^O9X*&+i^^$)PG1Qc0ROI2 zCi^)4I9zVk4K@=PX1*MZUv&A7h2que49Wo59uFGg#hS{k?ttaff9%E!dp@yKY^Tfi zW_DN0mU+*dw;L|&_LZ1U5r^knci2ey(RVHtFRnpFZ$zy$CzZ8m=5C+y$?imUS>zdR=*$KHM9WQs`5XM|A7oCPnraoEBBWf;V1 zh`cZCa2ZB6T$;!&!fisuJr2@{{8^#7CIT@Ak;2-dDZi1f57{XdYp!JcT%Sisdtxfw zXP6SYee3eJ&qT7=#6l6Z=Ag~lGk^@?FP#%6YgQs(vy&Btb+X%QpWr3*Q6n^2B070@ zD!gJAjtbV7kn7ab_a5_->yL%#O9~DcVPp2`N!kv11ehrbdGOmHogL zAYsN=nD18KViozrCGYRj8n%IP3QV9;H_ls)FpxKKCIoC$5*-Mv>C`=?pA#q7KjI8^ zt$;Y0iB?va3EK}u$4DykgzjoeZJMAI(6O1zDKj9U$ugXBhBVAL7tP?g!>cA=m=Nuxag|iid*vtRhF4&$%uyMY9(e;L z>U**dxd$2(hq!@7ehn=JUh2qKc!D>SfyJi9qHu5nY2S+oZ#4mFVG;SXb+GR1^*2qx z<6>idP^eYZn-a)23S6>X*Dy{P7mpkY(wjB+25OxUqD1vCKc_q})l2e&OS+AU&u3Fl zSs-7lasWkz<5qXEnR*<_)Gc)|;?vuoJdiuPm@f+2J(v4}4Mv%#6jy{p%lFKdJgf_& zZ3SP8q?MeweD2_UT_ljDffUVrNMEE7bR%U~oOnwMWzT+AdmSv3jU4VWHlATWM+!nq zAWwt!f#(35z%K&TRM;pz;BEF_`&3E(Y96u2%COXBlUjv?(nGK9jAGs^9QJTja^d!} z;%IcPsr5ct@}}f-YXPI}RbS!_dd&&JAZ4;%W0`(ul8jz9zjcY6&!B)@k6$(XsLEgX z`NQ>ZYG&a@%S1$*&k4C-ZINRu&%;=W+kufWorn4d1G4Z|dXVJaU(AN~LJUj&ooYUc zD!`IdNouqQY=a>;a*;CwsiyS1Ueq-dc$(S2?fCJVEU9Tx_!&x}p2<%&l=^@jBbWDyA?1+`IEw3k8f9B^x|p0W@b;5ql! zr_!@Cuzzy+Yph}Yw@dx4aT0J)Pxr`4}bF+w3{`p8|@4z-LV=xeS7cDfRXDt z z2SPahKtHx|d6E#FB-cn-og#t;=lEdVqcIIF6N>?3$?~aBCNJMkZ@psJExivc1+Cbh z>CzFYoelA8d2~%&o&7D;_ZfT?u#kBkjCj;~`CYP5i>B_x`|K#yRM+*Bl}P<@?4=-WhZ4 zHQm~p5OiI*?z;L**SVER0W#|*qNsLzCH>QGZGX*^FwhDXhZ7qwJHJ+3aBEW0a4|Dz zTn(l-jdpuy?~IzR(u(+{;gZR?!+pBpu_Akrt|<}vxk18cm%X=(dyW_iHx=hX2o70# z6A{M?0vz7uL|LjcL#WMKUZ>z_Y~P`#B1tlm@LPuZo=dF|hst#b69e%&8S8~d&bazC zRC+qScxt_RIYa%Z_};GiI;fvh@8orldMPijY)QZ&ZRrM?_o^>7v;Jm%!ZhFCKE0D) zyAxUhx_c3HvTSPiy?QGRgeX|nzj1bXsE!=3Q|t!mfegmrnlyGvTzReX?COmvQM=iFj){{@&xU^D;# literal 0 HcmV?d00001 diff --git a/images/icons/map.png b/images/icons/map.png new file mode 100644 index 0000000000000000000000000000000000000000..78994f274244bcfb7bdea78dd20d9c750fc0f45b GIT binary patch literal 1221 zcmV;$1UmbPP)Ve~zkm(EPT;4gTp}j?2hH;HVgOZAprn`p27m!GU*KS*KSa+uSm1d9HZEync zj{)h+5s@RnC14$J52&ymw>cV}M3L|hl+Z(xw&TtKL$>2?Qc~nhCG4>s*D`m51DsP* zTmw$UrJ=A9b(ryWpvQLH8YRVCBublsw}3t+#gy&1-sWe$HPsYpfFf+@cmM)&HZ6xdE$$ELPU~Sc! z_OJ}aQr)ktXO@*nhF|UlJ{d1ZeJV}u`i*$LkEiGPf!2u%+i~A8db7Zrw&PYU*MZsm z_dC77=il7iqX+P(W jV1D#V z_x$g<=YQ^wU;{W_PyiNyF|xx7FcJFh9{{-~lTT#q9AF4|I_)$gkfS>gojCZ?&fn6( zuMar0-lDy25YVCT8X)Rq%Z?YQ+Zp1Pk?UY5xAg06jpNPGYo%7IPmDS|(r5^M7sm_U z0uBM+g}(c$;|1f67rYBpfLX^2?gBmpo(p~V#|;Uzt8>Q--UeO(=7IEFf3@pO0$xu2sSfh^5cvu9o7g(asSJ zI9@Pf<<>3~;B1z_W5DmX`!C08C+xjmT#7(aWK(IZ( zysPKb@tK8}KY70y0U7%4!4_}HLEx{{`H_3h^^F$CP)Z}UqLxHxqtQl_=;685xW?Ag zr6ajkq}3t{X=7Xe<-%xjEFUKcH5n7us+>GL%LBvX)Ko$&6A)0y4@`AMh6009nnWw4 zRzxypZ*hd79fK&PkY>$pjLG%>Uvg|Fu>ho2tj0HpWK4LY3P2=dDp8e0N%B4YD5DYf zUQcmm6C@nqNr0VO7CAN!ClAlEw>ScT!654X^}YD<8!VJB-J*hLvN{B9G~ZtQfuS9P zL^7sy;3yaWT;f7`2_XbmudSf9rq_O}4P~7L+Gx)Gwun-SN>rtE;3yZ$OMGzt3#3*k ztx#r-z=Zu)6Im6R?fKKl(BIFF%U)HdC0jAtPXq~7-p244vb?3z7i+_ z2a0`kfOE|lIRXO>wK6=Xa%h44jz8{ zUG{u!zvT!D35@9O@fT3b`4!mZ6ieM06R8!n(RW36(B^M;fTllaQ@WN|);nODQ(TIl z$a&Zcu%nxkQUd!J7yA}fV{Q5a<5h+I<80zj3g^Q}m0fYk_y*=DaNIDXIKcn_002ov JPDHLkV1nG9!Sw(D diff --git a/images/icons/upload.png b/images/icons/upload.png new file mode 100644 index 0000000000000000000000000000000000000000..de70c73d0013edadbcac1cc104bc85cb982dd36e GIT binary patch literal 1154 zcmV-|1bzF7P)1P@6> zK~z}7wUX|<+BBUgku=!v8fun#LZb-7 zh)SY#Bj}=jv=~84eYK#AGTlgZ5$(pbbYpCb7Sp=093Fv7A?fV z59$2n3%Hg6M`zl!sssSu_B00|cbiVM!77Q+rpYS#M`1jJo?KZ&EVL=yt`*vx1ojGT zz62hh_I}AY&IoNj1=_8WEx;#M$>)J;q0KR1YcW8o(o}1mDvT-i$SkLS7q|mB0Nf|E zISrf@+T3fE>;%pTZQ6u3oxt0`zq0};HP3}My+EZ^^40Woe*xEl$AD&`%^N^sl{^j{ zPw8oy3qVPEZk0SNw7ExUa{@SJl{^8woPt|h*i&fp4sZncbxsOqNHsrYyaCugEdmc) zC4UC?3vC`1+GK$btdhR~7Wf$W%_`ZN&VQy908gf=R!E%}fX}DRc}Zx~2J~AcKLgGQ zZJra_bOBeak{zkzCg4rr>rwzzPs{Vl8P*J2CA)++52U9*YL)B*`clVrKo4*pI0^h% z3V>oP2yL3JlG#*rPYG>K0q+A(10z<+f+ltVSAg|p17MYWJ>~u+@S#=mG;lhl-(&deL|bVLYr;C zFwkX{Op4vBY7wRQ77(js?+iVn>;P&+cXnOcT4%TM5kz-(`cnsp#R7ODExTp4`MP1k z(wHkY0)4cV=d zYVC&l&6#{0Gm+%66Qdm3)xowkTbOV$`6Px2YBM!0OY+ql5pd2Edq?6Oxg^h~`gJtc zHQ<~h36sx52o+VciDNOs0!X}LEI&>z$z#Vy0mvnJZstabT|%a^8W%i~=*~`6$m*i>P zv4>072e~*jNEAg}8@_?}o~ra;t+CuH@WIpn=LMW|+{}&Ax?>L)hX(oT{P!f@;k?6z zNdP<3f3>JwMP^mz^6J>HIam-}>?Z436h*h3$KK&XD4WyUYDMxmcK`qY07*qoM6N<$g76v`&Hw-a literal 0 HcmV?d00001 diff --git a/layers/CartoDBLayer.py b/layers/CartoDBLayer.py index 6a5d87c..9608fce 100644 --- a/layers/CartoDBLayer.py +++ b/layers/CartoDBLayer.py @@ -44,13 +44,15 @@ class CartoDBLayer(QgsVectorLayer): LAYER_TNAME_PROPERTY = 'tableName' LAYER_SQL_PROPERTY = 'cartoSQL' - def __init__(self, iface, tableName, user, apiKey, owner=None, sql=None, geoJSON=None, filterByExtent=False, spatiaLite=None, readonly=False): + def __init__(self, iface, tableName, user, apiKey, owner=None, sql=None, geoJSON=None, + filterByExtent=False, spatiaLite=None, readonly=False, multiuser=False): # SQLite available? self.iface = iface self.user = user self._apiKey = apiKey self.layerType = 'ogr' self.owner = owner + self.multiuser = multiuser driverName = "SQLite" sqLiteDrv = ogr.GetDriverByName(driverName) self.databasePath = QgisCartoDB.CartoDBPlugin.PLUGIN_DIR + '/db/database.sqlite' @@ -61,7 +63,7 @@ def __init__(self, iface, tableName, user, apiKey, owner=None, sql=None, geoJSON self.forceReadOnly = False or readonly if sql is None: - sql = 'SELECT * FROM ' + ((owner + '.') if owner is not None else '') + self.cartoTable + sql = 'SELECT * FROM ' + self._schema() + self.cartoTable if filterByExtent: extent = self.iface.mapCanvas().extent() sql = sql + " WHERE ST_Intersects(ST_GeometryFromText('{}', 4326), the_geom)".format(extent.asWktPolygon()) @@ -169,7 +171,7 @@ def _loadData(self, sql, geoJSON=None, spatiaLite=None): self.setCustomProperty(CartoDBLayer.LAYER_SQL_PROPERTY, sql) def _uneditableFields(self): - schema = 'public' if self.owner is None else self.owner + schema = 'public' if not self.multiuser else self.owner sql = "SELECT table_name, column_name, column_default, is_nullable, data_type, table_schema \ FROM information_schema.columns \ WHERE data_type != 'USER-DEFINED' AND table_schema = '" + schema + "' AND table_name = '" + self.cartoTable + "' \ @@ -224,11 +226,10 @@ def _beforeCommitChanges(self): self._deleteFeatures(editBuffer.deletedFeatureIds()) def _updateAttributes(self, changedAttributeValues): - schema = '' if self.owner is None else (self.owner + '.') provider = self.dataProvider() for featureID, v in changedAttributeValues.iteritems(): QgsMessageLog.logMessage('Update attributes for feature ID: ' + str(featureID), 'CartoDB Plugin', QgsMessageLog.INFO) - sql = "UPDATE " + schema + self.cartoTable + " SET " + sql = "UPDATE " + self._schema() + self.cartoTable + " SET " request = QgsFeatureRequest().setFilterFid(featureID) try: feature = self.getFeatures(request).next() @@ -263,12 +264,11 @@ def _updateAttributes(self, changedAttributeValues): level=self.iface.messageBar().WARNING, duration=10) def _updateGeometries(self, changedGeometries): - schema = '' if self.owner is None else (self.owner + '.') for featureID, geom in changedGeometries.iteritems(): QgsMessageLog.logMessage('Update geometry for feature ID: ' + str(featureID), 'CartoDB Plugin', QgsMessageLog.INFO) request = QgsFeatureRequest().setFilterFid(featureID) try: - sql = "UPDATE " + schema + self.cartoTable + " SET the_geom = " + sql = "UPDATE " + self._schema() + self.cartoTable + " SET the_geom = " feature = self.getFeatures(request).next() sql = sql + "ST_GeomFromText('" + geom.exportToWkt() + "', ST_SRID(the_geom)) WHERE cartodb_id = " + unicode(feature['cartodb_id']) sql = sql.encode('utf-8') @@ -285,11 +285,10 @@ def _updateGeometries(self, changedGeometries): level=self.iface.messageBar().WARNING, duration=10) def _addFeatures(self, addedFeatures): - schema = '' if self.owner is None else (self.owner + '.') provider = self.dataProvider() for featureID, feature in addedFeatures.iteritems(): QgsMessageLog.logMessage('Add feature with feature ID: ' + str(featureID), 'CartoDB Plugin', QgsMessageLog.INFO) - sql = "INSERT INTO " + schema + self.cartoTable + " (" + sql = "INSERT INTO " + self._schema() + self.cartoTable + " (" addComma = False for field in feature.fields(): if unicode(feature[field.name()]) == 'NULL' or feature[field.name()] is None: @@ -311,26 +310,29 @@ def _addFeatures(self, addedFeatures): addComma = True if addComma: sql = sql + ", " - sql = sql + "ST_GeomFromText('" + feature.geometry().exportToWkt() + "', 4326)) RETURNING cartodb_id" + sql = sql + "ST_GeomFromText('" + feature.geometry().exportToWkt() + "', 4326)) RETURNING cartodb_id, created_at, updated_at" sql = sql.encode('utf-8') res = self._updateSQL(sql, 'Some error ocurred inserting feature') if isinstance(res, dict) and res['total_rows'] == 1: self.iface.messageBar().pushMessage('Info', 'Feature inserted at CartoDB servers', level=self.iface.messageBar().INFO, duration=10) - self.setFieldEditable(self.fieldNameIndex('cartodb_id'), True) - self.editBuffer().changeAttributeValue(featureID, self.fieldNameIndex('cartodb_id'), res['rows'][0]['cartodb_id'], None) - self.setFieldEditable(self.fieldNameIndex('cartodb_id'), False) + for f in ['cartodb_id', 'created_at', 'updated_at']: + self._updateNullableFields(featureID, f, res['rows'][0][f]) + + def _updateNullableFields(self, featureID, fieldName, value): + self.setFieldEditable(self.fieldNameIndex(fieldName), True) + self.editBuffer().changeAttributeValue(featureID, self.fieldNameIndex(fieldName), value, None) + self.setFieldEditable(self.fieldNameIndex(fieldName), False) def _deleteFeatures(self, deletedFeatureIds): - schema = '' if self.owner is None else (self.owner + '.') provider = self.dataProvider() for featureID in deletedFeatureIds: QgsMessageLog.logMessage('Delete feature with feature ID: ' + str(featureID), 'CartoDB Plugin', QgsMessageLog.INFO) request = QgsFeatureRequest().setFilterFid(featureID) try: feature = provider.getFeatures(request).next() - sql = "DELETE FROM " + schema + self.cartoTable + " WHERE cartodb_id = " + unicode(feature['cartodb_id']) + sql = "DELETE FROM " + self._schema() + self.cartoTable + " WHERE cartodb_id = " + unicode(feature['cartodb_id']) res = self._updateSQL(sql, 'Some error ocurred deleting feature') if isinstance(res, dict) and res['total_rows'] == 1: self.iface.messageBar().pushMessage('Info', @@ -354,6 +356,13 @@ def _updateSQL(self, sql, errorMsg): self.iface.messageBar().pushMessage('Error!!', errorMsg, level=self.iface.messageBar().CRITICAL, duration=10) return e + def _schema(self): + schema = self.schema() + return schema + ('.' if schema != '' else '') + + def schema(self): + return '' if not self.multiuser else self.owner + def tableName(self): return self.cartoTable @@ -377,12 +386,13 @@ class CartoDBLayerWorker(QObject): finished = pyqtSignal(CartoDBLayer) error = pyqtSignal(Exception, basestring) - def __init__(self, iface, tableName, owner=None, dlg=None, sql=None, filterByExtent=False, readonly=False): + def __init__(self, iface, tableName, owner=None, dlg=None, sql=None, filterByExtent=False, readonly=False, multiuser=False): QObject.__init__(self) self.iface = iface self.owner = owner self.tableName = tableName self.readonly = readonly + self.multiuser = multiuser self.dlg = dlg self.sql = sql self.filterByExtent = filterByExtent @@ -398,7 +408,7 @@ def load(self): @pyqtSlot(str) def _loadData(self, spatiaLite): layer = CartoDBLayer(self.iface, self.tableName, self.dlg.currentUser, self.dlg.currentApiKey, - self.owner, self.sql, spatiaLite=spatiaLite, readonly=self.readonly) + self.owner, self.sql, spatiaLite=spatiaLite, readonly=self.readonly, multiuser=self.multiuser) self.finished.emit(layer) @pyqtSlot() diff --git a/metadata.txt b/metadata.txt index da50bdd..74bcbb6 100644 --- a/metadata.txt +++ b/metadata.txt @@ -26,7 +26,10 @@ email=michaelsalgado@gkudos.com changelog=0.1.9 - Default symbology for not supported symbols. - Add messages for not supported symbols. - - Add uploaded message + - Add uploaded message. + - Change icons. + - Fix error updating layer single user account. + - Fix error getting columns in SQL dialog. 0.1.8 - Remove connection controls in SQL Editor. - Add composite mode in create maps. diff --git a/resources.qrc b/resources.qrc index 05b973d..980d6ba 100644 --- a/resources.qrc +++ b/resources.qrc @@ -12,7 +12,7 @@ images/icons/rectangle.png - images/icons/add_sql.png + images/icons/sql.png images/icons/text.png @@ -29,4 +29,10 @@ images/icons/layers.png + + images/icons/upload.png + + + images/icons/map.png + diff --git a/toolbars/CartoDBToolbar.py b/toolbars/CartoDBToolbar.py index 1ef0890..65740bb 100644 --- a/toolbars/CartoDBToolbar.py +++ b/toolbars/CartoDBToolbar.py @@ -39,6 +39,7 @@ def __init__(self, parent=None, flags=Qt.WindowFlags(0)): if self.currentUser: self.currentApiKey = self.settings.value('/CartoDBPlugin/%s/api' % self.currentUser) self.currentMultiuser = self.settings.value('/CartoDBPlugin/%s/multiuser' % self.currentUser, False) + self.currentMultiuser = self.currentMultiuser in ['True', 'true', True] else: self.currentApiKey = None self.currentMultiuser = None diff --git a/widgets/ListItemWidgets.py b/widgets/ListItemWidgets.py index ee5dc9e..1b4ecc1 100644 --- a/widgets/ListItemWidgets.py +++ b/widgets/ListItemWidgets.py @@ -26,12 +26,13 @@ class CartoDBDatasetsListItem(QWidget): - def __init__(self, tableName=None, tableOwner=None, size=None, rows=None, shared=False): + def __init__(self, tableName=None, tableOwner=None, size=None, rows=None, multiuser=False, shared=False): QWidget.__init__(self) self.ui = Ui_ListItem() self.ui.setupUi(self) self.shared = shared + self.multiuser = multiuser self.readonly = False self.tableOwner = tableOwner