Groovy: How to access to the values already set in DataSource - groovy

I have a groovy application which is using an Oracle DB as DataSource.
In DataSource.groovy I've set:
dataSource {
pooled = true
driverClassName = "oracle.jdbc.driver.OracleDriver"
username = "scott"
password = "tiger
//loggingSql = true
}
For some performance reasons at some points I am accesing the DB using sql in the following way:
def sql = Sql.newInstance("jdbc:oracle:thin:#localhost:1521:XE", "scott", "tiger", "oracle.jdbc.driver.OracleDriver")
That is, username and password are hardwired twice in the application.
My question is if it possible to address in my application to the attributes username and password already set in the DataSource.groovy.
Thanks in advance,
Luis

The solution is to add some imports
import javax.sql.DataSource
import groovy.sql.Sql
import org.codehaus.groovy.grails.commons.ConfigurationHolder
and the following code:
def _url = ConfigurationHolder.config.dataSource.url
def _username = ConfigurationHolder.config.dataSource.username
def _password = ConfigurationHolder.config.dataSource.password
def _driver = ConfigurationHolder.config.dataSource.driverClassName
def sql = Sql.newInstance(_url, _username, _password, _driver)
def query = "<your SQL query>"
sql.eachRow(query){
println "ID: " + it.id // Whatever you need
}

You may create Sql class by datasource, for example
def sql = new Sql(myDataSource)
where myDataSource - object of class DataSource (you can get your DS declared in DataSource.groovy)

Can't you just do the following? (assuming that dataSource is a variable in scope)
def sql = Sql.newInstance("jdbc:oracle:thin:#localhost:1521:XE", dataSource.username, dataSource.password, dataSource.driverClassName)

Related

Scriptrunner Create issue and assign to existing epic

While creating a new issue using scriptrunner, I would like to assign it an existing epic. it seems the issue.setCustomFieldValue(epicLinkCustomField) is not working. any help would be greatly appreciated. everything else works fine, im able to set name, summary, tittle, prio, description, assign reporter, projectkey, issue context, and issue type.
The code I have is below.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.context.IssueContext
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.fields.config.manager.PrioritySchemeManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.MutableIssue
import java.text.SimpleDateFormat
def date = new Date()
def sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
// the project key under which the issue will get created
final projectKey = 'SEC'
// stores status
final statusKey = 'AN QUE'
// the issue type for the new issue
final issueTypeName = 'Task'
// user with that user key will be the reporter of the issue
final reporterKey = 'MV108788'
// the summary of the new issue
final summary = 'test' + date
// the priority of the new issue
final priorityName = 'Low'
// sets description
final description = 'this is a decription'
//epic
final epicIssueKey = 'test'
def issueService = ComponentAccessor.issueService
def constantsManager = ComponentAccessor.constantsManager
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def prioritySchemeManager = ComponentAccessor.getComponent(PrioritySchemeManager)
//finds epic
def epicLinkCustomField = ComponentAccessor.customFieldManager.getCustomFieldObjects().findByName(epicIssueKey)
//finds status key
def status = ComponentAccessor.constantsManager.getStatusByName(statusKey)
//finds project key
def project = ComponentAccessor.projectManager.getProjectObjByKey(projectKey)
assert project : "Could not find project with key $projectKey"
//finds issue types
def issueType = constantsManager.allIssueTypeObjects.findByName(issueTypeName)
assert issueType : "Could not find issue type with name $issueTypeName"
// if we cannot find user with the specified key or this is null, then set as a reporter the logged in user
def reporter = ComponentAccessor.userManager.getUserByKey(reporterKey) ?: loggedInUser
// if we cannot find the priority with the given name or if this is null, then set the default priority
def issueContext = new IssueContextImpl(project, issueType) as IssueContext
// finds priority
def priorityId = constantsManager.priorities.findByName(priorityName)?.id ?: prioritySchemeManager.getDefaultOption(issueContext)
//sets all issue settings
def issueInputParameters = issueService.newIssueInputParameters().with {
setStatusId(statusId) //not working
setProjectId(project.id)
setDescription(description)
setIssueTypeId(issueType.id)
setReporterId(reporter.name)
setSummary(summary)
setPriorityId(priorityId)
issue.setCustomFieldValue(epicLinkCustomField)
}
def validationResult = issueService.validateCreate(loggedInUser, issueInputParameters)
assert validationResult.valid : validationResult.errorCollection
def result = issueService.create(loggedInUser, validationResult)
assert result.valid : result.errorCollection

