<commit_before>
var keywords = [
	"abort","absolute","action","add","after","agent","aggregate","all","allocate","alter","analyze","and","any","archive","are","array",
	"as","asc","ascii","asensitive","assertion","asymmetric","at","atomic","attach","attribute","auth","authorization","authorize","auto",
	"avg","back","backup","base","batch","before","begin","between","bigint","binary","bit","blob","block","boolean","both","breadth",
	"bucket","bulk","by","byte","call","called","calling","capacity","cascade","cascaded","case","cast","catalog","char","character",
	"check","class","clob","close","cluster","clustered","clustering","clusters","coalesce","collate","collation","collection","column",
	"columns","combine","comment","commit","compact","compile","compress","condition","conflict","connect","connection","consistency",
	"consistent","constraint","constraints","constructor","consumed","continue","convert","copy","corresponding","count","counter",
	"create","cross","cube","current","cursor","cycle","data","database","date","datetime","day","deallocate","dec","decimal","declare",
	"default","deferrable","deferred","define","defined","definition","delete","delimited","depth","deref","desc","describe","descriptor",
	"detach","deterministic","diagnostics","directories","disable","disconnect","distinct","distribute","do","domain","double","drop","dump",
	"duration","dynamic","each","element","else","elseif","empty","enable","end","equal","equals","error","escape","escaped","eval","evaluate",
	"exceeded","except","exception","exceptions","exclusive","exec","execute","exists","exit","explain","explode","export","expression","extended",
	"external","extract","fail","false","family","fetch","fields","file","filter","filtering","final","finish","first","fixed","flattern","float",
	"for","force","foreign","format","forward","found","free","from","full","function","functions","general","generate","get","glob","global","go",
	"goto","grant","greater","group","grouping","handler","hash","have","having","heap","hidden","hold","hour","identified","identity","if","ignore",
	"immediate","import","in","including","inclusive","increment","incremental","index","indexed","indexes","indicator","infinite","initially","inline",
	"inner","innter","inout","input","insensitive","insert","instead","int","integer","intersect","interval","into","invalidate","is","isolation",
	"item","items","iterate","join","key","keys","lag","language","large","last","lateral","lead","leading","leave","left","length","less","level",
	"like","limit","limited","lines","list","load","local","localtime","localtimestamp","location","locator","lock","locks","log","loged","long",
	"loop","lower","map","match","materialized","max","maxlen","member","merge","method","metrics","min","minus","minute","missing","mod","mode",
	"modifies","modify","module","month","multi","multiset","name","names","national","natural","nchar","nclob","new","next","no","none","not",
	"null","nullif","number","numeric","object","of","offline","offset","old","on","online","only","opaque","open","operator","option","or","order",
	"ordinality","other","others","out","outer","output","over","overlaps","override","owner","pad","parallel","parameter","parameters","partial",
	"partition","partitioned","partitions","path","percent","percentile","permission","permissions","pipe","pipelined","plan","pool","position",
	"precision","prepare","preserve","primary","prior","private","privileges","procedure","processed","project","projection","property","provisioning",
	"public","put","query","quit","quorum","raise","random","range","rank","raw","read","reads","real","rebuild","record","recursive","reduce","ref",
	"reference","references","referencing","regexp","region","reindex","relative","release","remainder","rename","repeat","replace","request","reset",
	"resignal","resource","response","restore","restrict","result","return","returning","returns","reverse","revoke","right","role","roles","rollback",
	"rollup","routine","row","rows","rule","rules","sample","satisfies","save","savepoint","scan","schema","scope","scroll","search","second","section",
	"segment","segments","select","self","semi","sensitive","separate","sequence","serializable","session","set","sets","shard","share","shared","short",
	"show","signal","similar","size","skewed","smallint","snapshot","some","source","space","spaces","sparse","specific","specifictype","split","sql",
	"sqlcode","sqlerror","sqlexception","sqlstate","sqlwarning","start","state","static","status","storage","store","stored","stream","string","struct",
	"style","sub","submultiset","subpartition","substring","subtype","sum","super","symmetric","synonym","system","table","tablesample","temp","temporary",
	"terminated","text","than","then","throughput","time","timestamp","timezone","tinyint","to","token","total","touch","trailing","transaction","transform",
	"translate","translation","treat","trigger","trim","true","truncate","ttl","tuple","type","under","undo","union","unique","unit","unknown","unlogged",
	"unnest","unprocessed","unsigned","until","update","upper","url","usage","use","user","users","using","uuid","vacuum","value","valued","values","varchar",
	"variable","variance","varint","varying","view","views","virtual","void","wait","when","whenever","where","while","window","with","within","without","work",
	"wrapped","write","year","zone"
]



