[copr] master: pep8 run on the subcommand.py file (fabe597)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit fabe59740d83260414a9f2a9b236a15bb05c2be4
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Mon Feb 4 11:47:08 2013 +0100
pep8 run on the subcommand.py file
>---------------------------------------------------------------
copr_cli/subcommands.py | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/copr_cli/subcommands.py b/copr_cli/subcommands.py
index b91ce0c..ce267a2 100644
--- a/copr_cli/subcommands.py
+++ b/copr_cli/subcommands.py
@@ -19,7 +19,7 @@ def set_user():
""" Retrieve the user information from the config file. """
config = ConfigParser.ConfigParser()
config.read(os.path.join(os.path.expanduser('~'), '.config',
- 'copr'))
+ 'copr'))
username = config.get('copr-cli', 'username', None)
token = config.get('copr-cli', 'token', None)
return {'username': username, 'token': token}
@@ -53,7 +53,7 @@ class List(cliff.lister.Lister):
else:
columns = ['output']
values = ['No copr retrieved for user: "{0}"'.format(
- user['username'])]
+ user['username'])]
return (columns, [values])
else:
columns = ['output']
@@ -97,7 +97,7 @@ class AddCopr(Command):
'initial_pkgs': initial_pkgs,
'description': args.description,
'instructions': args.instructions
- }
+ }
for chroot in args.chroots:
data[chroot] = 'y'
11 years, 2 months
[copr] master: Small pep8 clean up on the API code (649a180)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 649a1806036953323fb999ca0b6b8226642565da
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Mon Feb 4 11:45:55 2013 +0100
Small pep8 clean up on the API code
>---------------------------------------------------------------
coprs_frontend/coprs/views/api_ns/api_general.py | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/coprs_frontend/coprs/views/api_ns/api_general.py b/coprs_frontend/coprs/views/api_ns/api_general.py
index 4f9aae5..d12ea7e 100644
--- a/coprs_frontend/coprs/views/api_ns/api_general.py
+++ b/coprs_frontend/coprs/views/api_ns/api_general.py
@@ -24,13 +24,14 @@ def api_home():
return flask.render_template('api.html')
-(a)api_ns.route('/new/', methods = ["GET", "POST"])
+(a)api_ns.route('/new/', methods=["GET", "POST"])
@login_required
def api_new_token():
""" Method use to generate a new API token for the current user.
"""
user = flask.g.user
- user.api_token = helpers.generate_api_token(flask.current_app.config['API_TOKEN_LENGTH'])
+ user.api_token = helpers.generate_api_token(
+ flask.current_app.config['API_TOKEN_LENGTH'])
user.api_token_expiration = datetime.date.today() \
+ datetime.timedelta(days=30)
db.session.add(user)
@@ -64,8 +65,7 @@ def api_new_copr():
selected_chroots=form.selected_chroots,
description=form.description.data,
instructions=form.instructions.data,
- check_for_duplicates=True,
- )
+ check_for_duplicates=True)
infos.append('New copr was successfully created.')
if form.initial_pkgs.data:
@@ -73,10 +73,10 @@ def api_new_copr():
pkgs=" ".join(form.initial_pkgs.data.split()),
copr=copr,
owner=flask.g.user)
- infos.append('Initial packages were successfully submitted '
- 'for building.')
+ infos.append('Initial packages were successfully '
+ 'submitted for building.')
- output = {'output': 'ok', 'message' : '\n'.join(infos)}
+ output = {'output': 'ok', 'message': '\n'.join(infos)}
db.session.commit()
except exceptions.DuplicateException, err:
output = {'output': 'notok', 'error': err}
@@ -129,11 +129,12 @@ def api_coprs_by_owner(username=None):
@api_ns.route('/coprs/detail/<username>/<coprname>/new_build/',
- methods = ["POST"])
+ methods=["POST"])
@login_required
def copr_new_build(username, coprname):
form = forms.BuildForm()
- copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first()
+ copr = coprs_logic.CoprsLogic.get(flask.g.user, username,
+ coprname).first()
httpcode = 200
if not copr:
output = {'output': 'notok', 'error':
11 years, 2 months
[copr] master: Add the API entry to create a new build in a copr repository (ab7152c)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit ab7152cd0c7ecf33720df09a7bf254d7ae66fbe5
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Mon Feb 4 11:44:42 2013 +0100
Add the API entry to create a new build in a copr repository
Although this is looking fine especially since it is so close from the code in
the normal controler, I have not tested it, so I guess it might break, future
patch will come if so :)
>---------------------------------------------------------------
coprs_frontend/coprs/views/api_ns/api_general.py | 35 ++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/coprs_frontend/coprs/views/api_ns/api_general.py b/coprs_frontend/coprs/views/api_ns/api_general.py
index 7c87388..4f9aae5 100644
--- a/coprs_frontend/coprs/views/api_ns/api_general.py
+++ b/coprs_frontend/coprs/views/api_ns/api_general.py
@@ -126,3 +126,38 @@ def api_coprs_by_owner(username=None):
jsonout = flask.jsonify(output)
jsonout.status_code = httpcode
return jsonout
+
+
+(a)api_ns.route('/coprs/detail/<username>/<coprname>/new_build/',
+ methods = ["POST"])
+@login_required
+def copr_new_build(username, coprname):
+ form = forms.BuildForm()
+ copr = coprs_logic.CoprsLogic.get(flask.g.user, username, coprname).first()
+ httpcode = 200
+ if not copr:
+ output = {'output': 'notok', 'error':
+ 'Copr with name {0} does not exist.'.format(coprname)}
+ httpcode = 500
+
+ else:
+ if form.validate_on_submit() and flask.g.user.can_build_in(copr):
+ # we're checking authorization above for now
+ build = builds_logic.BuildsLogic.add(user=flask.g.user,
+ pkgs=form.pkgs.data.replace('\n', ' '), copr=copr)
+
+ if flask.g.user.proven:
+ build.memory_reqs = form.memory_reqs.data
+ build.timeout = form.timeout.data
+
+ db.session.commit()
+
+ output = {'output': 'ok', 'message':
+ 'Build was added to {0}.'.format(coprname)}
+ else:
+ output = {'output': 'notok', 'error': 'Invalid request'}
+ httpcode = 500
+
+ jsonout = flask.jsonify(output)
+ jsonout.status_code = httpcode
+ return jsonout
11 years, 2 months
[copr] master: Make the api return 500 status code when something goes wrong. (802c4e8)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 802c4e8b299faa1768bba8a83d20a8e13fc69752
Author: Pierre-Yves Chibon <pingou(a)pingoured.fr>
Date: Mon Feb 4 11:43:02 2013 +0100
Make the api return 500 status code when something goes wrong.
>---------------------------------------------------------------
coprs_frontend/coprs/views/api_ns/api_general.py | 17 ++++++++++++++---
1 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/coprs_frontend/coprs/views/api_ns/api_general.py b/coprs_frontend/coprs/views/api_ns/api_general.py
index 735da98..7c87388 100644
--- a/coprs_frontend/coprs/views/api_ns/api_general.py
+++ b/coprs_frontend/coprs/views/api_ns/api_general.py
@@ -53,6 +53,7 @@ def api_new_copr():
"""
form = forms.CoprFormFactory.create_form_cls()(csrf_enabled=False)
+ httpcode = 200
if form.validate_on_submit():
infos = []
try:
@@ -79,14 +80,20 @@ def api_new_copr():
db.session.commit()
except exceptions.DuplicateException, err:
output = {'output': 'notok', 'error': err}
+ httpcode = 500
db.session.rollback()
else:
- errormsg = "\n".join(form.errors['name'])
+ errormsg = ''
+ if form.errors:
+ errormsg = "\n".join(form.errors['name'])
errormsg = errormsg.replace('"', "'")
output = {'output': 'notok', 'error': errormsg}
+ httpcode = 500
- return flask.jsonify(output)
+ jsonout = flask.jsonify(output)
+ jsonout.status_code = httpcode
+ return jsonout
@api_ns.route('/owned/')
@@ -101,6 +108,7 @@ def api_coprs_by_owner(username=None):
"""
username = flask.request.args.get('username', None) or username
+ httpcode = 200
if 'username':
query = coprs_logic.CoprsLogic.get_multiple(flask.g.user,
user_relation='owned', username=username)
@@ -113,5 +121,8 @@ def api_coprs_by_owner(username=None):
'instructions': repo.instructions})
else:
output = {'output': 'notok', 'error': 'Invalid request'}
+ httpcode = 500
- return flask.jsonify(output)
+ jsonout = flask.jsonify(output)
+ jsonout.status_code = httpcode
+ return jsonout
11 years, 2 months
[PATCH] Change from using parameters to HTTP Basic access authentication
by Pierre-Yves Chibon
This change prevent the username/API token from being displayed in the server logs
and makes the API actually working in a more standardized maner, using the http
headers as they are expected to be.
---
The interesting part about conference is that you learn cool stuff :)
Here is a change which I think makes quite sense and prevents to display user's
personnal information in the server logs.
copr_cli/subcommands.py | 8 ++++++--
coprs_frontend/coprs/views/misc.py | 10 ++++++++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/copr_cli/subcommands.py b/copr_cli/subcommands.py
index cb112f2..7e63f52 100644
--- a/copr_cli/subcommands.py
+++ b/copr_cli/subcommands.py
@@ -101,7 +101,9 @@ class AddCopr(Command):
for chroot in args.chroots:
data[chroot] = 'y'
- req = requests.post(URL, params=user, data=data)
+ req = requests.post(URL,
+ auth=(user['username'], user['token']),
+ data=data)
output = json.loads(req.text)
if output['output'] == 'ok':
print output['message']
@@ -136,7 +138,9 @@ class Build(Command):
'timeout': args.timeout
}
- req = requests.post(URL, params=user, data=data)
+ req = requests.post(URL,
+ auth=(user['username'], user['token']),
+ data=data)
output = json.loads(req.text)
if req.status_code == 200:
print 'Something went wrong:\n {0}'.format(output['error'])
diff --git a/coprs_frontend/coprs/views/misc.py b/coprs_frontend/coprs/views/misc.py
index 48a1f3a..d7eb73e 100644
--- a/coprs_frontend/coprs/views/misc.py
+++ b/coprs_frontend/coprs/views/misc.py
@@ -1,3 +1,4 @@
+import base64
import datetime
import functools
@@ -79,8 +80,13 @@ def logout():
def login_required(f):
@functools.wraps(f)
def decorated_function(*args, **kwargs):
- token = flask.request.args.get('token')
- username = flask.request.args.get('username')
+ token = None
+ username = None
+ if 'Authorization' in flask.request.headers:
+ base64string = flask.request.headers['Authorization']
+ base64string = base64string.split()[1].strip()
+ userstring = base64.b64decode(base64string)
+ (username, token) = userstring.split(':')
token_auth = False
if token and username:
user = models.User.query.filter(
--
1.8.1
11 years, 2 months
[copr] master: Merge branch 'master' of ssh://git.fedorahosted.org/git/copr (da8c76d)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit da8c76ddaffbb3f7f39811d4454b80a5b3dbab63
Merge: 3693b5d ca05d75
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Fri Feb 1 14:21:57 2013 +0100
Merge branch 'master' of ssh://git.fedorahosted.org/git/copr
>---------------------------------------------------------------
backend/dispatcher.py | 6 +++---
backend/mockremote.py | 11 ++++++-----
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/backend/dispatcher.py b/backend/dispatcher.py
index 5fa6aa0..610b619 100644
--- a/backend/dispatcher.py
+++ b/backend/dispatcher.py
@@ -174,8 +174,6 @@ class Worker(multiprocessing.Process):
jobdata.destdir = self.opts.destdir + '/' + build['copr']['owner']['name'] + '/' + build['copr']['name'] + '/'
jobdata.build_id = build['id']
jobdata.results = self.opts.results_baseurl + '/' + build['copr']['owner']['name'] + '/' + build['copr']['name'] + '/'
- # add the results dir to the jobdata.repos
- jobdata.repos.append(jobdata.results)
jobdata.copr_id = build['copr']['id']
jobdata.user_id = build['user_id']
jobdata.user_name = build['copr']['owner']['name']
@@ -296,10 +294,12 @@ class Worker(multiprocessing.Process):
self.callback.log('Starting build: id=%r builder=%r timeout=%r destdir=%r chroot=%r repos=%r' % (job.build_id,ip, job.timeout, job.destdir, chroot, str(job.repos)))
self.callback.log('building pkgs: %s' % ' '.join(job.pkgs))
try:
+ chroot_repos = list(job.repos)
+ chroot_repos.append(job.results + '/' + chroot)
chrootlogfile = chroot_destdir + '/build-%s.log' % job.build_id
mr = mockremote.MockRemote(builder=ip, timeout=job.timeout,
destdir=job.destdir, chroot=chroot, cont=True, recurse=True,
- repos=job.repos,
+ repos=chroot_repos,
callback=mockremote.CliLogCallBack(quiet=True,logfn=chrootlogfile))
mr.build_pkgs(job.pkgs)
except mockremote.MockRemoteError, e:
diff --git a/backend/mockremote.py b/backend/mockremote.py
index 2e1e19f..308c21a 100755
--- a/backend/mockremote.py
+++ b/backend/mockremote.py
@@ -511,11 +511,12 @@ class MockRemote(object):
self.callback.log("Success building %s" % os.path.basename(pkg))
built_pkgs.append(pkg)
# createrepo with the new pkgs
- rc, out, err = createrepo(self.destdir)
- if err.strip():
- self.callback.error("Error making local repo: %s" % self.destdir)
- self.callback.error("%s" % err)
- #FIXME - maybe clean up .repodata and .olddata here?
+ for d in [self.destdir, self.destdir + '/' + self.chroot]:
+ rc, out, err = createrepo(d)
+ if err.strip():
+ self.callback.error("Error making local repo: %s" % d)
+ self.callback.error("%s" % err)
+ #FIXME - maybe clean up .repodata and .olddata here?
if self.failed:
if len(self.failed) != len(to_be_built):
11 years, 2 months
[copr] master: Fix the query not to fail on arguments with whitespace (3693b5d)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 3693b5d38ca988f94c19315c7544f297d90d38a1
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Fri Feb 1 14:21:11 2013 +0100
Fix the query not to fail on arguments with whitespace
>---------------------------------------------------------------
coprs_frontend/coprs/sql_custom.py | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/coprs_frontend/coprs/sql_custom.py b/coprs_frontend/coprs/sql_custom.py
index 056b3f3..8a4aa62 100644
--- a/coprs_frontend/coprs/sql_custom.py
+++ b/coprs_frontend/coprs/sql_custom.py
@@ -1,3 +1,4 @@
+from sqlalchemy import func
from sqlalchemy import types
from sqlalchemy.ext import compiler
@@ -19,6 +20,6 @@ def compile_tsvector(element, compiler, **kw):
class FullTextQuery(db.Query):
def fulltext(self, column, search_string):
if db.engine.dialect.name == 'postgresql':
- return self.filter(column.match(search_string))
+ return self.filter(column.op('@@@')(func.plainto_tsquery(search_string)))
else:
return self.filter(column.like('%{0}%'.format(search_string)))
11 years, 2 months
[copr] master: Enable searching from the displayed field (9eef762)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 9eef762bf0e9c5aa28c564fdce7ebb122610a90c
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Fri Feb 1 14:05:18 2013 +0100
Enable searching from the displayed field
>---------------------------------------------------------------
coprs_frontend/coprs/static/copr.css | 12 ++++++++++++
coprs_frontend/coprs/templates/layout.html | 5 ++++-
2 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/coprs_frontend/coprs/static/copr.css b/coprs_frontend/coprs/static/copr.css
index c5c6f3b..c147a30 100644
--- a/coprs_frontend/coprs/static/copr.css
+++ b/coprs_frontend/coprs/static/copr.css
@@ -58,15 +58,18 @@ div.login, div.login a {
font-weight: bold;
text-decoration: none;
line-height: 250%;
+ text-align: right;
position: relative;
float: right;
+ margin-left: 0.3em;
}
div.login .text {
font-weight: normal;
}
+
div.page, div.menu-inner {
width: 780px;
margin-left: auto;
@@ -226,6 +229,15 @@ input.rounded {
-webkit-border-radius: 10px;
}
+input.fulltext-submit {
+ color: white;
+ font-weight: bold;
+ background-color: #3d69a8;
+ border-radius: 10px;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+}
+
p.form-error {
color: red;
}
diff --git a/coprs_frontend/coprs/templates/layout.html b/coprs_frontend/coprs/templates/layout.html
index 458b731..6312d49 100644
--- a/coprs_frontend/coprs/templates/layout.html
+++ b/coprs_frontend/coprs/templates/layout.html
@@ -16,7 +16,10 @@
{% else %}
<div><a href="{{ url_for('misc.login') }}">log in</a></div>
{% endif %}
- <input class="rounded" type="text" name="search_text">
+ <form method="get" action="{{ url_for('coprs_ns.coprs_fulltext_search') }}">
+ <input class="rounded" type="text" name="fulltext">
+ <input class="fulltext-submit" type="submit" value="search">
+ </form>
</div>
</div>
</div>
11 years, 2 months
[copr] master: Enable fulltext-like search on sqlite, too (92e74af)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 92e74af303736c3857f7044f1f8f36456d155807
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Fri Feb 1 13:44:54 2013 +0100
Enable fulltext-like search on sqlite, too
- Introduce a new Query subclass that can do 'fulltext' in both DBs
>---------------------------------------------------------------
.../versions/3a035889852c_add_copr_fulltext.py | 25 +++++++++++--
coprs_frontend/coprs/logic/coprs_logic.py | 2 +-
coprs_frontend/coprs/models.py | 38 ++++++++++++++++++--
coprs_frontend/coprs/sql_custom.py | 24 ++++++++++++
coprs_frontend/coprs/sql_types.py | 10 -----
5 files changed, 82 insertions(+), 17 deletions(-)
diff --git a/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py b/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py
index c7292ff..8fa6a5e 100644
--- a/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py
+++ b/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py
@@ -13,11 +13,11 @@ down_revision = '3c3cce7a5fe0'
from alembic import op
import sqlalchemy as sa
-from coprs import sql_types
+from coprs import sql_custom
def upgrade():
### commands auto generated by Alembic - please adjust! ###
- op.add_column('copr', sa.Column('copr_ts_col', sql_types.Tsvector(), nullable=True))
+ op.add_column('copr', sa.Column('copr_ts_col', sql_custom.Tsvector(), nullable=True))
op.create_index('copr_ts_idx', 'copr', ['copr_ts_col'], postgresql_using='gin')
session = sa.orm.sessionmaker(bind=op.get_bind())()
@@ -32,7 +32,26 @@ def upgrade():
FOR EACH ROW EXECUTE PROCEDURE \
tsvector_update_trigger(copr_ts_col, 'pg_catalog.english', name, description, instructions);")
elif op.get_bind().dialect.name == 'sqlite':
- pass #TODO
+ op.execute("UPDATE copr \
+ SET copr_ts_col = coalesce(name, '') || ' ' || \
+ coalesce(description, '') || ' ' || coalesce(instructions, '')")
+ # two triggers for sqlite...
+ op.execute("CREATE TRIGGER copr_ts_update \
+ AFTER UPDATE OF name, description, instructions \
+ ON copr \
+ FOR EACH ROW \
+ BEGIN \
+ UPDATE copr SET copr_ts_col = coalesce(name, '') || ' ' || \
+ coalesce(description, '') || ' ' || coalesce(instructions, ''); \
+ END;")
+ op.execute("CREATE TRIGGER copr_ts_insert \
+ AFTER INSERT \
+ ON copr \
+ FOR EACH ROW \
+ BEGIN \
+ UPDATE copr SET copr_ts_col = coalesce(name, '') || ' ' || \
+ coalesce(description, '') || ' ' || coalesce(instructions, ''); \
+ END;")
### end Alembic commands ###
diff --git a/coprs_frontend/coprs/logic/coprs_logic.py b/coprs_frontend/coprs/logic/coprs_logic.py
index ba0266a..36aa51f 100644
--- a/coprs_frontend/coprs/logic/coprs_logic.py
+++ b/coprs_frontend/coprs/logic/coprs_logic.py
@@ -52,7 +52,7 @@ class CoprsLogic(object):
@classmethod
def get_multiple_fulltext(cls, user, search_string):
- query = models.Copr.query.filter(models.Copr.copr_ts_col.match(search_string))
+ query = models.Copr.query.fulltext(models.Copr.copr_ts_col, search_string)
return query
@classmethod
diff --git a/coprs_frontend/coprs/models.py b/coprs_frontend/coprs/models.py
index eef1082..e6b2fb3 100644
--- a/coprs_frontend/coprs/models.py
+++ b/coprs_frontend/coprs/models.py
@@ -6,7 +6,7 @@ from sqlalchemy.ext.associationproxy import association_proxy
from coprs import constants
from coprs import db
from coprs import helpers
-from coprs import sql_types
+from coprs import sql_custom
class Serializer(object):
def to_dict(self, options = {}):
@@ -108,6 +108,8 @@ class User(db.Model, Serializer):
class Copr(db.Model, Serializer):
+ query_class = sql_custom.FullTextQuery
+
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(100), nullable = False)
repos = db.Column(db.Text)
@@ -117,7 +119,7 @@ class Copr(db.Model, Serializer):
# duplicate information, but speeds up a lot and makes queries simpler
build_count = db.Column(db.Integer, default = 0)
# fulltext
- copr_ts_col = db.Column(sql_types.Tsvector)
+ copr_ts_col = db.Column(sql_custom.Tsvector)
copr_ts_idx = db.Index('copr_ts_col', postgresql_using='gin')
# relations
@@ -137,7 +139,8 @@ class Copr(db.Model, Serializer):
def instructions_or_not_filled(self):
return self.instructions or 'Instructions not filled in by author.'
-# fulltext search trigger for copr
+### fulltext search trigger for copr
+# postgres
sqlalchemy.event.listen(
Copr.__table__,
'after_create',
@@ -148,6 +151,35 @@ sqlalchemy.event.listen(
execute_if(dialect='postgresql')
)
+# sqlite
+sqlalchemy.event.listen(
+ Copr.__table__,
+ 'after_create',
+ sqlalchemy.schema.DDL("CREATE TRIGGER copr_ts_update \
+ AFTER UPDATE OF name, description, instructions \
+ ON copr \
+ FOR EACH ROW \
+ BEGIN \
+ UPDATE copr SET copr_ts_col = coalesce(name, '') || ' ' || \
+ coalesce(description, '') || ' ' || coalesce(instructions, ''); \
+ END;").\
+ execute_if(dialect='sqlite')
+)
+
+sqlalchemy.event.listen(
+ Copr.__table__,
+ 'after_create',
+ sqlalchemy.schema.DDL("CREATE TRIGGER copr_ts_insert \
+ AFTER INSERT \
+ ON copr \
+ FOR EACH ROW \
+ BEGIN \
+ UPDATE copr SET copr_ts_col = coalesce(name, '') || ' ' || \
+ coalesce(description, '') || ' ' || coalesce(instructions, ''); \
+ END;").\
+ execute_if(dialect='sqlite')
+)
+
class CoprPermission(db.Model, Serializer):
# 0 = nothing, 1 = asked for, 2 = approved
# not using enum, as that translates to varchar on some DBs
diff --git a/coprs_frontend/coprs/sql_custom.py b/coprs_frontend/coprs/sql_custom.py
new file mode 100644
index 0000000..056b3f3
--- /dev/null
+++ b/coprs_frontend/coprs/sql_custom.py
@@ -0,0 +1,24 @@
+from sqlalchemy import types
+from sqlalchemy.ext import compiler
+
+from coprs import db
+
+class Tsvector(types.UnicodeText):
+ # TODO: define the custom operator to perform fulltext searches ?
+ pass
+
+(a)compiler.compiles(Tsvector, 'postgresql')
+def compile_tsvector(element, compiler, **kw):
+ return 'tsvector'
+
+(a)compiler.compiles(Tsvector, 'sqlite')
+def compile_tsvector(element, compiler, **kw):
+ return 'text'
+
+
+class FullTextQuery(db.Query):
+ def fulltext(self, column, search_string):
+ if db.engine.dialect.name == 'postgresql':
+ return self.filter(column.match(search_string))
+ else:
+ return self.filter(column.like('%{0}%'.format(search_string)))
diff --git a/coprs_frontend/coprs/sql_types.py b/coprs_frontend/coprs/sql_types.py
deleted file mode 100644
index ea6376d..0000000
--- a/coprs_frontend/coprs/sql_types.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from sqlalchemy import types
-from sqlalchemy.ext import compiler
-
-class Tsvector(types.UnicodeText):
- # TODO: define the custom operator to perform fulltext searches ?
- pass
-
-(a)compiler.compiles(Tsvector, 'postgresql')
-def compile_tsvector(element, compiler, **kw):
- return 'tsvector'
11 years, 2 months
[copr] master: Only update existing coprs using ts_vector for postgresql (9f5ad77)
by bkabrda@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
>---------------------------------------------------------------
commit 9f5ad77960f00a5cbbc1170e4266d90288dbeafc
Author: Bohuslav Kabrda <bkabrda(a)redhat.com>
Date: Fri Feb 1 12:30:18 2013 +0100
Only update existing coprs using ts_vector for postgresql
>---------------------------------------------------------------
.../versions/3a035889852c_add_copr_fulltext.py | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py b/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py
index ac0c71a..c7292ff 100644
--- a/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py
+++ b/coprs_frontend/alembic/versions/3a035889852c_add_copr_fulltext.py
@@ -22,10 +22,10 @@ def upgrade():
session = sa.orm.sessionmaker(bind=op.get_bind())()
metadata = sa.MetaData()
- op.execute("UPDATE copr \
- SET copr_ts_col = to_tsvector('pg_catalog.english', coalesce(name, '') || ' ' || \
- coalesce(description, '') || ' ' || coalesce(instructions, ''))")
if op.get_bind().dialect.name == 'postgresql':
+ op.execute("UPDATE copr \
+ SET copr_ts_col = to_tsvector('pg_catalog.english', coalesce(name, '') || ' ' || \
+ coalesce(description, '') || ' ' || coalesce(instructions, ''))")
# no need to coalesce here, the trigger doesn't need it
op.execute("CREATE TRIGGER copr_ts_update BEFORE INSERT OR UPDATE \
ON copr \
11 years, 2 months