Lawful Basis: Consent

Consent means that individuals are offered real choice and control over their own personal data.
Consent is a clear affirmative act establishing a freely given, specific, informed and unambiguous indication of the people data agreement to the processing of the personal data.

Asking for Consent

Consent requires a very clear and specific statement with an explicit opt-in, so pre-checked boxes or other default pre-selected consent methods are illegal.
If the consent includes different purposes or several processing types a separate consent must be asked for each of them.

The statement of why the data is being gathered and what will be done with it must be clearly stated and based on the most appropriate lawful basis for processing.
Therefore, when an individual gives consent, it must be clear for all parts involved what is the consent about.

Public authorities and employers should take extra care to show that consent is freely given, and should avoid over-reliance on consent.

Children merit specific protection with regard to their personal data. Special attention must be give for purposes such as marketing, user profiles and the collection of personal data when using services offered directly to a child.
Ocasional exceptions exist in the context of preventive or counselling services offered directly to a child.
See Article 8 for details.

Auditing Consent

Because consent is auditable, it is necessary to keep records of when, how and what has the individual has given consent to.

Managing Consent

Individuals can manage the consent, including withdraw the consent at any given time.
It should be easy for people to withdraw the consent and that should be stated when asking for consent.

Goal

Genuine consent should put individuals in charge, building customer trust and engagement which will enhance your reputation.

Need Help with GDPR?

Get in touch with us if you need help on the subject.

Django wysiwyg Editor

Many Django projects require a wysiwyg editor. To cover this, there is an application for making Django textareas rich text editors: django-wysiwyg.

To use it, start by installing it through

pip install django-wysiwyg

.
Then, on your HTML template, include application:

{% load wysiwyg %}

As an example, take the following form:

#
# Event Edit From
#
class EventsDataForm(forms.Form):
    """
        Event data form
    """

    min_description_chars = 10
    max_description_chars = 2000

    ltitle = ugettext("Title")    
    ltitle_help = ugettext("The title of the event.")
    ltitle_required = ugettext("Please enter the title.")
   
    ldescription = ugettext("Description")
    ldescription_help = ugettext("Enter the event description.")
    ldescription_required = ugettext("Please describe the event.")    
    ldescription_min_length = ugettext('The minimum length is %s characters.')%(min_description_chars)
    ldescription_max_length = ugettext('The maximum length is %s characters of plain text (less characters for formated text)')%(max_description_chars)

    id = forms.IntegerField(widget=forms.HiddenInput(), required=False)
    title = forms.CharField(max_length=60, required=True, label=ltitle, help_text=ltitle_help, error_messages={'required': ltitle_required})
    long_description = forms.CharField(widget=forms.Textarea(attrs={'cols': 50, 'rows': 5}), min_length=min_description_chars, max_length=max_description_chars, required=True, label=ldescription, help_text=ldescription_help)

The “long_description” field is the field that will be wysiwyg editor.

Then, on your form, setup up the wysiwyg, draw the form and link it to your form field. Here’s an example:

{% block content %}
<form enctype="multipart/form-data" action='.' method='post'>
  {% csrf_token %}
  <table>  
    {% wysiwyg_setup %}
    {{ form.as_table }}
    {% wysiwyg_editor "id_long_description" %}
  </table>
  <input type="submit" value="Save" />
</form>
{% endblock %}

The

{% wysiwyg_setup %}

sets up the application.
The

{{ form.as_table }}

draws the form.
The

{% wysiwyg_editor "id_long_description" %}

links the form field “long_description” to the wysiwyg via the identifier.
Take special attention to the identifier, it’s the name of the field in the forms and it should be preceded by “id_”.

That is enough to make the “long_description” field a wysiwyg editor.

If one requires customization, for instance change the width or the toolbar buttons, one can do this by customizing the

django_wysiwyg_editor_config

variable. See the documentation for extra information about how to customize the component.
The trick is to perform the customization on the bottom of the page, just before closing the

</body>

tag.
First, load the “django_wysiwyg_editor_config” block, then load its code and, finally, apply your customization. Here’s and example:

<script>
{% block django_wysiwyg_editor_config %}
{{ block.super }}
django_wysiwyg_editor_config.width = "450px";
django_wysiwyg_editor_config.height = "200px";
{% endblock %}
</script>

And that’s it.

DB2 copy schema with tables

Sometimes one needs to automate a DB2 schema copy, clone or simple backup.
If the requirements are just to create a new schema and copy the tables and their content into the new schema, it seems to be a simple task.
But this simple task soon reveals to be a hard one, which can be achieved with a quite simple script.

The first step is to created a specific schema for this automation task, e. g. COPY_DATABASE_SCHEMA, so all the procedures will be created there.

The procedure that copies the table content is easy to code. Just declare a cursor that selects the source table data and load it into the target table.
Here is the procedure that performs the copy of the table content:

/**
* Copies, with replacement, the content from the source table
* into the target table.
* It will not check for success, i.e. no loading validation
* will be performed.
*
* @sourceTable: the full qualified source table name
* @targetTable: the full qualified target table name
*/

