<commit_before>// (c) Copyright 2015-2017 <NAME>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package flow

import (
	"database/sql"
	"errors"
	"fmt"
	"math"
	"time"
)

// EventStatus enumerates the query parameter values for filtering by
// event state.
type EventStatus uint8

const (
	EventStatusAll EventStatus = iota
	EventStatusApplied
	EventStatusPending
)

// DocEventID is the type of unique document event identifiers.
type DocEventID int64

// DocEvent represents a user action performed on a document in the
// system.
//
// Together with documents and nodes, events are central to the
// workflow engine in `flow`.  Events cause documents to transition
// from one state to another, usually in response to user actions.  It
// is possible for system events to cause state transitions, as well.
type DocEvent struct {
	id     DocEventID  // Unique ID of this event
	docID  DocumentID  // Document to which this event is to be applied
	state  DocState    // Current state of the document
	user   UserID      // User who caused this action
	action DocAction   // Action performed by the user
	text   string      // Comment or other content
	ctime  time.Time   // Time at which the event occurred
	status EventStatus // Status of this event
}

// ID answers the unique identifier of this document event.
func (e *DocEvent) ID() DocEventID {
	return e.id
}

// Document answers the document which this event transformed.
func (e *DocEvent) Document() DocumentID {
	return e.docID
}

// State answers the state of the document as of the time this event
// occurred.
func (e *DocEvent) State() DocState {
	return e.state
}

// User answers the user who caused this event to occur.
func (e *DocEvent) User() UserID {
	return e.user
}

// Action answers the document action that this event represents.
func (e *DocEvent) Action() DocAction {
	return e.action
}

// Text answers the comment or other content enclosed in this event.
func (e *DocEvent) Text() string {
	return e.text
}

// Time answers the time at which this event occurred.
func (e *DocEvent) Time() time.Time {
	return e.ctime
}

// Status answers the status of this event.
func (e *DocEvent) Status() (EventStatus, error) {
	var dstatus string
	row := db.QueryRow("SELECT status FROM wf_docevents WHERE id = ?", e.id)
	err := row.Scan(&dstatus)
	if err != nil {
		return 0, err
	}
	switch dstatus {
	case "A":
		e.status = EventStatusApplied

	case "P":
		e.status = EventStatusPending

	default:
		return 0, fmt.Errorf("unknown event status : %s", dstatus)
	}

	return e.status, nil
}

// Unexported type, only for convenience methods.
type _DocEvents struct{}

var _docevents *_DocEvents

func init() {
	_docevents = &_DocEvents{}
}

// New creates and initialises an event that transforms the document
// that it refers to.
func (des *_DocEvents) New(otx *sql.Tx, user UserID, doc *Document, action DocAction, text string) (DocEventID, error) {
	if doc == nil || user <= 0 {
		return 0, errors.New("document should be non-nil; user ID should be a positive integer")
	}

	var tx *sql.Tx
	if otx == nil {
		tx, err := db.Begin()
		if err != nil {
			return 0, err
		}
		defer tx.Rollback()
	} else {
		tx = otx
	}

	q := `
	INSERT INTO wf_docevents(doc_id, docstate_id, user_id, docaction_id, data, ctime, status)
	VALUES(?, ?, ?, ?, ?, NOW(), 'P')
	`
	res, err := tx.Exec(q, doc.id, doc.state, user, action.id, text)
	if err != nil {
		return 0, err
	}
	var id int64
	id, err = res.LastInsertId()
	if err != nil {
		return 0, err
	}

	if otx == nil {
		err = tx.Commit()
		if err != nil {
			return 0, err
		}
	}

	return DocEventID(id), nil
}

// List answers a subset of document events, based on the input<commit_msg>Modify `DocEvent` creation to take appropriate IDs as parameters<commit_after>// (c) Copyright 2015-2017 <NAME>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package flow

import (
	"database/sql"
	"errors"
	"fmt"
	"math"
	"time"
)

// EventStatus enumerates the query parameter values for filtering by
// event state.
type EventStatus uint8

const (
	EventStatusAll EventStatus = iota
	EventStatusApplied
	EventStatusPending
)

// DocEventID is the type of unique document event identifiers.
type DocEventID int64

// DocEvent represents a user action performed on a document in the
// system.
//
// Together with documents and nodes, events are central to the
// workflow engine in `flow`.  Events cause documents to transition
// from one state to another, usually in response to user actions.  It
// is possible for system events to cause state transitions, as well.
type DocEvent struct {
	id     DocEventID  // Unique ID of this event
	docID  DocumentID  // Document to which this event is to be applied
	state  DocState    // Current state of the document
	user   UserID      // User who caused this action
	action DocAction   // Action performed by the user
	text   string      // Comment or other content
	ctime  time.Time   // Time at which the event occurred
	status EventStatus // Status of this event
}

// ID answers the unique identifier of this document event.
func (e *DocEvent) ID() DocEventID {
	return e.id
}

// Document answers the document which this event transformed.
func (e *DocEvent) Document() DocumentID {
	return e.docID
}

// State answers the state of the document as of the time this event
// occurred.
func (e *DocEvent) State() DocState {
	return e.state
}

// User answers the user who caused this event to occur.
func (e *DocEvent) User() UserID {
	return e.user
}

// Action answers the document action that this event represents.
func (e *DocEvent) Action() DocAction {
	return e.action
}

// Text answers the comment or other content enclosed in this event.
func (e *DocEvent) Text() string {
	return e.text
}

// Time answers the time at which this event occurred.
func (e *DocEvent) Time() time.Time {
	return e.ctime
}

// Status answers the status of this event.
func (e *DocEvent) Status() (EventStatus, error) {
	var dstatus string
	row := db.QueryRow("SELECT status FROM wf_docevents WHERE id = ?", e.id)
	err := row.Scan(&dstatus)
	if err != nil {
		return 0, err
	}
	switch dstatus {
	case "A":
		e.status = EventStatusApplied

	case "P":
		e.status = EventStatusPending

	default:
		return 0, fmt.Errorf("unknown event status : %s", dstatus)
	}

	return e.status, nil
}

// Unexported type, only for convenience methods.
type _DocEvents struct{}

var _docevents *_DocEvents

func init() {
	_docevents = &_DocEvents{}
}

// New creates and initialises an event that transforms the document
// that it refers to.
func (des *_DocEvents) New(otx *sql.Tx, user UserID, dtype DocTypeID, did DocumentID,
	state DocStateID, action DocActionID, text string) (DocEventID, error) {
	if user <= 0 {
		return 0, errors.New("user ID should be a positive integer")
	}

	var tx *sql.Tx
	if otx == nil {
		tx, err := db.Begin()
		if err != nil {
			return 0, err
		}
		defer tx.Rollback()
	} else {
		tx = otx
	}

	q := `
	INSERT INTO wf_docevents(doctype_id, doc_id, docstate_id, docaction_id, user_id, data, ctime, status)
	VALUES(?, ?, ?, ?, ?, NOW(), 'P')
	`
	res, err := tx.Exec(q, dtype, did, state, action, text)
	if err != nil {
		return 0, err
	}
	var id int64
	id, err = res.LastInsertId()
	if err != nil {
		return 0, err
	}

	if otx == nil {
		err = tx.Commit()
		if err != nil {
			return 0, err
		}
	}

	return DocEventID(id), nil
}

// List answers a subset of document events, based on the input
{'fraction_non_alphanumeric': 0.09769639692852924, 'fraction_numerical': 0.005906674542232723, 'mean_word_length': 3.3304347826086955, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1616264', 'n_tokens_mistral': 2700, 'n_tokens_neox': 2581, 'n_words': 1122}