var _expr_attribute = function( attr ) {
	return attr
		.split('.').join("_dot_")
		.split('-').join("_minus_")
}

var util = require('@awspilot/dynamodb-util')

	//util.config.empty_string_replace_as = o.empty_string_replace_as;

	util.config.stringset_parse_as_set = true;
	util.config.numberset_parse_as_set = true;
	util.config.binaryset_parse_as_set = true;

	function Transact( $client, config ) {

		this.err = null;
		this.reset()
		this.TransactItems = []



		this.events = config.events // global events
		this.describeTables = config.describeTables
		this.return_explain = config.return_explain
		this.local_events = {}
		this.client = $client


	}
	Transact.prototype.reset = function() {
		this.pending = {
			if: null,
			ExpressionAttributeNames: {},
			ExpressionAttributeValues: {},
			ConditionExpression: [],
		}
	}
	Transact.prototype.table = function($tableName) {
		this.reset()
		this.pending.tableName = $tableName;
		return this;
	}
	Transact.prototype.debug = function() {
		console.log("pending=",JSON.stringify(this.pending,null,"\t"))
		return this;
	}
	Transact.prototype.where = function( key ) {
		this.pending.where = key;
		return this;
	}
	Transact.prototype.eq = function( value ) {
		if (this.pending.where) {
			if (!this.pending.hasOwnProperty('wheres'))
				this.pending.wheres = {}

			this.pending.wheres[this.pending.where] = value
			delete this.pending.where;
		}

		if (this.pending.if !== null) {

			var _name = this._namefy( this.pending.if.attr, '#ifeq_' )
			var _vname = this._valuefy( this.pending.if.attr, ':ifeq_',  value )
			this.pending.ConditionExpression.push(
				"( " + _name + " = " + _vname + " )"
			)
			this.pending.if = null;
			return this
		}

		return this;
	}

	Transact.prototype._namefy = function( name, prefix ) {
		if (
				( keywords.indexOf(name.toLowerCase()) === -1 ) &&
				( name.match(/^[a-zA-Z]+$/) !== null )
			)
			return name;

		var _att_name = prefix + _expr_attribute(name)
		this.pending.ExpressionAttributeNames [ _att_name ] = name;
		return _att_name;
	}
	Transact.prototype._valuefy = function( name, prefix, value ) {

		var _att_name = prefix + name.split('-').join('_minus_')

		this.pending.ExpressionAttributeValues[ _att_name ] = util.stringify(value)
		return _att_name;
	}


	Transact.prototype.if = function( attr ) {
		this.pending.if = {
			attr: attr,<commit_msg>support for nested attributes in .if()<commit_after>
var keywords = [
	"abort","absolute","action","add","after","agent","aggregate","all","allocate","alter","analyze","and","any","archive","are","array",
	"as","asc","ascii","asensitive","assertion","asymmetric","at","atomic","attach","attribute","auth","authorization","authorize","auto",
	"avg","back","backup","base","batch","before","begin","between","bigint","binary","bit","blob","block","boolean","both","breadth",
	"bucket","bulk","by","byte","call","called","calling","capacity","cascade","cascaded","case","cast","catalog","char","character",
	"check","class","clob","close","cluster","clustered","clustering","clusters","coalesce","collate","collation","collection","column",
	"columns","combine","comment","commit","compact","compile","compress","condition","conflict","connect","connection","consistency",
	"consistent","constraint","constraints","constructor","consumed","continue","convert","copy","corresponding","count","counter",
	"create","cross","cube","current","cursor","cycle","data","database","date","datetime","day","deallocate","dec","decimal","declare",
	"default","deferrable","deferred","define","defined","definition","delete","delimited","depth","deref","desc","describe","descriptor",
	"detach","deterministic","diagnostics","directories","disable","disconnect","distinct","distribute","do","domain","double","drop","dump",
	"duration","dynamic","each","element","else","elseif","empty","enable","end","equal","equals","error","escape","escaped","eval","evaluate",
	"exceeded","except","exception","exceptions","exclusive","exec","execute","exists","exit","explain","explode","export","expression","extended",
	"external","extract","fail","false","family","fetch","fields","file","filter","filtering","final","finish","first","fixed","flattern","float",
	"for","force","foreign","format","forward","found","free","from","full","function","functions","general","generate","get","glob","global","go",
	"goto","grant","greater","group","grouping","handler","hash","have","having","heap","hidden","hold","hour","identified","identity","if","ignore",
	"immediate","import","in","including","inclusive","increment","incremental","index","indexed","indexes","indicator","infinite","initially","inline",
	"inner","innter","inout","input","insensitive","insert","instead","int","integer","intersect","interval","into","invalidate","is","isolation",
	"item","items","iterate","join","key","keys","lag","language","large","last","lateral","lead","leading","leave","left","length","less","level",
	"like","limit","limited","lines","list","load","local","localtime","localtimestamp","location","locator","lock","locks","log","loged","long",
	"loop","lower","map","match","materialized","max","maxlen","member","merge","method","metrics","min","minus","minute","missing","mod","mode",
	"modifies","modify","module","month","multi","multiset","name","names","national","natural","nchar","nclob","new","next","no","none","not",
	"null","nullif","number","numeric","object","of","offline","offset","old","on","online","only","opaque","open","operator","option","or","order",
	"ordinality","other","others","out","outer","output","over","overlaps","override","owner","pad","parallel","parameter","parameters","partial",
	"partition","partitioned","partitions","path","percent","percentile","permission","permissions","pipe","pipelined","plan","pool","position",
	"precision","prepare","preserve","primary","prior","private","privileges","procedure","processed","project","projection","property","provisioning",
	"public","put","query","quit","quorum","raise","random","range","rank","raw","read","reads","real","rebuild","record","recursive","reduce","ref",
	"reference","references","referencing","regexp","region","reindex","relative","release","remainder","rename","repeat","replace","request","reset",
	"resignal","resource","response","restore","restrict","result","return","returning","returns","reverse","revoke","right","role","roles","rollback",
	"rollup","routine","row","rows","rule","rules","sample","satisfies","save","savepoint","scan","schema","scope","scroll","search","second","section",
	"segment","segments","select","self","semi","sensitive","separate","sequence","serializable","session","set","sets","shard","share","shared","short",
	"show","signal","similar","size","skewed","smallint","snapshot","some","source","space","spaces","sparse","specific","specifictype","split","sql",
	"sqlcode","sqlerror","sqlexception","sqlstate","sqlwarning","start","state","static","status","storage","store","stored","stream","string","struct",
	"style","sub","submultiset","subpartition","substring","subtype","sum","super","symmetric","synonym","system","table","tablesample","temp","temporary",
	"terminated","text","than","then","throughput","time","timestamp","timezone","tinyint","to","token","total","touch","trailing","transaction","transform",
	"translate","translation","treat","trigger","trim","true","truncate","ttl","tuple","type","under","undo","union","unique","unit","unknown","unlogged",
	"unnest","unprocessed","unsigned","until","update","upper","url","usage","use","user","users","using","uuid","vacuum","value","valued","values","varchar",
	"variable","variance","varint","varying","view","views","virtual","void","wait","when","whenever","where","while","window","with","within","without","work",
	"wrapped","write","year","zone"
]



var _expr_attribute = function( attr ) {
	return attr
		.split('.').join("_dot_")
		.split('-').join("_minus_")
}

var util = require('@awspilot/dynamodb-util')

	//util.config.empty_string_replace_as = o.empty_string_replace_as;

	util.config.stringset_parse_as_set = true;
	util.config.numberset_parse_as_set = true;
	util.config.binaryset_parse_as_set = true;

	function Transact( $client, config ) {

		this.err = null;
		this.reset()
		this.TransactItems = []



		this.events = config.events // global events
		this.describeTables = config.describeTables
		this.return_explain = config.return_explain
		this.local_events = {}
		this.client = $client


	}
	Transact.prototype.reset = function() {
		this.pending = {
			if: null,
			ExpressionAttributeNames: {},
			ExpressionAttributeValues: {},
			ConditionExpression: [],
		}
	}
	Transact.prototype.table = function($tableName) {
		this.reset()
		this.pending.tableName = $tableName;
		return this;
	}
	Transact.prototype.debug = function() {
		console.log("pending=",JSON.stringify(this.pending,null,"\t"))
		return this;
	}
	Transact.prototype.where = function( key ) {
		this.pending.where = key;
		return this;
	}
	Transact.prototype.eq = function( value ) {
		if (this.pending.where) {
			if (!this.pending.hasOwnProperty('wheres'))
				this.pending.wheres = {}

			this.pending.wheres[this.pending.where] = value
			delete this.pending.where;
		}

		if (this.pending.if !== null) {

			var _name = this._namefy( this.pending.if.attr, '#ifeq_' )
			var _vname = this._valuefy( this.pending.if.attr, ':ifeq_',  value )
			this.pending.ConditionExpression.push(
				"( " + _name + " = " + _vname + " )"
			)
			this.pending.if = null;
			return this
		}

		return this;
	}

	Transact.prototype._namefy = function( name, prefix ) {
		var $this=this;
		if (
				( keywords.indexOf(name.toLowerCase()) === -1 ) &&
				( name.match(/^[a-zA-Z]+$/) !== null )
			)
			return name;


		var _att_names = []
		name.split('.').map(function( n, idx ) {

			// if its an array path, remove it and add it later
			// for (const match of "hello[1][12][14]".matchAll(/([^\[]*)\[([0-9]+)\]/gs)) { console.log(match) }
			if ( n.indexOf('[') === -1 ) {
				var _att_name = prefix +idx+ _expr_attribute(n)
				$this.pending.ExpressionAttributeNames [ _att_name ] = n;
				_att_names.push(_att_name)
			} else {
				var _arr_path = n.slice(n.indexOf('['))
				n = n.slice(0,n.indexOf('['))
				var _att_name = prefix +idx+ _expr_attribute(n)
				$this.pending.ExpressionAttributeNames [ _att_name ] = n;
				_att_names.push(_att_name + _arr_path )
			}

		})

		return _att_names.join('.');
	}
	Transact.prototype._valuefy = function( name, prefix, value ) {
		var _att_name = prefix + name
			.split('-').join('_minus_')
			.split('.').join("_dot_")
			.split('[').join("_sqp1_")
			.split(']').join("_sqp1_")

		this.pending.ExpressionAttributeValues[ _att_name ] = util.stringify(value)
		return _att_name;
	}


	Transact.prototype.if = function( attr ) {
		this.pending.if = {
			attr: attr,
{'fraction_non_alphanumeric': 0.2660137965016014, 'fraction_numerical': 0.000800689825080069, 'mean_word_length': 10.757422157856626, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1625856', 'n_tokens_mistral': 5161, 'n_tokens_neox': 4801, 'n_words': 415}