FastAPI - Set response_model_exclude when calling API

In FastAPI I have a situation similar to this:
models.py
class MachineGroups(Base):
__tablename__ = 'MachineGroups'
MachineGroupsId = Column(NVARCHAR(25), primary_key=True)
Description = Column(NVARCHAR(255))
class Machines(Base):
__tablename__ = 'Machines'
MachinesId = Column(NVARCHAR(50), primary_key=True)
Description = Column(NVARCHAR(255))
MachineGroupsId = Column(NVARCHAR(25), ForeignKey("MachineGroups.MachineGroupsId", ondelete="SET NULL"), nullable=True)
group = relationship("MachineGroups")
schemas.py
class MachineGroups(BaseModel):
MachineGroupsId: str
Description: str
class Config:
orm_mode = True
class Machines(BaseModel):
MachinesId: str
Description: str
MachineGroupsId: str = None
group: Optional[MachineGroups] = None
class Config:
orm_mode = True
In the controller I have a function create like this:
controller.py
#app.get(
"/machines",
response_model=List[machine_schemas.Machines],
response_model_exclude={'group'}
)
def get_machines(db: Session = Depends(get_db)):
return db.query(machine_models.Machines).all()
I would like to be able to set the response_model_exclude field value in the decorator directly from the API call. In practice I would like to have a query parameter on the function that allows me allows me to get the foreign key information or not.
To avoid having this situation:
#app.get(
"/machines",
response_model=List[machine_schemas.Machines],
response_model_exclude={'group'}
)
def get_machines(db: Session = Depends(get_db)):
return db.query(machine_models.Machines).all()
#app.get(
"/machines/all",
response_model=List[machine_schemas.Machines],
)
def get_machines_all(db: Session = Depends(get_db)):
return db.query(machine_models.Machines).all()
Is it possible to achieve this?
Thank you.
I solved the problem by creating a custom JSONResponse and using the jsonable_encoder function to exclude the foreign key fields.
#app.get(
"/machines/all",
response_model=List[machine_schemas.Machines],
)
def get_machines_all(get_foreign_keys: bool = True, db: Session = Depends(get_db)):
machines = db.query(machine_models.Machines).all()
if get_foreign_keys:
return machines
else:
return JSONResponse(jsonable_encoder(machines, exclude={'group'}))

How to connect to flask-sqlalchemy database from inside a RQ job