CREATE PROCEDURE COPY_DATABASE_SCHEMA.COPY_TABLE(
sourceTable VARCHAR(128),
targetTable VARCHAR(128))
LANGUAGE SQL
BEGIN
DECLARE v_version_number INTEGER DEFAULT 1;
DECLARE v_cursor_statement VARCHAR(32672);
DECLARE v_load_command VARCHAR(32672);
DECLARE v_sqlcode INTEGER DEFAULT -1;
DECLARE v_sqlmessage VARCHAR(2048) DEFAULT '';
DECLARE v_rows_read BIGINT DEFAULT -1 ;
DECLARE v_rows_skipped BIGINT DEFAULT -1;
DECLARE v_rows_loaded BIGINT DEFAULT -1;
DECLARE v_rows_rejected BIGINT DEFAULT -1;
DECLARE v_rows_deleted BIGINT DEFAULT -1;
DECLARE v_rows_committed BIGINT DEFAULT -1;
DECLARE v_rows_part_read BIGINT DEFAULT -1;
DECLARE v_rows_part_rejected BIGINT DEFAULT -1;
DECLARE v_rows_part_partitioned BIGINT DEFAULT -1;
DECLARE v_mpp_load_summary VARCHAR(32672) DEFAULT NULL;

SET v_cursor_statement =
   'DECLARE C1 CURSOR FOR SELECT * from ' || sourceTable;
SET v_load_command =
   'load from C1 of cursor insert into ' || targetTable;

CALL db2load(1, v_cursor_statement, v_load_command, v_sqlcode,
         v_sqlmessage, v_rows_read, v_rows_skipped,
         v_rows_loaded, v_rows_rejected, v_rows_deleted,
         v_rows_committed, v_rows_part_read,
         v_rows_part_rejected, v_rows_part_partitioned,
         v_mpp_load_summary) ;
END#

Please note that the target table must already be created in order for this procedure to work, and the script terminator is # and not the usual ;.

This procedure is the hardest part of the script. Copying the contents of any table requires a dynamic prepared query statement to use as a cursor, and the load command is not available inside a procedure, so the db2load procedure from SYSPROC must be used.

The next procedure creates the schema, the tables, and copies the tables contents:

/**
* Copies an entire schema into a new schema named with the current date.
* @sourceSchema: the source schema name
* @targetSchema: the target schema name
* @tableNameSelection: the tables name to include ('%' for all tables)
*/

CREATE PROCEDURE COPY_DATABASE_SCHEMA.COPY_DATABASE(
sourceSchema VARCHAR(50),
targetSchema VARCHAR(50),
tableNameSelection VARCHAR(150)
)
LANGUAGE SQL
BEGIN
-- Variables
DECLARE stmtSchema VARCHAR(250);
DECLARE stmtTableStructure VARCHAR(200);
DECLARE stmtTableContents VARCHAR(250);
DECLARE stmtAlias VARCHAR(250);
DECLARE tableName VARCHAR(128);
DECLARE numPages BIGINT;
DECLARE nError INTEGER DEFAULT 0;
DECLARE at_end SMALLINT DEFAULT 0;
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE V_SQL VARCHAR(200);
DECLARE V_STMT STATEMENT;
DECLARE V_LOAD_STMT STATEMENT;
DECLARE TGT_TABLE_CUR CURSOR WITH HOLD WITH RETURN FOR V_STMT;
DECLARE LOAD_CUR CURSOR FOR V_LOAD_STMT;
DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;


-- Create schema
SET stmtSchema = CHAR('CREATE SCHEMA ' concat CHAR(targetSchema));
EXECUTE IMMEDIATE stmtSchema;
SET CURRENT SCHEMA targetSchema;


-- Copy tables and views
SET V_SQL = 'SELECT name, npages FROM SYSIBM.SYSTABLES
       WHERE CREATOR = '
'' || TRIM(sourceSchema) || '''
       AND NAME LIKE '
'' || TRIM(tableNameSelection) || '''
       order by name'
;
PREPARE V_STMT FROM V_SQL;
OPEN TGT_TABLE_CUR;

fetch_loop:
LOOP
FETCH TGT_TABLE_CUR INTO tableName, numPages;
IF at_end &lt;&gt; 0 THEN
  LEAVE fetch_loop;
ELSE  
  SET stmtTableStructure = 'CREATE TABLE ' ||
      targetSchema || '.' || tableName || ' LIKE ' ||
      sourceSchema || '.' || tableName ;
  EXECUTE IMMEDIATE stmtTableStructure;

  IF numPages &gt; 0 THEN
     CALL COPY_DATABASE_SCHEMA.copy_table(
             sourceSchema || '.' || tableName,
             targetSchema || '.' || tableName);
  END IF;
END IF;
END LOOP fetch_loop;

CLOSE TGT_TABLE_CUR;
END#

It dynamically issues DB2 SQL commands to create the schema and the tables structure and makes use of the previously created COPY_TABLE to copy the tables content. See the code comments for more information.

To use this just

CALL COPY_DATABASE_SCHEMA.COPY_DATABASE('sourceSchemaName','targetSchemaName','%');

These procedures have some limitations, for instance views are not supported.
Nevertheless, it is a good start to all that need to clone a schema or a table, since all the missing items can be gathered from the database catalog.

If you to drop an old schema, for instance to recreate it with a a new updated version, you can drop drop the schema with this procedure.

RCP Save Workbench Status

In Rich Client Platform (RCP) application, the workbench status can be easily saved and restored by simply including the snippet bellow in the ApplicationWorkbenchAdvisor class, that extends WorkbenchAdvisor.

@Override
public void initialize(IWorkbenchConfigurer configurer) {
super.initialize(configurer);

// tell eclipse to save workbench state when it quits
// (things like window size, view layout, etc.)
configurer.setSaveAndRestore(true);
}

This will automatically save the status of the workbench when the application is closed and will automatically restore that status when the application is executed again. The settings are saved on the [runtime-{your-product}]/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml file.

Welcome.

Welcome to Hexónio’s Blog. :)
This blog exists with the purpose to share our knowledge with the world.

Hexónio is focused on Information Technology Consulting with expertise centered in Data Migration. This will be the focus of this blog content.

He hope that our knowledge helps others in decision making, doubts and problem solving.