use AnP

if object_id(N'dbo.bw', N'FN') is not null drop function dbo.bw
go
create function dbo.bw(
	@number bigint,
	@bits smallint
) returns bigint begin 
	return (case 
		when @bits > 0 then @number * power(cast(2 as bigint), @bits)
		when @bits < 0 then @number / power(cast(2 as bigint), -@bits)
	else @number end)
end
go

if object_id(N'dbo.where_set', N'FN') is not null drop function dbo.where_set
go
create function dbo.where_set(
	@new_where varchar(max),
	@old_where varchar(max)
) returns varchar(max) begin 
	return (case when isnull(@new_where, '') = '' then isnull(@old_where, '') else (case when isnull(@old_where, '') = '' then @new_where else '(' + @new_where + ') and (' + @old_where + ')' end) end)
end
go
	
if object_id(N'dbo.tables_list', N'P') is not null drop procedure dbo.tables_list
go
create procedure tables_list(
	@view varchar(max),
	@page integer,
	@items_per_page integer,
	@where varchar(max),
	@order_by varchar(max),
	@has_errors bit,
	@pages integer output,
	@items integer output,
	@results integer output
) with execute as owner as begin set nocount on 
		
	declare @item_from integer
	declare @query nvarchar(max)
	declare @where_string varchar(max)

	if @has_errors = 1
		set @where = dbo.where_set('0 = 1', @where)
	set @where_string = (case when isnull(@where, '') = '' then '' else ' where ' + @where end)

	set @query = N'select top 1 @subitems = count(1) from ' + @view + @where_string

	execute sp_executesql @query, N'@subitems integer output', @subitems = @items output

	set @pages = ceiling(@items / cast(@items_per_page as float))
			
	if @page < 1 
		set @page = 1
	else if @pages > 0 and @page > @pages
		set @page = @pages

	set @query = (
		N'select * from ' + @view + @where_string + 
		' order by ' + (case when isnull(@order_by, '') = '' then 'id desc' else @order_by end) + 
		' offset ' + convert(varchar(14), (@page - 1) * @items_per_page) + ' rows fetch next ' + convert(varchar(14), @items_per_page) + ' rows only'
	)

	execute sp_executesql @query
	set @results = @@rowcount
	
end
go

if object_id(N'dbo.json_set', N'FN') is not null drop function dbo.json_set
go
create function dbo.json_set(
	@path varchar(max),
	@key varchar(max),
	@value varchar(max)
) returns varchar(max) begin 
	return json_modify(@path, '$.' + @key, @value)
end
go