Using flask-sqlalchemy, how is it possible to connect to a database from within a redis task?
The database connection is created in create_app with:
db = SQLAlchemy(app)
I call a job from a route:
#app.route("/record_occurrences")
def query_library():
job = queue.enqueue(ApiQueryService(word), word)
Then inside the redis task, I want to make an update to the database
class ApiQueryService(object):
def __init__(self,word):
resp = call_api()
db.session.query(Model).filter_by(id=word.id).update({"count":resp[1]})
I can't find a way to access the db. I've tried importing it with from app import db. I tried storing it in g. I tried reinstantiating it with SQLAlchemy(app), and several other things, but none of these work. When I was using sqlite, all of this worked, and I could easily connect to the db from any module with a get_db method that simply called sqlite3.connect(). Is there some simple way to access it with SQLAlchemy that's similar to that?
This can be solved using the App Factory pattern, as mentioned by #vulpxn.
Let's assume we have our configuration class somewhere like this:
class Config(object):
DEBUG = False
TESTING = False
DEVELOPMENT = False
API_PAGINATION = 10
PROPAGATE_EXCEPTIONS = True # needed due to Flask-Restful not passing them up
SQLALCHEMY_TRACK_MODIFICATIONS = False # ref: https://stackoverflow.com/questions/33738467/how-do-i-know-if-i-can-disable-sqlalchemy-track-modifications/33790196#33790196
class ProductionConfig(Config):
CSRF_COOKIE_SAMESITE = 'Strict'
SESSION_PROTECTION = "strong"
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Strict'
SECRET_KEY = "super-secret"
INVITES_SECRET = "super-secret"
PASSWORD_RESET_SECRET = "super-secret"
PUBLIC_VALIDATION_SECRET = "super-secret"
FRONTEND_SERVER_URL = "https://127.0.0.1:4999"
SQLALCHEMY_DATABASE_URI = "sqlite:///%s" % os.path.join(os.path.abspath(os.path.dirname(__file__)), "..",
"people.db")
We create our app factory:
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from development.config import DevelopmentConfig
from rq import Queue
from email_queue.worker import conn
db = SQLAlchemy()
q = Queue(connection=conn)
def init_app(config=ProductionConfig):
# app creation
app = Flask(__name__)
app.config.from_object(config)
# plugin initialization
db.init_app(app)
with app.app_context():
# adding blueprints
from .blueprints import api
app.register_blueprint(api, url_prefix='/api/v1')
return app
We will now be able to start our app using the app factory:
app = centrifuga4.init_app()
if __name__ == "__main__":
with app.app_context():
app.run()
But we will also be able to (in our Redis job), do the following:
def my_job():
app = init_app()
with app.app_context():
return something_using_sqlalchemy()

How to define database 'driver' using Groovy sql module

I am trying to connect to an Oracle Sql Developer DB using Groovys sql class, which requires 4 pieces of information: (db url, username, password, db driver) I have all information needed except the driver. I have tried using oracle.jdbc.driver.OracleDrive and have set my GROOVY_HOME as : Variable: %GROOVY_HOME%\lib Value: C:\Oracle_SQL_DEVELOPER\sqldeveloper
I am receiving the following error :
Caused by: java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
I have referenced a few answers here on StackOverflow but haven't had any luck setting up a connection. Here are the links I've read and tried:
Unable to connect to oracle database from groovy
SQLException: No suitable Driver Found for jdbc:oracle:thin:#//localhost:1521/orcl
I have also looked and researched the Groovy documentation but it is not clear on how to define the driver: https://groovy-lang.org/databases.html#_connecting_with_a_datasource
Any help would be much appreciated. Here is the code for reference:
import groovy.sql.Sql
class EstablishConnection {
def static url = 'url'
def static user = 'user'
def static password = 'pass'
def static driver = 'oracle.jdbc.driver.OracleDriver'
def static sql = Sql.newInstance(url, user, password, driver)
}
EstablishConnection.sql.eachRow('select * from ACCOUNT where CONSTI_ID = \'12345678\';'){
row ->
def a = row[0]
}

error: groovy.lang.MissingPropertyException No such property: sql for class: Script9

I need to compare two values in data format
import groovy.sql.*
com.eviware.soapui.support.GroovyUtils.registerJdbcDriver( "oracle.jdbc.driver.OracleDriver" )
def messageId1 = context.expand( '${#Project#Id1}' )
def messageId2 = context.expand( '${#Project#Id2}' )
def first = sql.firstRow("select timestamp from table where Messageid = '"+messageId1+"'")
def second = sql.firstRow("select timestamp from table where Messageid = '"+messageId2+"'")
assert first < second, 'OK'
I get following error:
error: groovy.lang.MissingPropertyException No such property: sql for class: Script9
I had the same issue and the mistake that I made is, I didn't create a SQL Instance...So this would help you
def DBurl = '<Your database URL>'
def DBuser = '<Database user name>'
def DBpassword = '<Database Password>'
def DBdriver = '< Your database driver>'
def sql = Sql.newInstance(DBurl, DBuser, DBpassword, DBdriver)

Resources