wmglobalqueue 2.3.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of wmglobalqueue might be problematic. Click here for more details.
- Utils/CPMetrics.py +270 -0
- Utils/CertTools.py +62 -0
- Utils/EmailAlert.py +50 -0
- Utils/ExtendedUnitTestCase.py +62 -0
- Utils/FileTools.py +182 -0
- Utils/IteratorTools.py +80 -0
- Utils/MathUtils.py +31 -0
- Utils/MemoryCache.py +119 -0
- Utils/Patterns.py +24 -0
- Utils/Pipeline.py +137 -0
- Utils/PortForward.py +97 -0
- Utils/ProcessStats.py +103 -0
- Utils/PythonVersion.py +17 -0
- Utils/Signals.py +36 -0
- Utils/TemporaryEnvironment.py +27 -0
- Utils/Throttled.py +227 -0
- Utils/Timers.py +130 -0
- Utils/Timestamps.py +86 -0
- Utils/TokenManager.py +143 -0
- Utils/Tracing.py +60 -0
- Utils/TwPrint.py +98 -0
- Utils/Utilities.py +308 -0
- Utils/__init__.py +11 -0
- WMCore/ACDC/Collection.py +57 -0
- WMCore/ACDC/CollectionTypes.py +12 -0
- WMCore/ACDC/CouchCollection.py +67 -0
- WMCore/ACDC/CouchFileset.py +238 -0
- WMCore/ACDC/CouchService.py +73 -0
- WMCore/ACDC/DataCollectionService.py +485 -0
- WMCore/ACDC/Fileset.py +94 -0
- WMCore/ACDC/__init__.py +11 -0
- WMCore/Algorithms/Alarm.py +39 -0
- WMCore/Algorithms/MathAlgos.py +274 -0
- WMCore/Algorithms/MiscAlgos.py +67 -0
- WMCore/Algorithms/ParseXMLFile.py +115 -0
- WMCore/Algorithms/Permissions.py +27 -0
- WMCore/Algorithms/Singleton.py +58 -0
- WMCore/Algorithms/SubprocessAlgos.py +129 -0
- WMCore/Algorithms/__init__.py +7 -0
- WMCore/Cache/GenericDataCache.py +98 -0
- WMCore/Cache/WMConfigCache.py +572 -0
- WMCore/Cache/__init__.py +0 -0
- WMCore/Configuration.py +651 -0
- WMCore/DAOFactory.py +47 -0
- WMCore/DataStructs/File.py +177 -0
- WMCore/DataStructs/Fileset.py +140 -0
- WMCore/DataStructs/Job.py +182 -0
- WMCore/DataStructs/JobGroup.py +142 -0
- WMCore/DataStructs/JobPackage.py +49 -0
- WMCore/DataStructs/LumiList.py +734 -0
- WMCore/DataStructs/Mask.py +219 -0
- WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
- WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
- WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
- WMCore/DataStructs/MathStructs/__init__.py +0 -0
- WMCore/DataStructs/Pickleable.py +24 -0
- WMCore/DataStructs/Run.py +256 -0
- WMCore/DataStructs/Subscription.py +175 -0
- WMCore/DataStructs/WMObject.py +47 -0
- WMCore/DataStructs/WorkUnit.py +112 -0
- WMCore/DataStructs/Workflow.py +60 -0
- WMCore/DataStructs/__init__.py +8 -0
- WMCore/Database/CMSCouch.py +1349 -0
- WMCore/Database/ConfigDBMap.py +29 -0
- WMCore/Database/CouchUtils.py +118 -0
- WMCore/Database/DBCore.py +198 -0
- WMCore/Database/DBCreator.py +113 -0
- WMCore/Database/DBExceptionHandler.py +57 -0
- WMCore/Database/DBFactory.py +110 -0
- WMCore/Database/DBFormatter.py +177 -0
- WMCore/Database/Dialects.py +13 -0
- WMCore/Database/ExecuteDAO.py +327 -0
- WMCore/Database/MongoDB.py +241 -0
- WMCore/Database/MySQL/Destroy.py +42 -0
- WMCore/Database/MySQL/ListUserContent.py +20 -0
- WMCore/Database/MySQL/__init__.py +9 -0
- WMCore/Database/MySQLCore.py +132 -0
- WMCore/Database/Oracle/Destroy.py +56 -0
- WMCore/Database/Oracle/ListUserContent.py +19 -0
- WMCore/Database/Oracle/__init__.py +9 -0
- WMCore/Database/ResultSet.py +44 -0
- WMCore/Database/Transaction.py +91 -0
- WMCore/Database/__init__.py +9 -0
- WMCore/Database/ipy_profile_couch.py +438 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
- WMCore/GlobalWorkQueue/__init__.py +0 -0
- WMCore/GroupUser/CouchObject.py +127 -0
- WMCore/GroupUser/Decorators.py +51 -0
- WMCore/GroupUser/Group.py +33 -0
- WMCore/GroupUser/Interface.py +73 -0
- WMCore/GroupUser/User.py +96 -0
- WMCore/GroupUser/__init__.py +11 -0
- WMCore/Lexicon.py +836 -0
- WMCore/REST/Auth.py +202 -0
- WMCore/REST/CherryPyPeriodicTask.py +166 -0
- WMCore/REST/Error.py +333 -0
- WMCore/REST/Format.py +642 -0
- WMCore/REST/HeartbeatMonitorBase.py +90 -0
- WMCore/REST/Main.py +623 -0
- WMCore/REST/Server.py +2435 -0
- WMCore/REST/Services.py +24 -0
- WMCore/REST/Test.py +120 -0
- WMCore/REST/Tools.py +38 -0
- WMCore/REST/Validation.py +250 -0
- WMCore/REST/__init__.py +1 -0
- WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
- WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
- WMCore/ReqMgr/DataStructs/__init__.py +0 -0
- WMCore/ReqMgr/__init__.py +1 -0
- WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
- WMCore/Services/AlertManager/__init__.py +0 -0
- WMCore/Services/CRIC/CRIC.py +238 -0
- WMCore/Services/CRIC/__init__.py +0 -0
- WMCore/Services/DBS/DBS3Reader.py +1044 -0
- WMCore/Services/DBS/DBSConcurrency.py +44 -0
- WMCore/Services/DBS/DBSErrors.py +113 -0
- WMCore/Services/DBS/DBSReader.py +23 -0
- WMCore/Services/DBS/DBSUtils.py +139 -0
- WMCore/Services/DBS/DBSWriterObjects.py +381 -0
- WMCore/Services/DBS/ProdException.py +133 -0
- WMCore/Services/DBS/__init__.py +8 -0
- WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
- WMCore/Services/FWJRDB/__init__.py +0 -0
- WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
- WMCore/Services/HTTPS/__init__.py +0 -0
- WMCore/Services/LogDB/LogDB.py +201 -0
- WMCore/Services/LogDB/LogDBBackend.py +191 -0
- WMCore/Services/LogDB/LogDBExceptions.py +11 -0
- WMCore/Services/LogDB/LogDBReport.py +85 -0
- WMCore/Services/LogDB/__init__.py +0 -0
- WMCore/Services/MSPileup/__init__.py +0 -0
- WMCore/Services/MSUtils/MSUtils.py +54 -0
- WMCore/Services/MSUtils/__init__.py +0 -0
- WMCore/Services/McM/McM.py +173 -0
- WMCore/Services/McM/__init__.py +8 -0
- WMCore/Services/MonIT/Grafana.py +133 -0
- WMCore/Services/MonIT/__init__.py +0 -0
- WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
- WMCore/Services/PyCondor/PyCondorUtils.py +105 -0
- WMCore/Services/PyCondor/__init__.py +0 -0
- WMCore/Services/ReqMgr/ReqMgr.py +261 -0
- WMCore/Services/ReqMgr/__init__.py +0 -0
- WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
- WMCore/Services/ReqMgrAux/__init__.py +0 -0
- WMCore/Services/RequestDB/RequestDBReader.py +267 -0
- WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
- WMCore/Services/RequestDB/__init__.py +0 -0
- WMCore/Services/Requests.py +624 -0
- WMCore/Services/Rucio/Rucio.py +1287 -0
- WMCore/Services/Rucio/RucioUtils.py +74 -0
- WMCore/Services/Rucio/__init__.py +0 -0
- WMCore/Services/RucioConMon/RucioConMon.py +128 -0
- WMCore/Services/RucioConMon/__init__.py +0 -0
- WMCore/Services/Service.py +400 -0
- WMCore/Services/StompAMQ/__init__.py +0 -0
- WMCore/Services/TagCollector/TagCollector.py +155 -0
- WMCore/Services/TagCollector/XMLUtils.py +98 -0
- WMCore/Services/TagCollector/__init__.py +0 -0
- WMCore/Services/UUIDLib.py +13 -0
- WMCore/Services/UserFileCache/UserFileCache.py +160 -0
- WMCore/Services/UserFileCache/__init__.py +8 -0
- WMCore/Services/WMAgent/WMAgent.py +63 -0
- WMCore/Services/WMAgent/__init__.py +0 -0
- WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
- WMCore/Services/WMArchive/DataMap.py +463 -0
- WMCore/Services/WMArchive/WMArchive.py +33 -0
- WMCore/Services/WMArchive/__init__.py +0 -0
- WMCore/Services/WMBS/WMBS.py +97 -0
- WMCore/Services/WMBS/__init__.py +0 -0
- WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
- WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
- WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
- WMCore/Services/WMStats/WMStatsReader.py +445 -0
- WMCore/Services/WMStats/WMStatsWriter.py +273 -0
- WMCore/Services/WMStats/__init__.py +0 -0
- WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
- WMCore/Services/WMStatsServer/__init__.py +0 -0
- WMCore/Services/WorkQueue/WorkQueue.py +492 -0
- WMCore/Services/WorkQueue/__init__.py +0 -0
- WMCore/Services/__init__.py +8 -0
- WMCore/Services/pycurl_manager.py +574 -0
- WMCore/WMBase.py +50 -0
- WMCore/WMConnectionBase.py +164 -0
- WMCore/WMException.py +183 -0
- WMCore/WMExceptions.py +269 -0
- WMCore/WMFactory.py +76 -0
- WMCore/WMInit.py +228 -0
- WMCore/WMLogging.py +108 -0
- WMCore/WMSpec/ConfigSectionTree.py +442 -0
- WMCore/WMSpec/Persistency.py +135 -0
- WMCore/WMSpec/Steps/BuildMaster.py +87 -0
- WMCore/WMSpec/Steps/BuildTools.py +201 -0
- WMCore/WMSpec/Steps/Builder.py +97 -0
- WMCore/WMSpec/Steps/Diagnostic.py +89 -0
- WMCore/WMSpec/Steps/Emulator.py +62 -0
- WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
- WMCore/WMSpec/Steps/Executor.py +210 -0
- WMCore/WMSpec/Steps/StepFactory.py +213 -0
- WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
- WMCore/WMSpec/Steps/Template.py +204 -0
- WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
- WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
- WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
- WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
- WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
- WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
- WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
- WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
- WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
- WMCore/WMSpec/Steps/__init__.py +8 -0
- WMCore/WMSpec/Utilities.py +63 -0
- WMCore/WMSpec/WMSpecErrors.py +12 -0
- WMCore/WMSpec/WMStep.py +347 -0
- WMCore/WMSpec/WMTask.py +1980 -0
- WMCore/WMSpec/WMWorkload.py +2288 -0
- WMCore/WMSpec/WMWorkloadTools.py +370 -0
- WMCore/WMSpec/__init__.py +9 -0
- WMCore/WorkQueue/DataLocationMapper.py +273 -0
- WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
- WMCore/WorkQueue/DataStructs/Block.py +48 -0
- WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
- WMCore/WorkQueue/DataStructs/__init__.py +0 -0
- WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
- WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
- WMCore/WorkQueue/Policy/End/__init__.py +32 -0
- WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
- WMCore/WorkQueue/Policy/Start/Block.py +258 -0
- WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
- WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
- WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
- WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
- WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
- WMCore/WorkQueue/Policy/__init__.py +57 -0
- WMCore/WorkQueue/WMBSHelper.py +772 -0
- WMCore/WorkQueue/WorkQueue.py +1237 -0
- WMCore/WorkQueue/WorkQueueBackend.py +750 -0
- WMCore/WorkQueue/WorkQueueBase.py +39 -0
- WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
- WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
- WMCore/WorkQueue/WorkQueueUtils.py +130 -0
- WMCore/WorkQueue/__init__.py +13 -0
- WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
- WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
- WMCore/Wrappers/__init__.py +6 -0
- WMCore/__init__.py +10 -0
- wmglobalqueue-2.3.10.data/data/bin/wmc-dist-patch +15 -0
- wmglobalqueue-2.3.10.data/data/bin/wmc-dist-unpatch +8 -0
- wmglobalqueue-2.3.10.data/data/bin/wmc-httpd +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/README.md +40 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/language +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
- wmglobalqueue-2.3.10.dist-info/LICENSE +202 -0
- wmglobalqueue-2.3.10.dist-info/METADATA +24 -0
- wmglobalqueue-2.3.10.dist-info/NOTICE +16 -0
- wmglobalqueue-2.3.10.dist-info/RECORD +345 -0
- wmglobalqueue-2.3.10.dist-info/WHEEL +5 -0
- wmglobalqueue-2.3.10.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""
|
|
2
|
+
File : MongoDB.py
|
|
3
|
+
Description: Provides a wrapper class for MongoDB
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# futures
|
|
7
|
+
from __future__ import division, print_function
|
|
8
|
+
from builtins import str, object
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
import mongomock
|
|
12
|
+
except ImportError:
|
|
13
|
+
# this library should only be required by unit tests
|
|
14
|
+
mongomock = None
|
|
15
|
+
|
|
16
|
+
from pymongo import MongoClient, errors, IndexModel
|
|
17
|
+
from pymongo.errors import ConnectionFailure
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MongoDB(object):
|
|
21
|
+
"""
|
|
22
|
+
A simple wrapper class for creating a connection to a MongoDB instance
|
|
23
|
+
"""
|
|
24
|
+
def __init__(self, database=None, server=None,
|
|
25
|
+
create=False, collections=None, testIndexes=False,
|
|
26
|
+
logger=None, mockMongoDB=False, **kwargs):
|
|
27
|
+
"""
|
|
28
|
+
:databases: A database Name to connect to
|
|
29
|
+
:server: The server url or a list of (server:port) pairs (see https://docs.mongodb.com/manual/reference/connection-string/)
|
|
30
|
+
:create: A flag to trigger a database creation (if missing) during
|
|
31
|
+
object construction, together with collections if present.
|
|
32
|
+
:collections: A list of tuples describing collections with indexes -
|
|
33
|
+
the first element is considered the collection name, all
|
|
34
|
+
the rest elements are considered as indexes
|
|
35
|
+
:testIndexes: A flag to trigger index test and eventually to create them
|
|
36
|
+
if missing (TODO)
|
|
37
|
+
:mockMongoDB: A flag to trigger a database simulation instead of trying
|
|
38
|
+
to connect to a real database server.
|
|
39
|
+
:logger: Logger
|
|
40
|
+
|
|
41
|
+
Here follows a short list of usefull optional parameters accepted by the
|
|
42
|
+
MongoClient which may be passed as keyword arguments to the current module:
|
|
43
|
+
|
|
44
|
+
:replicaSet: The name of the replica set to connect to. The driver will verify
|
|
45
|
+
that all servers it connects to match this name. Implies that the
|
|
46
|
+
hosts specified are a seed list and the driver should attempt to
|
|
47
|
+
find all members of the set. Defaults to None.
|
|
48
|
+
:port: The port number on which to connect. It is overwritten by the ports
|
|
49
|
+
defined in the Url string or from the tuples listed in the server list
|
|
50
|
+
:connect: If True, immediately begin connecting to MongoDB in the background.
|
|
51
|
+
Otherwise connect on the first operation.
|
|
52
|
+
:directConnection: If True, forces the client to connect directly to the specified MongoDB
|
|
53
|
+
host as a standalone. If False, the client connects to the entire
|
|
54
|
+
replica set of which the given MongoDB host(s) is a part.
|
|
55
|
+
If this is True and a mongodb+srv:// URI or a URI containing multiple
|
|
56
|
+
seeds is provided, an exception will be raised.
|
|
57
|
+
:username: A string
|
|
58
|
+
:password: A string
|
|
59
|
+
Although username and password must be percent-escaped in a MongoDB URI,
|
|
60
|
+
they must not be percent-escaped when passed as parameters. In this example,
|
|
61
|
+
both the space and slash special characters are passed as-is:
|
|
62
|
+
MongoClient(username="user name", password="pass/word")
|
|
63
|
+
"""
|
|
64
|
+
self.server = server
|
|
65
|
+
self.logger = logger
|
|
66
|
+
self.mockMongoDB = mockMongoDB
|
|
67
|
+
if mockMongoDB and mongomock is None:
|
|
68
|
+
msg = "You are trying to mock MongoDB, but you do not have mongomock in the python path."
|
|
69
|
+
self.logger.critical(msg)
|
|
70
|
+
raise ImportError(msg)
|
|
71
|
+
|
|
72
|
+
# NOTE: We need to explicitely check for server availiability.
|
|
73
|
+
# From pymongo Documentation: https://pymongo.readthedocs.io/en/stable/api/pymongo/mongo_client.html
|
|
74
|
+
# """
|
|
75
|
+
# ...
|
|
76
|
+
# Starting with version 3.0 the :class:`MongoClient`
|
|
77
|
+
# constructor no longer blocks while connecting to the server or
|
|
78
|
+
# servers, and it no longer raises
|
|
79
|
+
# :class:`~pymongo.errors.ConnectionFailure` if they are
|
|
80
|
+
# unavailable, nor :class:`~pymongo.errors.ConfigurationError`
|
|
81
|
+
# if the user's credentials are wrong. Instead, the constructor
|
|
82
|
+
# returns immediately and launches the connection process on
|
|
83
|
+
# background threads.
|
|
84
|
+
# ...
|
|
85
|
+
# """
|
|
86
|
+
try:
|
|
87
|
+
if mockMongoDB:
|
|
88
|
+
self.client = mongomock.MongoClient()
|
|
89
|
+
self.logger.info("NOTICE: MongoDB is set to use mongomock, instead of real database.")
|
|
90
|
+
else:
|
|
91
|
+
self.client = MongoClient(host=self.server, **kwargs)
|
|
92
|
+
self.client.server_info()
|
|
93
|
+
self.client.admin.command('ping')
|
|
94
|
+
except ConnectionFailure as ex:
|
|
95
|
+
msg = "Could not connect to MongoDB server: %s. Server not available. \n"
|
|
96
|
+
msg += "Giving up Now."
|
|
97
|
+
self.logger.error(msg, self.server)
|
|
98
|
+
raise ex from None
|
|
99
|
+
except Exception as ex:
|
|
100
|
+
msg = "Could not connect to MongoDB server: %s. Due to unknown reason: %s\n"
|
|
101
|
+
msg += "Giving up Now."
|
|
102
|
+
self.logger.error(msg, self.server, str(ex))
|
|
103
|
+
raise ex from None
|
|
104
|
+
self.create = create
|
|
105
|
+
self.testIndexes = testIndexes
|
|
106
|
+
self.dbName = database
|
|
107
|
+
self.collections = collections or []
|
|
108
|
+
|
|
109
|
+
self._dbConnect(database)
|
|
110
|
+
|
|
111
|
+
if self.create and self.collections:
|
|
112
|
+
for collection in self.collections:
|
|
113
|
+
self._collCreate(collection, database)
|
|
114
|
+
|
|
115
|
+
if self.testIndexes and self.collections:
|
|
116
|
+
for collection in self.collections:
|
|
117
|
+
self._indexTest(collection[0], collection[1])
|
|
118
|
+
|
|
119
|
+
def _indexTest(self, collection, index):
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
def _collTest(self, coll, db):
|
|
123
|
+
# self[db].list_collection_names()
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
def collCreate(self, coll):
|
|
127
|
+
"""
|
|
128
|
+
A public method for _collCreate
|
|
129
|
+
"""
|
|
130
|
+
self._collCreate(coll, self.database)
|
|
131
|
+
|
|
132
|
+
def _collCreate(self, coll, db):
|
|
133
|
+
"""
|
|
134
|
+
A function used to explicitly create a collection with the relevant
|
|
135
|
+
indexes - used to avoid the Lazy Creating from MongoDB and eventual issues
|
|
136
|
+
in case we end up with no indexed collection, especially ones missing
|
|
137
|
+
the (`unique` index parameter)
|
|
138
|
+
:coll: A tuple describing one collection with indexes -
|
|
139
|
+
The first element is considered to be the collection name, and all
|
|
140
|
+
the rest of the elements are considered to be indexes.
|
|
141
|
+
The indexes must be of type IndexModel. See pymongo documentation:
|
|
142
|
+
|
|
143
|
+
https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.create_index
|
|
144
|
+
|
|
145
|
+
:db: The database name for the collection
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
collName = coll[0]
|
|
149
|
+
collIndexes = list(coll[1:])
|
|
150
|
+
try:
|
|
151
|
+
self.client[db].create_collection(collName)
|
|
152
|
+
except errors.CollectionInvalid:
|
|
153
|
+
# this error is thrown in case of an already existing collection
|
|
154
|
+
msg = "Collection '{}' Already exists in database '{}'".format(coll, db)
|
|
155
|
+
self.logger.warning(msg)
|
|
156
|
+
|
|
157
|
+
if collIndexes:
|
|
158
|
+
for index in collIndexes:
|
|
159
|
+
if not isinstance(index, IndexModel):
|
|
160
|
+
msg = "ERR: Bad Index type for collection %s" % collName
|
|
161
|
+
raise errors.InvalidName
|
|
162
|
+
try:
|
|
163
|
+
self.client[db][collName].create_indexes(collIndexes)
|
|
164
|
+
except Exception as ex:
|
|
165
|
+
msg = "Failed to create indexes on collection: %s\n%s" % (collName, str(ex))
|
|
166
|
+
self.logger.error(msg)
|
|
167
|
+
raise ex
|
|
168
|
+
|
|
169
|
+
def _dbTest(self, db):
|
|
170
|
+
"""
|
|
171
|
+
Tests database connection.
|
|
172
|
+
"""
|
|
173
|
+
# Test connection (from mongoDB documentation):
|
|
174
|
+
# https://api.mongodb.com/python/3.4.0/api/pymongo/mongo_client.html
|
|
175
|
+
try:
|
|
176
|
+
# The 'ismaster' command is cheap and does not require auth.
|
|
177
|
+
self.client.admin.command('ismaster')
|
|
178
|
+
except errors.ConnectionFailure as ex:
|
|
179
|
+
msg = "Server not available: %s" % str(ex)
|
|
180
|
+
self.logger.error(msg)
|
|
181
|
+
raise ex
|
|
182
|
+
|
|
183
|
+
# Test for database existence
|
|
184
|
+
if db not in self.client.list_database_names():
|
|
185
|
+
msg = "Missing MongoDB databases: %s" % db
|
|
186
|
+
self.logger.error(msg)
|
|
187
|
+
raise errors.InvalidName
|
|
188
|
+
|
|
189
|
+
def _dbCreate(self, db):
|
|
190
|
+
# creating an empty collection in order to create the database
|
|
191
|
+
_initColl = self.client[db].create_collection('_initCollection')
|
|
192
|
+
_initColl.insert_one({})
|
|
193
|
+
# NOTE: never delete the _initCollection if you want the database to persist
|
|
194
|
+
# self.client[db].drop_collection('_initCollection')
|
|
195
|
+
|
|
196
|
+
def dbConnect(self):
|
|
197
|
+
"""
|
|
198
|
+
A public method for _dbConnect
|
|
199
|
+
"""
|
|
200
|
+
self._dbConnect(self.database)
|
|
201
|
+
|
|
202
|
+
def _dbConnect(self, db):
|
|
203
|
+
"""
|
|
204
|
+
The function to be used for the initial database connection creation and testing
|
|
205
|
+
"""
|
|
206
|
+
try:
|
|
207
|
+
setattr(self, db, self.client[db])
|
|
208
|
+
if not self.mockMongoDB:
|
|
209
|
+
self._dbTest(db)
|
|
210
|
+
except errors.ConnectionFailure as ex:
|
|
211
|
+
msg = "Could not connect to MongoDB server for database: %s\n%s\n" % (db, str(ex))
|
|
212
|
+
msg += "Giving up Now."
|
|
213
|
+
self.logger.error(msg)
|
|
214
|
+
raise ex
|
|
215
|
+
except errors.InvalidName as ex:
|
|
216
|
+
msg = "Could not connect to a missing MongoDB databases: %s\n%s" % (db, str(ex))
|
|
217
|
+
self.logger.error(msg)
|
|
218
|
+
if self.create:
|
|
219
|
+
msg = "Trying to create: %s" % db
|
|
220
|
+
self.logger.error(msg)
|
|
221
|
+
try:
|
|
222
|
+
# self._dbCreate(getattr(self, db))
|
|
223
|
+
self._dbCreate(db)
|
|
224
|
+
except Exception as exc:
|
|
225
|
+
msg = "Could not create MongoDB databases: %s\n%s\n" % (db, str(exc))
|
|
226
|
+
msg += "Giving up Now."
|
|
227
|
+
self.logger.error(msg)
|
|
228
|
+
raise exc
|
|
229
|
+
try:
|
|
230
|
+
self._dbTest(db)
|
|
231
|
+
except Exception as exc:
|
|
232
|
+
msg = "Second failure while testing %s\n%s\n" % (db, str(exc))
|
|
233
|
+
msg += "Giving up Now."
|
|
234
|
+
self.logger.error(msg)
|
|
235
|
+
raise exc
|
|
236
|
+
msg = "Database %s successfully created" % db
|
|
237
|
+
self.logger.error(msg)
|
|
238
|
+
except Exception as ex:
|
|
239
|
+
msg = "General Exception while trying to connect to : %s\n%s" % (db, str(ex))
|
|
240
|
+
self.logger.error(msg)
|
|
241
|
+
raise ex
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_Destroy_
|
|
3
|
+
|
|
4
|
+
Implementation of Destroy for MySQL
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from WMCore.Database.DBFormatter import DBFormatter
|
|
9
|
+
|
|
10
|
+
class Destroy(DBFormatter):
|
|
11
|
+
|
|
12
|
+
def execute(self, subscription = None, conn = None, transaction = False):
|
|
13
|
+
|
|
14
|
+
sql = """SELECT DATABASE() AS dbname"""
|
|
15
|
+
|
|
16
|
+
results = self.dbi.processData(sql, {}, conn = conn,
|
|
17
|
+
transaction = transaction)
|
|
18
|
+
|
|
19
|
+
dbName = self.formatDict(results)[0]['dbname']
|
|
20
|
+
|
|
21
|
+
if dbName == None or dbName == 'None':
|
|
22
|
+
# Then we have no database.
|
|
23
|
+
# This presents us with a problem. We've been asked to clear a
|
|
24
|
+
# non-existant DB.
|
|
25
|
+
# Obviously we can't drop it, so what we have to do is try
|
|
26
|
+
# to pull the URL from the threaded dbi and use that
|
|
27
|
+
# to create the proper db
|
|
28
|
+
dbName = self.dbi.engine.url.database
|
|
29
|
+
else:
|
|
30
|
+
sql = """DROP DATABASE %s""" % dbName
|
|
31
|
+
self.dbi.processData(sql, {}, conn = conn,
|
|
32
|
+
transaction = transaction)
|
|
33
|
+
|
|
34
|
+
sql = """CREATE DATABASE %s""" % dbName
|
|
35
|
+
self.dbi.processData(sql, {}, conn = conn,
|
|
36
|
+
transaction = transaction)
|
|
37
|
+
|
|
38
|
+
sql = """USE %s""" % dbName
|
|
39
|
+
self.dbi.processData(sql, {}, conn = conn,
|
|
40
|
+
transaction = transaction)
|
|
41
|
+
|
|
42
|
+
return
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_ListUserContent_
|
|
3
|
+
|
|
4
|
+
Implementation of ListUserContent for MySQL
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from WMCore.Database.DBFormatter import DBFormatter
|
|
9
|
+
|
|
10
|
+
class ListUserContent(DBFormatter):
|
|
11
|
+
|
|
12
|
+
def execute(self, subscription = None, conn = None, transaction = False):
|
|
13
|
+
|
|
14
|
+
sql = """SELECT table_name FROM information_schema.tables
|
|
15
|
+
WHERE table_schema = (SELECT DATABASE())"""
|
|
16
|
+
|
|
17
|
+
result = self.dbi.processData(sql, {}, conn = conn,
|
|
18
|
+
transaction = transaction)
|
|
19
|
+
|
|
20
|
+
return self.formatDict(result)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
_MySQLCore_
|
|
4
|
+
|
|
5
|
+
Handle bind variable parsing for MySQL.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import copy
|
|
9
|
+
|
|
10
|
+
from WMCore.Database.DBCore import DBInterface
|
|
11
|
+
from WMCore.Database.ResultSet import ResultSet
|
|
12
|
+
|
|
13
|
+
def bindVarCompare(a):
|
|
14
|
+
"""
|
|
15
|
+
_bindVarCompare_
|
|
16
|
+
|
|
17
|
+
Bind variables are represented as a tuple with the first element being the
|
|
18
|
+
variable name and the second being it's position in the query. We sort on
|
|
19
|
+
the position in the query.
|
|
20
|
+
"""
|
|
21
|
+
return a[1]
|
|
22
|
+
|
|
23
|
+
def stringLengthCompare(a):
|
|
24
|
+
"""
|
|
25
|
+
_stringLengthCompare_
|
|
26
|
+
|
|
27
|
+
Sort comparison function to sort strings by length.
|
|
28
|
+
Since we want to sort from longest to shortest, this must be reversed when used
|
|
29
|
+
"""
|
|
30
|
+
return len(a)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MySQLInterface(DBInterface):
|
|
34
|
+
def substitute(self, origSQL, origBindsList):
|
|
35
|
+
"""
|
|
36
|
+
_substitute_
|
|
37
|
+
|
|
38
|
+
Transform as set of bind variables from a list of dictionaries to a list
|
|
39
|
+
of tuples:
|
|
40
|
+
|
|
41
|
+
b = [ {'bind1':'value1a', 'bind2': 'value2a'},
|
|
42
|
+
{'bind1':'value1b', 'bind2': 'value2b'} ]
|
|
43
|
+
|
|
44
|
+
Will be transformed into:
|
|
45
|
+
|
|
46
|
+
b = [ ('value1a', 'value2a'), ('value1b', 'value2b')]
|
|
47
|
+
|
|
48
|
+
Don't need to substitute in the binds as executemany does that
|
|
49
|
+
internally. But the sql will also need to be reformatted, such that
|
|
50
|
+
:bind_name becomes %s.
|
|
51
|
+
|
|
52
|
+
See: http://www.devshed.com/c/a/Python/MySQL-Connectivity-With-Python/5/
|
|
53
|
+
"""
|
|
54
|
+
if origBindsList == None:
|
|
55
|
+
return origSQL, None
|
|
56
|
+
|
|
57
|
+
origBindsList = self.makelist(origBindsList)
|
|
58
|
+
origBind = origBindsList[0]
|
|
59
|
+
|
|
60
|
+
bindVarPositionList = []
|
|
61
|
+
updatedSQL = copy.copy(origSQL)
|
|
62
|
+
|
|
63
|
+
# We process bind variables from longest to shortest to avoid a shorter
|
|
64
|
+
# bind variable matching a longer one. For example if we have two bind
|
|
65
|
+
# variables: RELEASE_VERSION and RELEASE_VERSION_ID the former will
|
|
66
|
+
# match against the latter, causing problems. We'll sort the variable
|
|
67
|
+
# names by length to guard against this.
|
|
68
|
+
bindVarNames = list(origBind)
|
|
69
|
+
bindVarNames.sort(key=stringLengthCompare, reverse=True)
|
|
70
|
+
|
|
71
|
+
bindPositions = {}
|
|
72
|
+
for bindName in bindVarNames:
|
|
73
|
+
searchPosition = 0
|
|
74
|
+
|
|
75
|
+
while True:
|
|
76
|
+
bindPosition = origSQL.lower().find(":%s" % bindName.lower(),
|
|
77
|
+
searchPosition)
|
|
78
|
+
if bindPosition == -1:
|
|
79
|
+
break
|
|
80
|
+
|
|
81
|
+
if bindPosition not in bindPositions:
|
|
82
|
+
bindPositions[bindPosition] = 0
|
|
83
|
+
bindVarPositionList.append((bindName, bindPosition))
|
|
84
|
+
searchPosition = bindPosition + 1
|
|
85
|
+
|
|
86
|
+
searchPosition = 0
|
|
87
|
+
while True:
|
|
88
|
+
bindPosition = updatedSQL.lower().find(":%s" % bindName.lower(),
|
|
89
|
+
searchPosition)
|
|
90
|
+
|
|
91
|
+
if bindPosition == -1:
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
left = updatedSQL[0:bindPosition]
|
|
95
|
+
right = updatedSQL[bindPosition + len(bindName) + 1:]
|
|
96
|
+
updatedSQL = left + "%s" + right
|
|
97
|
+
|
|
98
|
+
bindVarPositionList.sort(key=bindVarCompare)
|
|
99
|
+
|
|
100
|
+
mySQLBindVarsList = []
|
|
101
|
+
for origBind in origBindsList:
|
|
102
|
+
mySQLBindVars = []
|
|
103
|
+
for bindVarPosition in bindVarPositionList:
|
|
104
|
+
mySQLBindVars.append(origBind[bindVarPosition[0]])
|
|
105
|
+
|
|
106
|
+
mySQLBindVarsList.append(tuple(mySQLBindVars))
|
|
107
|
+
|
|
108
|
+
return (updatedSQL, mySQLBindVarsList)
|
|
109
|
+
|
|
110
|
+
def executebinds(self, s = None, b = None, connection = None,
|
|
111
|
+
returnCursor = False):
|
|
112
|
+
"""
|
|
113
|
+
_executebinds_
|
|
114
|
+
|
|
115
|
+
Execute a SQL statement that has a single set of bind variables.
|
|
116
|
+
Transform the bind variables into the format that MySQL expects.
|
|
117
|
+
"""
|
|
118
|
+
s, b = self.substitute(s, b)
|
|
119
|
+
return DBInterface.executebinds(self, s, b, connection, returnCursor)
|
|
120
|
+
|
|
121
|
+
def executemanybinds(self, s = None, b = None, connection = None,
|
|
122
|
+
returnCursor = False):
|
|
123
|
+
"""
|
|
124
|
+
_executemanybinds_
|
|
125
|
+
|
|
126
|
+
Execute a SQL statement that has multiple sets of bind variables.
|
|
127
|
+
Transform the bind variables into the format that MySQL expects.
|
|
128
|
+
"""
|
|
129
|
+
newsql, binds = self.substitute(s, b)
|
|
130
|
+
|
|
131
|
+
return DBInterface.executemanybinds(self, newsql, binds, connection,
|
|
132
|
+
returnCursor)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_Destroy_
|
|
3
|
+
|
|
4
|
+
Implementation of Destroy for Oracle
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from WMCore.Database.DBFormatter import DBFormatter
|
|
9
|
+
|
|
10
|
+
class Destroy(DBFormatter):
|
|
11
|
+
|
|
12
|
+
def execute(self, subscription = None, conn = None, transaction = False):
|
|
13
|
+
|
|
14
|
+
sql = """DECLARE
|
|
15
|
+
BEGIN
|
|
16
|
+
|
|
17
|
+
execute immediate 'purge recyclebin';
|
|
18
|
+
|
|
19
|
+
-- Tables
|
|
20
|
+
FOR o IN (SELECT table_name name FROM user_tables) LOOP
|
|
21
|
+
execute immediate 'drop table ' || o.name || ' cascade constraints';
|
|
22
|
+
END LOOP;
|
|
23
|
+
|
|
24
|
+
-- Sequences
|
|
25
|
+
FOR o IN (SELECT sequence_name name FROM user_sequences) LOOP
|
|
26
|
+
execute immediate 'drop sequence ' || o.name;
|
|
27
|
+
END LOOP;
|
|
28
|
+
|
|
29
|
+
-- Triggers
|
|
30
|
+
FOR o IN (SELECT trigger_name name FROM user_triggers) LOOP
|
|
31
|
+
execute immediate 'drop trigger ' || o.name;
|
|
32
|
+
END LOOP;
|
|
33
|
+
|
|
34
|
+
-- Synonyms
|
|
35
|
+
FOR o IN (SELECT synonym_name name FROM user_synonyms) LOOP
|
|
36
|
+
execute immediate 'drop synonym ' || o.name;
|
|
37
|
+
END LOOP;
|
|
38
|
+
|
|
39
|
+
-- Functions
|
|
40
|
+
FOR o IN (SELECT object_name name FROM user_objects WHERE object_type = 'FUNCTION') LOOP
|
|
41
|
+
execute immediate 'drop function ' || o.name;
|
|
42
|
+
END LOOP;
|
|
43
|
+
|
|
44
|
+
-- Procedures
|
|
45
|
+
FOR o IN (SELECT object_name name FROM user_objects WHERE object_type = 'PROCEDURE') LOOP
|
|
46
|
+
execute immediate 'drop procedure ' || o.name;
|
|
47
|
+
END LOOP;
|
|
48
|
+
|
|
49
|
+
execute immediate 'purge recyclebin';
|
|
50
|
+
|
|
51
|
+
END;"""
|
|
52
|
+
|
|
53
|
+
self.dbi.processData(sql, {}, conn = conn,
|
|
54
|
+
transaction = transaction)
|
|
55
|
+
|
|
56
|
+
return
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_ListUserContent_
|
|
3
|
+
|
|
4
|
+
Implementation of ListUserContent for Oracle
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from WMCore.Database.DBFormatter import DBFormatter
|
|
9
|
+
|
|
10
|
+
class ListUserContent(DBFormatter):
|
|
11
|
+
|
|
12
|
+
def execute(self, subscription = None, conn = None, transaction = False):
|
|
13
|
+
|
|
14
|
+
sql = """SELECT object_name FROM user_objects"""
|
|
15
|
+
|
|
16
|
+
result = self.dbi.processData(sql, {}, conn = conn,
|
|
17
|
+
transaction = transaction)
|
|
18
|
+
|
|
19
|
+
return self.formatDict(result)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_ResultSet_
|
|
3
|
+
|
|
4
|
+
A class to read in a SQLAlchemy result proxy and hold the data, such that the
|
|
5
|
+
SQLAlchemy result sets (aka cursors) can be closed. Make this class look as much
|
|
6
|
+
like the SQLAlchemy class to minimise the impact of adding this class.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from builtins import object
|
|
10
|
+
import threading
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ResultSet(object):
|
|
14
|
+
def __init__(self):
|
|
15
|
+
self.data = []
|
|
16
|
+
self.keys = []
|
|
17
|
+
|
|
18
|
+
def close(self):
|
|
19
|
+
return
|
|
20
|
+
|
|
21
|
+
def fetchone(self):
|
|
22
|
+
if len(self.data) > 0:
|
|
23
|
+
return self.data[0]
|
|
24
|
+
else:
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
def fetchall(self):
|
|
28
|
+
return self.data
|
|
29
|
+
|
|
30
|
+
def add(self, resultproxy):
|
|
31
|
+
|
|
32
|
+
myThread = threading.currentThread()
|
|
33
|
+
|
|
34
|
+
if resultproxy.closed:
|
|
35
|
+
return
|
|
36
|
+
elif resultproxy.returns_rows:
|
|
37
|
+
for r in resultproxy:
|
|
38
|
+
if len(self.keys) == 0:
|
|
39
|
+
# do not modernize next line.
|
|
40
|
+
# r is a `sqlalchemy.engine.result.RowProxy`, not a `dict`
|
|
41
|
+
self.keys.extend(r.keys())
|
|
42
|
+
self.data.append(r)
|
|
43
|
+
|
|
44
|
+
return
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
_Transaction_
|
|
4
|
+
|
|
5
|
+
A simple wrapper around DBInterface to make working with transactions simpler
|
|
6
|
+
|
|
7
|
+
On MySQL transactions only work for innodb tables.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
import time
|
|
14
|
+
|
|
15
|
+
from WMCore.DataStructs.WMObject import WMObject
|
|
16
|
+
from WMCore.WMException import WMException
|
|
17
|
+
from WMCore.WMExceptions import WMEXCEPTION
|
|
18
|
+
|
|
19
|
+
class Transaction(WMObject):
|
|
20
|
+
dbi = None
|
|
21
|
+
|
|
22
|
+
def __init__(self, dbinterface = None):
|
|
23
|
+
"""
|
|
24
|
+
Get the connection from the DBInterface and open a new transaction on it
|
|
25
|
+
"""
|
|
26
|
+
self.dbi = dbinterface
|
|
27
|
+
self.conn = None
|
|
28
|
+
self.transaction = None
|
|
29
|
+
|
|
30
|
+
def begin(self):
|
|
31
|
+
if self.conn == None:
|
|
32
|
+
self.conn = self.dbi.connection()
|
|
33
|
+
if self.conn.closed:
|
|
34
|
+
self.conn = self.dbi.connection()
|
|
35
|
+
|
|
36
|
+
if self.transaction == None:
|
|
37
|
+
self.transaction = self.conn.begin()
|
|
38
|
+
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
def processData(self, sql, binds={}):
|
|
42
|
+
"""
|
|
43
|
+
Propagates the request to the proper dbcore backend,
|
|
44
|
+
and performs checks for lost (or closed) connection.
|
|
45
|
+
"""
|
|
46
|
+
result = self.dbi.processData(sql, binds, conn = self.conn,
|
|
47
|
+
transaction = True)
|
|
48
|
+
return result
|
|
49
|
+
|
|
50
|
+
def commit(self):
|
|
51
|
+
"""
|
|
52
|
+
Commit the transaction and return the connection to the pool
|
|
53
|
+
"""
|
|
54
|
+
if not self.transaction == None:
|
|
55
|
+
self.transaction.commit()
|
|
56
|
+
|
|
57
|
+
if not self.conn == None:
|
|
58
|
+
self.conn.close()
|
|
59
|
+
self.conn = None
|
|
60
|
+
self.transaction = None
|
|
61
|
+
|
|
62
|
+
def rollback(self):
|
|
63
|
+
"""
|
|
64
|
+
To be called if there is an exception and you want to roll back the
|
|
65
|
+
transaction and return the connection to the pool
|
|
66
|
+
"""
|
|
67
|
+
if self.transaction:
|
|
68
|
+
self.transaction.rollback()
|
|
69
|
+
|
|
70
|
+
if self.conn:
|
|
71
|
+
self.conn.close()
|
|
72
|
+
|
|
73
|
+
self.conn = None
|
|
74
|
+
self.transaction = None
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
def rollbackForError(self):
|
|
78
|
+
"""
|
|
79
|
+
This is called when handling a major exception. This is because sometimes
|
|
80
|
+
you can end up in a situation where the transaction appears open, but is not. In
|
|
81
|
+
this case, calling a rollback on the transaction will cause an exception, which
|
|
82
|
+
then destroys all logging and shutdown of the actual code.
|
|
83
|
+
|
|
84
|
+
Use only in components.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
self.rollback()
|
|
89
|
+
except:
|
|
90
|
+
pass
|
|
91
|
+
return
|